JVM 상의 메모리 구조에 관한 문서를 읽으면서 상속 관계는 어떻게 될까 하는 의문이 들었다.
겨우 겨우 이해하면서 외웠었는데 이제는 확실하게 기억할 수 있을 거 같다.
-----------------------------------------------------------------------------------------
부모 클래스의 레퍼런스는 자식 클래스의 객체를 가리킬 수 있지만 자식 틀래스의 레퍼런스는 부모 클래스의 객체를 가리킬 수 없다. 단, 부모 클래스의 레퍼런스는 자식 클래스의 객체 중 부모에게서 상속받은 메서드와 멤버변수만 호출할 수 있다. 자식 클래스에만 있는 메서드와 멤버 변수는 호출할 수 없다.
∵ 부모 클래스의 레퍼런스로 자식 클래스의 객체를 가리킬 경우 메서드를 호출하려면 부모 클래스의 메서드 테이블을 이용한다. 따라서 자식 클래스의 객체 중 부모 클래스의 메서드만을 호출할 수 있는 것이다.
반대로 자식 클래스의 레퍼런스로 부모 클래스의 객체를 가리킬 경우 메서드를 호출하려면 자식 클래스의 메서드 테이블을 이용한다. 그러면 부모 클래스의 객체에는 없는 자식 클래스의 메서드도 호출할 수 있게 되며 이 경우 에러가 발생한다.
사용자가 주의한다면 문제가 되지 않을 수도 있지만 그걸 허용하면 언어 자체에 헛점이 생기는 것이기 때문에 자식 클래스의 레퍼런스로 부모 클래스의 객체를 가리키지 못 하게 한다.
<예제 코드. 함께 기억하면 절대 까먹지 않으리...>
public class ParentJava
{
public int p = 10;
public ParentJava(){}
public int parentGet(){
return p;
}
public void parentSet(int i){
this.p = i;
}
}
public class ChildJava extends ParentJava
{
public int c = 15;
public ChildJava(){}
public int childGet(){
return c;
}
public void childSet(int i){
this.c = i;
}
public static void main(String[] args){
ParentJava pj = new ChildJava();
ChildJava cj = new ParentJava();
System.out.println("pj.parentGet() " + pj.parentGet());
System.out.println("pj.c " + pj.c);
System.out.println("pj.childGet() " + pj.childGet());
System.out.println("cj.parentGet() " + cj.parentGet());
System.out.println("cj.childGet() " + cj.childGet());
}
}
/*
D:\JavaTest>C:\bea\jdk141_05\bin\javac *.java
ChildJava.java:16: incompatible types
found : ParentJava
required: ChildJava
ChildJava cj = new ParentJava();
^
ChildJava.java:19: cannot resolve symbol
symbol : variable c
location: class ParentJava
System.out.println("pj.c " + pj.c);
^
ChildJava.java:20: cannot resolve symbol
symbol : method childGet ()
location: class ParentJava
System.out.println("pj.childGet() " + pj.childGet());
^
3 errors
첫 번째 에러를 보면 자바 언어에서 자식이 부모를 가리키지 못 하도록 하고 있음을 알 수 있다.
두 번째와 세 번째 에러는 부모 클래스의 레퍼런스로는 자식 클래스의 멤버 변수와 메서드를 호출할 수 없다는 것을 보여준다.
댓글을 달아 주세요