[작성일: 2023. 01. 29]
목차
참조변수의 형변환
- 사용할 수 있는 멤버의 개수를 조절하는 것(값이 달라지는 것이 아님) ➡ 리모콘을 변경하는 것
- 조상 자손 관계의 참조변수는 서로 형변환 가능
- 멤버의 갯수를 늘리는 형변환은 자동 형변환 되지 않으므로 형변환 생략 불가
- 참조변수가 가리키는 실제 객체가 중요함.
class Ex7_7 {
public static void main(String[] args) {
Car car = null;
// 객체가 없어도 형변환에는 문제가 없으나 실행시 에러
// 실제 인스턴스가 무엇인지 중요함
FireEngine fe = new FireEngine();
FireEngine f2 = null;
fe.water();
car = fe;
car.water(); // 에러. Car타입의 참조변수로는 water() 호출 불가능
fe2 = (FireEngine)car;
fe2.water();
car.drive();
Car car = (Car)fe; // 가능. 조상인 Car 타입으로 형변환(생략 가능)
FireEngine f2 = (FireEngine)car; // 가능. 자손인 FireEngine 타입으로 형변환(생략 불가)
Ambulance a = (Ambulance)fe; // 불가능. 상속관계가 아닌 클래스 간의 형변환 불가
c.water(); // 에러
}
}
class Car {
String color;
int door;
void dirve() {
System.out.println("drive, Brrrr~");
}
void stop() {
System.out.println("Stop!!!");
}
}
class FireEngine extends Car {
void water() {
System.out.println("water!!!");
}
}
class Ambulance extends Car {
}
instanceof 연산자
- 참조변수의 형변환 가능여부 확인에 사용 ➡ 가능하면 true 반환
- 형변환 전에 반드시 instanceof 연산자로 확인하고 형변환 해야 함
- 형변환을 하는 이유는 인스턴스의 원래 기능을 모두 사용하기 위해서인데 Car 타입의 리모콘인 c로는 water()를 호출할 수 없으니까 리모콘을 FireEngine타입으로 바꿔서 water()를 호출하는 것.
void doWork(Car c) {
if(c instanceof FireEngine) { // 1. 형변환이 가능한지 확인
FireEngine fe = (FireEngine)c; // 2. 형변환
fe.water();
...
} else if(c instanceof Ambulance) {
Ambulance a = (Ambulance)c;
}
}
// doWork(Car c) 대신에
// doWork(new Car());
// doWork(new FireEngine());
// doWork(new Ambulance()); 모두 가능
/* Car c = new FireEngine();
doWork(c); 와 같은 의미 */
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
// 상속계층도에서 조상은 모두 true가 나옴
Object obj = (Object)fe; // 가능
Car c = (Car)fe; // 가능
클래스의 형변환
Parent p = new Child();
// O 부모의 메서드를 자식이 다 가지고 있기 때문에 new Child가 가능함.
Child c = new Parent(); // 불가능
Child c = (Child) p; // O
// 부모의 메서드이지만 내용은 새롭게 오버라이딩 된 기능을 사용할 수 있음.
Parent Child Nephew Cousin
void Method(Child) // X
void Method(Prent p) {
}
// 위 예제와 같이 상속받은 클래스가 늘어날 때에도 메서드를 새로 만들 필요가 없음.
Food 갈비탕 라면 돈가스
void eat(Food f) {
if (f가 갈비탕이면) {
간장소스 제공
}
else if (f가 라면이면) {
김치 제공
} else {
물 제공
}
}
Q&A
Q. 참조변수의 형변환은 왜 하나요?
A. 참조변수(리모콘)을 변경함으로써 사용할 수 있는 멤버의 개수를 조절하기 위해
FireEngine f = new FireEngine();
Car c = (Car)f; // 가능
Q. instanceof 연산자는 언제 사용하나요?
A. 참조변수를 형변환하기 전에 형변환 가능여부를 확인하고자 할 때
🐣 해당 게시글은 자바의 정석(남궁성 님) 영상으로 함께 공부하며 요약/정리한 글입니다.
🐣 입문 개발자가 작성한 글이므로 틀린 내용이나 오타가 있을 수 있습니다.