오늘은 어제에 이어서 좀 더 개념적으로 오버라이딩을 알아본다.
어제 내용을 한줄 요약하면
오버라이딩이란 상위 클래스에서 정의된 메소드를 하위 클래스에서 다시 정의하는 것을 말하며
참조변수가 참조하는 인스턴스의 종류에 상관없이, 참조변수의 '형'에 해당하는 클래스와
그 클래스가 상속하는 상위 클래스에 정의된 메소드들만 호출 가능하다.
(한줄이긴해,,)
그리고 또
CheeseCake이 Cake를 상속할 때
CheeseCake cake1 = new CheeseCake();
Cake cake2 = cake1;
이건 가능.
Cake cake3 = new CheeseCake();
CheeseCake cake4 = cake3;
이건 불가능.
왜냐면 컴파일러 역시 '참조변수의 형' 만을 가지고 대입의 가능성을 판단하기 때문이다.
이러한 내용을 배열 관점에서도 간단하게 예를들면,
CheeseCake[] cakes = new CheeseCake[10];
이런 내용이
Cake[] cakes = new CheeseCake[10];
이렇게도 된다고 한다.
(이건 좀 신기했다.) 이러한 참조 관계가 배열까지 이어진다는 사실을 기억하고 있으면 된다고 한다.
상위 클래스에서 정의된 메소드를 하위 클래스에서 다시 정의한다는 것은 => '무효화' 시키는 것이다. => 오버라이딩
예를들어,
class Cake {
public void yummy() {
sout("맛있당");
}
}
class CheeseCake extend Cake {
public void yummy() { // Cake의 yummy 메소드를 오버라이딩함.
sout("치즈케잌이 더 맛있당");
}
}
메인코드 {
Cake c1 = new CheeseCake();
CheeseCake c2 = new CheeseCake();
c1.yummy(); // 치즈케잌이 더 맛있당
c2.yummy(); // 치즈케잌이 더 맛있당
}
치즈케이크 클래스는 yummy 메소드에 대한 세가지를 재정의했는데,
메소드의 이름, 메소드의 반환형, 메소드의 매개변수 선언
이 3가지가 같아야 오버라이딩이 성립하게 된다.
이렇게 오버라이딩 하게되면,
참조 변수의 형에 상관없이 오버라이딩한 메소드가(치즈케잌의 야미) 오버라이딩 된 메소드를 (케잌의 야미) 대신하게 된다.
내일은 이어서 오버라이딩의 일반화와 호출방법을 알아본다.
오늘의 코멘트: 오버라이딩을 사용해본적이 없어서 약간의 정리가 필요했다.