JAVA/자바의 정석

[자바의 정석 - 기초편] 7. (7) 다형성 ( 참조변수의 형변환 / instanceof 연산자 )

서영22 2023. 11. 30. 20:34

 참조변수의 형변환 

사용할 수 있는 멤버의 개수를 조절하는 것

 

- 조상 & 자손 관계의 참조변수는 서로 형변환 가능

- 형제 관계는 불가능

 

* 객체가 NULL이어도 형변환 가능하지만, 실행하면 NullPointException 발생

* 실제 인스턴스를 확인하고 그 멤버의 개수를 넘어서면 안됨

 

class Car { }
class FireEngine extends Car { }
class Ambulance extends Car { }

FireEngine f = new FireEngine();

Car c = (Car) f;                            // OK. 조상인 Car타입으로 형변환 (생략가능)
FireEngine f2 = (FireEngine) c;  // OK. 자손인 FireEngine타입으로 형변환 (생략불가)
Ambulance a = (Ambulance) f;  // 에러. 상속관계가 아닌 클래스 간의 형변환 불가

 

 

참조변수 c에 참조변수 f의 주소값을 대입  ➔  객체는 5개의 멤버변수를 갖고있지만 조상인 Car 은 멤버변수 4개를 갖고 있어서 4개만 사용가능함

 

참조변수 f2에 참조변수 c의 주소값을 대입  ➔  Car 은 멤버변수 4개를 갖고 있지만 FireEngine은 5개를 갖고있어서 다시 5개 모두 사용가능

 

 

 

< 예제  1 >

 

 

자식 ➔ 조상 : 개수를 줄이기 때문에 안전 : 형변환 생략 O

조상 ➔ 자식 : 개수를 늘리기 때문에 불안전 : 형변환 생략 X

 

생략 가능해도 되도록이면 그냥 형변환 붙이는 게 좋음

 

 

 

< 예제 2 >

 

 

문제 : 컴파일 OK지만 형변환 실행 에러뜸!!

 

이유 : 객체가 Car 이기 때문에 애초에 water()가 없음

          리모콘만 버튼 있고 티비에는 기능 없는 셈

 

 

참조 변수들이 가리키는 실제 인스턴스가 무엇인지가 가장 중요!

 

 

 

 instanceof 연산자 

참조변수의 형변환 가능여부 확인에 사용

 

- 가능하다면 true 반환

- 형변환 전에 반드시 instanceof로 확인해야함

 

void dowork (Car c) {
       if (c instanceof FireEngine) {              // 1. 형변환이 가능한지 확인
              FireEngine fe = (FireEngine) c;   // 2. 형변환
              fe.water();
              ....
FireEngine fe = new FireEngine();
System.out.println(fe instanceof Object);          // true
System.out.println(fe instanceof Car);              // true
System.out.println(fe instanceof FireEngine);  // true

   Object obj = (Object) fe;   // OK
   Car c = (car) fe;                // OK

자기 자신과 조상에 대해서 참이 나옴