다형성(polymorphism)
def: 조상클래스 타입의 참조변수로, 자손클래스의 인스턴스를 참조할 수 있도록 한 것.
// 예시 class TV { /* 내용 생략 */ } class captionTV extends TV { /* 내용 생략 */ }
TV t = new CaptionTV(); // 조상 타입의 참조변수로 자손 인스턴스를 참조 captionTV ct = new TV(); // ERR!!
이 경우, t는 CaptionTV의 인스턴스이지만 TV타입의 참조변수이기 때문에 상속된 TV클래스에만 접근할 수 있다. 즉 TV클래스에서 정의되지 않고 captionTV에서만 정의된 인스턴스 멤버에는 접근할 수 없다.
그렇다면, captionTV타입의 참조변수로 정의하면 모든 멤버를 사용할 수 있을텐데 굳이 조상클래스의 참조변수로 할까?
조상타입의 참조변수가 자손클래스의 인스턴스를 참조하는 것은 가능하지만 그 반대는 불가하다.
기본형처럼 참조변수도 상속관계가 있으면 형변환이 가능하다. 자손=>부모타입(
up casting
)은 형변환 생략이 가능하며, 부모=>자손타입(down casting
)은 형변환 생략이 불가하다.// 다운캐스팅이 가능한 경우 class CastingTest { Car c = null; FireEngine fe = new FireEngine(); FireEngine fe2 = null; c = fe; // 업캐스팅. 형변환 생략. fe2 = (FireEngine)c; // 다운캐스팅. } class Car { /* 내용 생략 */ } class FireEngine extends Car { /* 내용 생략 */ }
// 다운캐스팅이 불가능한 경우 class CastingTest { Car c = new Car(); // 조상클래스 인스턴스 생성 FireEngine fe2 = null; fe2 = (FireEngine)c; // Err! 자손타입의 변수가 조상 인스턴스를 참조하는 것은 불가하다. }
이 경우
Car c = new FireEngine();
으로 바꾸면 에러가 나지 않는다.
형변환은 참조변수의 타입을 변환하는 것이지, 인스턴스를 변환하는 것은 아니다.
그렇기 때문에 참조변수의 형변환은 인스턴스에 영향을 미치지 않으며, 단지 참조할 수 있는 멤버의 범위를 조절하는 것뿐이다. 업캐스팅을 하면 참조할 수 있는 멤버 수가 조상클래스 멤버로 줄어들며, 다운캐스팅을 하면 자손클래스 멤버까지 참조할 수 있게 되는 것이다.