다형성(Polymorphism)은 이름 그대로 “다양한 형태”, “여러 형태”를 뜻한다.
프로그래밍에서 다형성은 한 객체가 여러 타입의 객체로 취급될 수 있는 능력을 뜻한다. 보통 하나의 객체는 하나의 타입으로 고정되어 있다. 그런데 다형성을 사용하면 하나의 객체가 다른 타입으로 사용될 수 있다.
package poly.basic;
public class Parent {
public void parentMethod() {
System.out.println("Parent.parentMethod");
}
}
package poly.basic;
public class Child extends Parent {
public void childMethod() {
System.out.println("Child.childMethod");
}
}
package poly.basic;
public class PolyMain {
public static void main(String[] args) {
// 부모 변수가 부모 인스턴스 참조
System.out.println("Parent -> Parent");
Parent parent = new Parent();
parent.parentMethod();
// 자식 변수가 자식 인스턴스 참조
System.out.println("Child -> Child");
Child child = new Child();
child.parentMethod();
child.childMethod();
// 부모 변수가 자식 인스턴스 참조 (다형적 참조)
System.out.println("Parent -> Child");
Parent poly = new Child();
poly.parentMethod();
// Child child1 = new Parent(); // 자식은 부모를 담을 수 없다.
// 자식의 기능은 호출할 수 없다. 컴파일 오류 발생
// poly.childMethod();
}
}
Parent parent = new Parent()
Parent
인스턴스를 만들었다. 이 경우 부모 타입인 Parent
를 생성했기 때문에 메모리 상에 Parent
만 생성된다. (자식은 생성되지 않음)Parent
타입의 변수인 parent
에 담아둔다.parent.parentMethod()
를 호출하면 인스턴스의 Parent
클래스에 있는 parentMethod()
가 호출된다.Child child = new Child()
Child
인스턴스를 만들었다. 이 경우 자식 타입인 Child
를 생성했기 때문에 메모리 상에 Child
와 Parent
가 모두 생성된다.Child
타입의 변수인 child
에 담아둔다.child.childMethod()
를 호출하면 인스턴스의 Child
클래스에 있는 childMethod()
가 호출된다.Parent poly = new Child()
Child
인스턴스를 만들었다. 이 경우 자식 타입인 Child
를 생성했기 때문에 메모리 상에 Child
와 Parent
가 모두 생성된다.Parent
타입의 변수인 poly
에 담아둔다.Parent poly
는 부모 타입이다. new Child()
를 통해 생성된 결과는 Child
타입이다. 자바에서 부모 타입은 자식 타입을 담을 수 있다.Parent poly = new Child() ⇒ 성공
Child child1 = new Parent()
⇒ 컴파일 오류 발생지금까지는 항상 같은 타입에 참조를 대입했다. 그래서 보통 한 가지 형태만 참조할 수 있었다.
Parent parent = new Parent()
Child child = new Child()
그런데 Parent
타입의 변수는 자신인 Parent
는 물론이고, 자식 타입까지 참조할 수 있다. 만약 손자가 있다면 손자도 그 하위 타입도 참조할 수 있다.
Parent poly = new Parent()
Parent poly = new Child()
Parent poly = new Grandson()
⇒ Child
하위에 손자가 있다면 가능자바에서 부모 타입은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. 이것이 바로 다양한 형태를 참조할 수 있다고 해서 다형적 참조라 한다.
poly.parentMethod()
를 호출하면 먼저 참조값을 사용해서 인스턴스를 찾는다. 그리고 다음으로 인스턴스 안에서 실행할 타입도 찾아야 한다. poly
는 Parent
타입이다. 따라서 Parent
클래스부터 시작해서 필요한 기능을 찾는다. 인스턴스의 Parent
클래스에 parentMethod()
가 있다. 따라서 해당 메서드가 호출된다.
Parent poly = new Child()
이렇게 자식을 참조한 상황에서 poly
가 자식 타입인 Child
에 있는 childMethod()
를 호출하면 어떻게 될까?
poly.childMethod()
를 실행하면 먼저 참조값을 통해 인스턴스를 찾는다. 그리고 인스턴스 안에서 실행할 타입을 찾아야 한다. 호출자는 poly
인 Parent
타입이다. 따라서 Parent
클래스부터 시작해서 필요한 기능을 찾는다. 그런데 상속 관계는 부모 방향으로 찾아 올라갈 순 있지만 자식 방향으로 찾아 내려갈 수는 없다. Parent
는 부모 타입이고 상위에 부모가 없다. 따라서 childMethod()
를 찾을 수 없으므로 컴파일 오류가 발생한다.
이런 경우 childMethod()
를 호출하고 싶으면 어떻게 해야할까? 바로 캐스팅이 필요하다.
출처 : 김영한의 실전 자바 - 기본편
https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard