● 서로 상속 관계인 부모 자식관계의 클래스 사이에서는 서로 형 변환이 가능하다 조상 타입을 자손 타입으로 형 변환을 (DOWN-CASTING) 그 반대를 (UP-CASTING)이라고 한다.
class Car {
String color;
int door;
void drive() {
System.out.println("drive,Brrrr~");
}
void stop() {
System.out.println("멈춰!");
}
}
class FireEngine extends Car {
void water() {
System.out.println("water!!");
}
}
Car클래스를 상속받은 FireEngine클래스이다.
※다시한번 다형성 PART-1의 개념을 반복해보자면, Car타입(조상 타입) 참조 변수로 FireEngine타입(자손 타입) 인스턴스를 참조하는 것이 가능하나 그 반대는 불가능하다.
public class Casting{
public static void main(String[] args) {
Car car ;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;
fe.water();
car = (Car)fe; // Up-casting
fe2 = (FireEngine)car; // Down-casting
fe2.water();
car.water(); // Error!! --> Why?
}
}
car = (Car)fe; (UP-CASTING)
fe2 = (FireEngine)car; (DOWN-CASTING)
기본형의 형변환과 마찬가지로 변환하고자 하는 타입을 참조 변수 앞 소괄호에 기입해준다. (UP-CASTING)의 경우 형 변환 생략이 가능하다. 자손 간에는 형 변환은 가능하지 않고 오로지 상속관계에서만 서로의 형변환이 가능하다.
다시 위의 코드를 살펴보면 Car 타입의 참조변수는 선언만 했을 뿐 인스턴스를 생성하지 않았다. 따라서 참조 변수 car로는 할 수 있는 게 아무것도 없다.
FireEngine은 인스턴스를 생성하였고 FireEngine은 Car를 상속받았다. 이때 car = (Car) fe; 형변환을 해주면 참조변수car에 fe가 참조하고 있는 인스턴스의 주소가 car에 저장이 되고, 따라서 car는 이 주소를 가지고 FireEngine의 인스턴스를 참조하여 멤버들을 호출할 수 있게 된다.
하지만, car.water(); 메서드가 에러가 난 것을 확인할 수 있는데 이는 다형성에서 조상 타입의 참조변수로 자손 타입의 인스턴스를 형성했을 때 쓸 수 있는 멤버는 조상 클래스의 멤버밖에 쓸 수 없는 것과 같은 논리이다. 따라서 FireEngine인스턴스를 가리키는 fe를 Car타입으로 형변환을 시켜도 접근할 수 있는 멤버 수는 Car타입 멤버 4가지 바로 door , color , drive() , stop()이다.
그렇다면 참조변수의 형변환은 무엇이 목적인가? 바로 참조하는 인스턴스가 사용할 수 있는 멤버의 개수를 조절하는 것인데 이를 조절하는 것이 무엇이 중요하고 왜 써야하는가는 나중에 알아볼것이다. 지금은 멤버의 개수를 조절하는것이 참조변수의 형변환의 목적이라는 것을 잘 알아두자
※주의해야 할 점
public class Casting2 {
public static void main(String[] args) {
Car car = new Car();
Car car2 = null;
FireEngine fe = null;
car.drive();
fe=(FireEngine)car; // Error!! --> Why?
fe.drive();
car2 = fe;
car2.drive();
}
}
위 코드에서 Error가 난 부분을 보면 평범한 Down-casting인데 실행결과에서 에러가 발생한다? 그 이유는 무엇일까?
바로 이전 포스팅 다형성 PART-1에서 배웠던 "자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다."를 기억하는가? 지금 참조변수car는 인스턴스를 가리키고 있다. 자손타입의 fe에 Car인스턴스의 주소를 넣어주려고 하는 것이다. 이는 fe가 다룰 수 있는 멤버의 개수가 Car인스턴스의 멤버 개수보다 많기 때문에, 오류를 일으켜 실행결과 에러가 난다. (fe는 버튼 5개의 리모컨이고 Car는 기능이 4개인 tv 따라서 fe에는 눌러도 아무 일이 일어나지 않는 불량품 버튼이 생기는 것과 같은 논리)
간단하게 정리하자면 다음과 같다.
상속관계의 타입 간 자손 <--> 조상 형변환은 자유롭다.
참조변수의 형변환의 목적은 인스턴스로 접근할 수 있는 멤버개수의 조절이다.
참조변수가 인스턴스를 가리키고 있을때, 해당 인스턴스의 자손타입으로는 형변환이 불가능하다, 따라서 참조변수가 가리키는 인스턴스의 타입이 어떻게 되는지를 확인하는 것은 매우 중요하다.
'Java > Java Study' 카테고리의 다른 글
this & this( ) & super (5월/13일 내용추가) (0) | 2021.05.10 |
---|---|
오버라이딩 vs 오버로딩 (0) | 2021.05.08 |
[객체지향] 다형성, Polymorphism - Part1 (0) | 2021.04.26 |
new 연산자 와 객체생성에 대하여 (0) | 2021.04.24 |
Call by value (0) | 2021.04.19 |