상위 클래스의 참조변수가 참조할 수 있는 대상의 범위
class SmartPhone extends MobilePhone { . . . . }
스마트폰은 모바일폰이다.
SmartPhone phone = new SmartPhone ( "010-555-7777", "Nougat" );
따라서 스마트폰 참조변수로 스마트폰 참조 가능하고,
이 역은 성립하지 않음에 주의! (다운캐스팅 안됨)
MobilePhone phone = new SmartPhone( "010-555-777", "Nougat" );
모바일폰 참조변수로 스마트폰 참조도 가능하다. (업캐스팅 가능)
단 , 업캐스팅 시 SmartPhone 인스턴스 생성되었지만 메서드는 MobilePhone에 제한된다. SmartPhone에 만 있는 기능은 사용 못함!!
참조변수의 참조 가능성에 대한 정리
class Cake {
public void sweet() { ... }
}
class CheeseCake extends Cake {
public void milky() { ... }
}
class StrawberrCheeseCake extends CheeseCake {
public void sour() { ... }
}
Cake cake1 = new StrawberrCheeseCake(); // 접근은 Cake 클래스 변수와, 메소드만 가능
CheeseCake cake2 = new StrawberryCheeseCake(); // 접근은 CheeseCake 클래스 변수와, 메소드만 가능
참조변수 간 대입과 형 변환
class Cake {
public void sweet() { ... }
}
class CheeseCake extends Cake {
public void milky() { ... }
}
CheeseCake ca1 = new CheeseCake();
Cake ca2 = ca1; // 가능!
Cake ca3 = new CheeseCake();
CheeseCake ca4 = ca3; // 불가능!
이 시점에 컴파일러 및 가상머신은 ca3가 참조하는 대상을 Cake 인스턴스로 판단한다!
ca3가 참조하는 인스턴스의 정확한 클래스 정보는 유지하지 않는다.
참조변수의 참조 가능성 : 배열 기반
class Cake {
public void sweet() { ... }
}
class CheeseCake extends Cake {
public void milky() { ... }
}
Cake cake = new CheeseCake(); 가능!
CheeseCake[] cakes = new CheeseCake[10]; 가능!
Cake[] cakes = new CheeseCake[10]; 가능!
상속의 관계가 배열 인스턴스의 참조 관계까지 이어진다.
메소드 오버라이딩 1
class Cake {
public void yummy() {
System.out.println( "Yummy Cake" );
}
}
class CheeseCake extends Cake {
public void yummy() {
System.out.println( "Yummy Cheese Cake" );
}
}
오버라이딩 관계
CheeseCake의 yummy 메소드가 Cake의 yummy 메소드를 오버라이딩!
public static void main( String[] args ) {
Cake c1= new CheeseCake();
CheeseCake c2 = new CheeseCake();
c1.yummy(); // 오버라이드 했기때문에 참조변수 Cake 메소드가 아닌 인스턴스 오버라이딩 된 메서드 호출됨!
c2.yummy();
}
메소드 오버라이딩 2
class Cake {
public void yummy() { ... }
}
class CheeseCake extends Cake {
public void yummy() { ... } // Cake의 yummy를 오버라이딩
}
class StrawberryCheeseCake extends CheeseCake {
public void yummy() { ... } // 그리고 CheeseCake의 yummy를 오버라이딩
}
public static void main(String[] args) {
Cake c1 = new StrawberryCheeseCake();
CheeseCake c2 = new StrawberryCheeseCake();
StrawberryCheeseCake c3 = new StrawberryCheeseCake();
c1.yummy(); // StrawberryCheeseCake 메소드 호출
c2.yummy(); // StrawberryCheeseCake 메소드 호출
}
오버라이딩 된 메소드 호출하는 방법
class Cake {
public void yummy() {
System.out.println( "Yummy Cake" );
}
}
class CheeseCake extends Cake {
public void yummy() {
super.yummy();
System.out.println( "Yummy Cheese Cake" );
}
public void tasty() {
super.yummy();
System.out.println( "Yummy Tasty Cake" );
}
}
오버라이딩 된 메소드를 인스턴스 외부에서 호출하는 방법은 없다.
그러나 인스턴스 내부에서는 키워드 super를 이용해 호출 가능
인스턴스 변수와 클래스 변수도 오버라이딩이 되는가?
class Cake {
public int size;
....
}
class CheeseCake extends Cake {
public int size;
....
}
CheeseCake c1 = new CheeseCake();
c1.size = ... // CheeseCake의 size에 접근
Cake c2 = new CheeseCake();
c2.size = ... // Cake의 size에 접근
인스턴스 변수는 오버라이딩 되지 않는다. 따라서 참조변수의 형에 따라 접근하는 멤버가 결정된다.
'# 02 > Java' 카테고리의 다른 글
[윤성우 열혈자바] 16-1. 상속이 도움이 되는 상황의 소개 (0) | 2019.10.22 |
---|---|
[윤성우 열혈자바] 15-3. instanceof 연산자 (0) | 2019.10.22 |
[윤성우 열혈자바] 15-1. 상속을 위한 두 클래스의 관계 (0) | 2019.10.22 |
[윤성우 열혈자바] 14-2. 클래스 변수, 클래스 메소드와 상속 (0) | 2019.10.22 |
[윤성우 열혈자바] 14-1. 상속의 기본 문법 이해 (0) | 2019.10.22 |