다형성
객체지향의 특징에는 캡슐화, 상속, 다형성이 있다. 다형성은 그 중에서도 가장 중요한 특징 중 하나이다. 다형성(Polymorphism)은 이름 그대로 "다양한 형태", "여러 형태"를 뜻한다. 프로그래밍에서 다형성은 한 객체가 여러 타입의 객체로 취급될 수 있는 능력을 뜻한다. 보통 하나의 객체는 하나의 타입으로 고정되어 있다. 그런데 다형성을 사용하면 하나의 객체가 다른 타입으로 사용될 수 있다.
다형적 참조
Parent.java
package poly.basic;
public class Parent {
public void parentMethod() {
System.out.println("Parent.parentMethod");
}
}
Child.java
package poly.basic;
public class Child extends Parent{
public void childMethod() {
System.out.println("Child.childMethod");
}
}
PolyMain.java
package poly.basic;
public class PolyMain {
public static void main(String[] args) {
//1. 부모 변수가 부모 인스턴스 참조
System.out.println("Parent -> Parent");
Parent parent = new Parent();
parent.parentMethod();
// 2. 자식 변수가 자식 인스턴스 참조
System.out.println("Child -> Child");
Child child = new Child();
child.parentMethod();
child.childMethod();
// 3. 부모 변수가 자식 인스턴스 참조(다형적 참조)
System.out.println("Parent -> Child");
Parent poly = new Child();
poly.parentMethod();
//자식의 기능은 호출할 수 없다.
// poly.childMethod();
}
}
1. 부모 타입의 변수가 부모 인스턴스를 참조한다.
Parent -> Parent:parent.parentMethod()
- Parent 인스턴스를 만들었다. 이 경우 부모 타입인 Parent를 생성했기 때문에 메모리 상에 Parent만 생성된다. (자식은 생성 X)
- 생성된 참조값을 변수 parent에 담아둔다.
- parent.parentMethod()를 호출하면 인스턴스의 Parent 클래스에 있는 parentMethod() 가 호출된다.
2. 자식 타입의 변수가 자식 인스턴스 참조
Child -> child: child.childMethod()
- 자식 타입의 변수가 자식 인스턴스를 참조한다.
- Child 인스턴스를 만들면, 메모리 상에 Child와 Parent가 모두 생성된다.
- 생성된 참조값을 Child 타입의 변수인 child에 담아둔다.
- child.childMethod()를 호출하면 인스턴스 Child 클래스에 있는 childMethod() 가 호출된다.
3. 다형적 참조: 부모 타입의 변수가 자식 인스턴스 참조
Parent -> Child:poly.prentMethod()
- 부모 타입의 변수가 자식 인스턴스를 참조한다.
- Parent poly = new Child()
- Child 인스턴스를 만들었다 이경우 자식 타입인 Child를 생성했기 때문에 메모리에 Child와 Parent가 모두 생성된다.
- 생성된 참조값을 Parent 타입의 변수인 poly에 담아둔다.
- 타입이 Parent이기 때문에 본인만 알고 있다. 따라서 childMethod()는 호출할 수 없다.
=> 부모 타입은 자식 타입을 담을 수 있다.
반대로 자식 타입은 부모 타입을 담을 수 없다.
지금까지 학습한 내용을 떠올려 보면 항상 같은 타입에 참조를 대입했다.
그런데 Parent 타입의 변수는 자신인 Parent는 물론이고, 자식 타입까지 참조할 수 있다.
자바에서 부모 타입은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다 이것이 바로 다양한 형태를 참조할 수 있다고 해서 다형점 참조라 한다.
다형적 참조와 인스턴스 실행
poly.parentMethod()를 호출하면 먼저 참조값을 사용해서 인스턴스를 찾는다. 그리고 다음으로 인스턴스 안에서 실행할 타입도 찾아야한다. poly는 Parent 타입이다. 따라서 Parent 클래스부터 시작해서 필요한 기능을 찾는다.
다형적 참조의 한계
Parent -> Child:poly.childMethod()
Parent poly = new Child() 이렇게 자식을 참조한 상황에서 poly가 자식 타입인 Child에 있는 childMethod()를 호출하면 어떻게 될까?
poly.childMethod()를 실행하면 먼저 참조값을 통해 인스턴스를 찾는다. poly는 Parent 타입이므로 Parent 클래스에서 필요한 기능을 찾는다. 상속관계는 부모에서 자식방향으로 내려 갈 수는 없다. Parent는 부모 타입이고 상위에 부모가 없다. 따라서 childMethod()를 찾을 수 없으므로 컴파일 오류가 발생한다.
다형적 참조의 핵심은 부모는 자식을 품을 수 있다는 것이다.
childMethod()는 어떻게 호출할까?
이럴 때는 캐스팅이 필요하다.
캐스팅에 대해서는 다음 포스팅에서 알아보겠다.
* 인프런 '김영한의 실전 자바 - 기본편'을 참고하여 작성하였습니다.
'프로그래밍언어 > Java' 카테고리의 다른 글
[Java 기본] instanceof (1) | 2024.07.23 |
---|---|
[Java 기본] 다형성과 캐스팅 (0) | 2024.07.23 |
[Java 기본] super - 부모 참조, 생성자 (0) | 2024.07.16 |
[Java 기본] 상속과 접근 제어 (0) | 2024.07.16 |
[Java 기본] 상속과 메서드 오버라이딩 (0) | 2024.07.15 |