[Java] 참조형식과 호출되는 메서드의 관계
아래와 같은 부모, 자식 클래스가 있다고 가정하자.
public class Parent {
// 생략
}
public class Child extends Parents {
// 생략
}
그럼 당연히 아래와 같이 부모, 자식 클래스의 각 인스턴스 변수(parent, child)를 생성할 수 있다.
public class Main {
public static void main(String[] args) {
Parent parent = new Parent();
Child child = new Child();
}
}
그렇다면 아래와 같이 인스턴스를 생성할 수 있을까?
public class Main {
public static void main(String[] args) {
Parent A = new Child();
Child A = new Parent();
}
}
정답은 Parent A = new Child(); 만 가능하다.
Why?
Child 클래스는 Parent 클래스의 자식이기 때문에 데이터를 담고 있는 크기가 적어도 같거나 클 수밖에 없다.
* 자식 클래스가 새로운 메서드나 필드를 선언하는 순간, 자식 클래스의 데이터가 부모 클래스가 가진 데이터의 양보다 커질 수밖에 없다.
자바에서는 new 연산자를 통해 인스턴스를 생성하는데 이는 곧 해당 클래스를 참조한다('난 네가 가진 필드와 메서드를 사용할거야!')는 의미이기도 하다.
// A의 자료형이 a라는 인스턴스 변수는 A라는 클래스(자기 자신을)를 참조한다.
A a = new A();
자바에서는 어떤 자료형의 인스턴스 변수가 어떤 클래스를 참조할 때는 참조되는 클래스의 크기가 더 커야한다.
정리하자면, 참조되는 클래스의 데이터가 더 커야하므로 자식 클래스의 자료형을 가진 인스턴스 변수가 부모 클래스를 참조할 수 없고 부모 클래스의 자료형을 가진 인스턴스 변수는 자식 클래스를 참조할 수 있다.
Parent 클래스에 "Hello"를 출력하는 printHello 메서드가 있다고 가정해보자.
그리고 Child 클래스가 printHello 메서드를 오버라이딩하여 "Hello Hello"를 출력한다고 가정해보자.
그렇다면 Parent A = new Child(); 이와 같이 A라는 인스턴스 변수를 만들고 A.printHello 함수를 호출하면 어떻게 될까?
정답은 오버라이딩 된 "Hello Hello"를 출력한다.
이유는 자바는 참조형식의 함수보다 객체형식의 함수 호출을 우선으로 하기 때문이다.