package org.opentutorials.javatutorials.polymorphism;
class A{}
class B extends A{}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();
}
}
이상하게 보이겠지만 클래스 B의 데이터 형이 클래스 A이다. 클래스 B는 클래스 A를 상속하고 있다. 이런 경우에 클래스 B는 클래스 A를 데이터 형으로 삼을 수 있다. 그럼 이렇게 하는 이유가 무엇인가 궁금해 질 것이다. 위의 코드를 변경한 아래의 코드를 보자.
package org.opentutorials.javatutorials.polymorphism;
class A{
public String x(){return "x";}
}
class B extends A{
public String y(){return "y";}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();
obj.x();
obj.y();
}
}
차이점은 아래와 같다.
아래 코드는 실행이 된다.
obj.x();
하지만 아래 코드는 실행되지 않는다.
obj.y();
클래스 B는 메소드 y를 가지고 있다. 그럼에도 불구하고 메소드 y가 마치 존재하지 않는 것처럼 실행되지 않고 있다. 10행의 코드를 아래와 같이 변경해보자.
B obj = new B();
그럼 아래 코드가 실행될 것이다.
obj.y();
즉 클래스 B의 데이터 형을 클래스 A로 하면 클래스 B는 마치 클래스 A인것처럼 동작하게 되는 것이다. 클래스 B를 사용하는 입장에서는 클래스 B를 클래스 A인것처럼 사용하면 된다. 여전히 왜 이런 기능이 있는지 의구심이 풀리지 않을 것이다. 아래 코드를 보자.
package org.opentutorials.javatutorials.polymorphism;
class A{
public String x(){return "A.x";}
}
class B extends A{
public String x(){return "B.x";}
public String y(){return "y";}
}
public class PolymorphismDemo1 {
public static void main(String[] args) {
A obj = new B();
System.out.println(obj.x());
}
}
차이점은 아래와 같다.
클래스 A의 메소드 x를 클래스 B에서 오버라이딩하고 있다. 실행 결과는 아래와 같다.
B.x
엄청 헷갈릴 것이다. 찬찬히 따져보자.
- 클래스 B의 데이터 타입을 클래스 A로 인스턴스화 했을 때 클래스 B의 메소드 y는 마치 존재하지 않는 것처럼 실행되지 않았다. => 클래스 B가 클래스 A화 되었다.
- 클래스 B의 데이터 타입을 클래스 A로해서 인스턴스화 했을 때 클래스 B의 메소드 x를 실행하면 클래스 A에서 정의된 메소드가 아니라 클래스 B에서 정의된 메소드가 실행 되었다. => 클래스 B의 기본적인 성질은 그대로 간직하고 있다.
정리해보면 아래와 같다.
클래스 B를 클래스 A의 데이터 타입으로 인스턴스화 했을 때 클래스 A에 존재하는 맴버만이 클래스 B의 맴버가 된다. 동시에 클래스 B에서 오버라이딩한 맴버의 동작방식은 그대로 유지한다.