여기서 tmp를 만드는 이유는 뭔가요? ``` for (int i = 0; i < sportsArr.length; i++) { Sports tmp = sportsArr[i]; tmp.description(); } ``` sportsArr도 Sports에서 나온 배열이니까 description()를 호출할 수 있는거 아닌가요? ``` for (int i = 0; i < sportsArr.length; i++) { sportsArr[i].description(); } ``` sportsArr가 Sports의 객체가 아니라 배열이라서 description()를 호출을 못한다고 이해해야하나요? # protected 접근 제한자 #### CODE <a class='btn btn-default' href='/codes/25091'>Link</a> ``` public class ProtectedFields { public static void main(String[] args) { // 객체 생성 Basketball b = new Basketball(); Soccer s = new Soccer(); PingPong p = new PingPong(); // 객체 필드 초기화 b.name = "농구"; s.name = "축구"; p.name = "탁구"; // 부모 타입(업 캐스팅)으로 배열 생성 Sports[] sportsArr = { b, s, p }; // 모든 운동 설명 출력 for (int i = 0; i < sportsArr.length; i++) { Sports tmp = sportsArr[i]; tmp.description(); } } } // 운동 class Sports { /* 1. 상속 관계 및 동일 패키지내에서 해당 필드를 자유로이 쓰게 하세요. */ protected String name; public void description() { System.out.printf("[%s]는 여가/경기/체력 단련 등을 위한 신체 운동입니다.\n", name); } } // 농구 class Basketball extends Sports { /* 2. 메소드 오버라이딩(재정의)을 통해 농구을 설명해주세요. */ public void description() { System.out.printf("[%s]는 손으로 공을 던져 골을 넣는 운동이다.\n", name); } } // 축구 class Soccer extends Sports { /* 3. 메소드 오버라이딩(재정의)을 통해 축구을 설명해주세요. */ public void description() { System.out.printf("[%s]는 주로 발로 공을 차 넣는 운동이다.\n", name); } } // 탁구 class PingPong extends Sports { /* 4. 메소드 오버라이딩(재정의)을 통해 탁구을 설명해주세요. */ public void description() { System.out.printf("[%s]는 공을 번갈아가며 주고 받는 운동이다.\n", name); } } ``` #### INPUT ``` ``` #### OUPUT ``` [농구]는 손으로 공을 던져 골을 넣는 운동이다. [축구]는 주로 발로 공을 차 넣는 운동이다. [탁구]는 공을 번갈아가며 주고 받는 운동이다. ```
# 두 코드는 정상 동작하며, 모두 동일한 수행을 합니다. ``` // 배열을 사용한 메소드 수행 for (int i = 0; i < sportsArr.length; i++) { sportsArr[i].description(); } // 객체를 명시한 메소드 수행 for (int i = 0; i < sportsArr.length; i++) { Sports tmp = sportsArr[i]; tmp.description(); } ``` ## 차이가 있다면 배열 사용 코드는 코드가 짧고, 객체 명시한 코드는 가독성(잘 읽혀지는 정도)이 좋습니다. ## PS. 좋은 질문 감사합니다!
Basketball b = new Basketball(); Soccer s = new Soccer(); PingPong p = new PingPong(); Sports[] sportsArr = { b, s, p }; Basketball, Soccer, PingPong클래스가 Sports클래스를 상속받았기때문에 Sports즉 부모타입으로 객체배열을 만들었습니다. for (int i = 0; i < sportsArr.length; i++) { Sports tmp = sportsArr[i]; tmp.description(); } i가 0인경우 sportsArr[0]은 new Basketball(); 객체의 주소를 갖고있습니다. i가 1인경우 sportsArr[1]은 new Soccer(); 객체의 주소를 갖고있습니다. i가 3인 경우 sportsArr[2]는 new PingPong(); 객체의 주소를 갖고있습니다. sportsArr도 Sports에서 나온 배열이니까 description()를 호출할 수 있는거 아닌가요? sportsArr[0].description()으로 호출하면 sportsArr[0]은 new Basketball() 객체의 주소를 갖고있습니다. 그런데 Basketball이 Sports를 상속받았고 description()를 Basketball클래스에서 재정의 해줬기 때문에 Basketball클래스에 선언된 description()가 호출됩니다. 즉 sportsArra[0].description(); 의 주체객체는 new Basketball() 입니다. 마찬가지로 sportsArr[1].description()이 호출될때 메소드 호출의 주체객체는 new Soccer();이고 sportsArr[2].description()의 주체객체는 new PingPong();입니다. 그런데 description메소드가 인스턴스메소드이기 때문에 객체.메소드명으로 호출해야 한다는것을 강조하기 위해서 sportsArr[0]이 갖고있는 new Basketball()객체의 주소를 Sport 타입의 temp변수로 복사하였습니다. 그러면 temp변수가 new Basketball()객체의 주소를 갖고있게 됩니다. 즉 temp.description();으로 호출하면 new Basketball() 객체가 메소드 호출의 주체가 되기 때문에 더 확실하게 인스턴스 메소드를 호출하는지 알수 있기때문에 temp.description();으로 호출한거 같습니다.