자식 타입의 기능을 사용하려면 다음과 같이 다운캐스팅 결과를 변수에 담아두고 이후에 기능을 사용하면 된다.
Child child = (Child) poly;
child.childMethod();
하지만 다운캐스팅 결과를 변수에 담아두는 과정이 번거롭다. 이런 과정 없이 일시적으로 다운캐스팅을 해서 인스턴스에 있는 하위 클래스의 기능을 바로 호출할 수 있다.
package poly.basic;
public class CastingMain2 {
public static void main(String[] args) {
// 부모 변수가 자식 인스턴스 참조 (다형적 참조)
Parent poly = new Child(); // x001
// 단 자식의 기능은 호출할 수 없다. 컴파일 오류 발생
// poly.childMethod();
// 다운캐스팅 (부모 타입 -> 자식 타입)
Child child = (Child) poly; // x001
child.childMethod();
// 일시적 다운캐스팅 - 해당 메서드를 호출하는 순간만 다운캐스팅
((Child) poly).childMethod();
}
}
((Child) poly).childMethod();
poly
는 Parent
타입이다. 그런데 이 코드를 실행하면 Parent
타입을 임시로 Child
로 변경한다. 그리고 메서드를 호출할 때 Child
타입에서 찾아서 실행한다.
정확히는 poly
가 Child
타입으로 바뀌는 것은 아니다.
((Child) poly).childMethod(); // 다운캐스팅을 통해 부모 타입을 자식 타입으로 변환 후 기능 호출
((Child) x001).childMethod(); // 참조값을 읽은 다음 자식 타입으로 다운캐스팅
참고로 캐스팅을 한다고 해서 Parent poly
의 타입이 변하는 것은 아니다. 해당 참조값을 꺼내고 꺼낸 참조값이 Child
타입이 되는 것이다. 따라서 poly
의 타입은 Parent
로 유지된다.
이렇게 일시적 다운캐스팅을 사용하면 별도의 변수 없이 인스턴스의 자식 타입의 기능을 사용할 수 있다.
다운캐스팅과 반대로 현재 타입을 부모 타입으로 변경하는 것을 업캐스팅이라 한다.
package poly.basic;
// Upcasting vs DownCasting
public class CastingMain3 {
public static void main(String[] args) {
Child child = new Child();
Parent parent1 = (Parent) child; // 업캐스팅은 생략 가능, 생략 권장
Parent parent2 = child; // 업캐스팅 생략
parent1.parentMethod();
parent2.parentMethod();
}
}
Parent parent1 = (Parent) child;
Child
타입을 Parent
타입에 대입해야 한다. 따라서 타입을 변환하는 캐스팅이 필요하다.
그런데 부모 타입으로 변환하는 경우에는 다음과 같이 캐스팅 코드인 (타입)
을 생략할 수 있다.
Parent parent2 = child;
Parent parent2 = new Child();
업캐스팅은 생략할 수 있다. 다운캐스팅은 생략할 수 없다. 참고로 업캐스팅은 매우 자주 사용하기 때문에 생략을 권장한다.
자바에서 부모는 자식을 담을 수 있다. 하지만 반대는 안된다. (꼭 필요하다면 다운캐스팅을 해야 한다.)