여기서 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
```
[농구]는 손으로 공을 던져 골을 넣는 운동이다.
[축구]는 주로 발로 공을 차 넣는 운동이다.
[탁구]는 공을 번갈아가며 주고 받는 운동이다.
```
sehongpark님의 답변
# 두 코드는
정상 동작하며, 모두 동일한 수행을 합니다.
```
// 배열을 사용한 메소드 수행
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.
좋은 질문 감사합니다!
tkgksw님의 답변
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();으로 호출한거 같습니다.