※ 참조하는 인스턴스에 관계없이 참조변수의 형(Type)에 따라서 접근가능한 멤버가 결정된다.
참조하는 인스턴스에 따라서 접근 가능한 멤버가 결정되지 않도록 설계한 이유
1. 실행시간을 늦추는 결과로 이어질 수 있다.
-> 자바는 메소드 호출 시 참조변수의 형(Type)을 참조하여 그 메소드 호출이 옳은 것인지 판단한다.
예) MobilePhone phone = new MobilePhone();
phone.answer(); ( MobilePhone 클래스에 answer() 메소드가 존재한다고 가정한다. )
(다음과 같이 컴파일러가 판단하고 컴파일을 한다.)
- 변수 phone의 참조 형이 MobilePhone 이므로 MobilePhone 클래스의 메소드 answer()은 호출 가능.
이러한 형태의 판단은 그 속도가 빠르다. 하지만 참조하는 인스턴스를 대상으로 메소드 호출 가능성을 판단하게
되면 속도가 느릴 수 밖에 없다. 코드의 흐름에 따라서 참조하는 인스턴스는 얼마든지 달라질 수 있기 때문이다.
2. 참조변수의 형을 기준으로 접근 가능한 멤버를 제한하는 것은 코드를 단순하게 한다. ( 중요 )
-> 단점이 많은 일부 기능을 제한함으로써 단순하고 명료한 코드의 작성을 유도하는 언어가 좋은 언어이다.
그런 측면에서 참조변수의 형을 기준으로 접근 가능한 멤버를 제한한 것은 의미가 있는 일이다.
참조변수 간 대입과 형 변환
컴파일러는 ‘참조변수의 형’만을 가지고 대입의 가능성을 판단한다.
“자바는 참조변수의 형(Type)정보를 기준으로 대입의 가능성을 판단한다.”
class Cake {
public void sweet() { . . . }
}
class CheeseCake extends Cake {
public void milky() { . . . }
}
// CheeseCake ca1 = new CheeseCake();
// Cake ca2 = ca1; // 가능
// Cake ca3 = new CheeseCake();
// CheeseCake car = ca3; // 불가능
- Cake ca3 = …
- CheeseCake car = ca3; // 불가능
이 경우에는 ca3가 참조하는 인스턴스가 CheeseCake 인스턴스임은 확신할 수 없다.
(Cake를 상속하는 다른 클래스도 대입할 수 있다.)
따라서 이를 허용하지 않는다. 그러나 다음과 같이 명시적으로 형 변환을 하면 대입이 가능하다.
- Cake ca3 = …
- CheeseCake car = (CheeseCake)ca3; // 가능
이는 ca3가 참조하는 인스턴스가 CheeseCake 인스턴스임을 프로그래머가 보장한다는 의미이다.
따라서 컴파일러는 이를 허용해버린다. 그러니 프로그래머는 이러한 형 변환을 진행하는 경우, 대입의 가능성을 정확히 판단하여 치명적인 실수가 발생하지 않도록 주의해야 한다.
이러한 참조 관계는 배열까지도 이어진다.
- CheeseCake[] cakes = new CheeseCake[10];
- Cake[] cakes = new CheeseCake[10]; // 가능
[참고자료]
윤성우의 열혈 Java 프로그래밍
'Java > 기본' 카테고리의 다른 글
자바(Java) - 추상 클래스 (0) | 2020.02.29 |
---|---|
자바(Java) - 인터페이스 (0) | 2020.02.27 |
자바(Java) - 상속 (0) | 2020.02.26 |
자바(Java) - 다차원 배열 (0) | 2020.02.26 |
자바(Java) StringBuilder, StringBuffer (0) | 2020.02.26 |