참조변수의 형변환
- 사용할 수 있는 멤버(멤버 변수, 메서드)의 갯수를 조절하는 것
이거 외에는 아무것도 없다!!
주소값이나 객체? 절대 안바뀐다.
- 조상 자손 관계일때만 참조변수 서로 형변환 가능(형제X)
class Car {}
class FireEngine extends Car {}
FireEngine f = new FireEngine();
Car c = (Car)f; //조상인 Car타입으로 형변환(생략가능)
예제
class CastingTest1 {
public static void main(String args[]) {
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;
fe.water();
car = fe; // car =(Car)fe;에서 형변환이 생략된 형태다.
// car.water(); //컴파일 에러! Car타입의 참조변수로는 water()사용불가
fe2 = (FireEngine)car; // 자손타입 ← 조상타입. 형변환 생략 불가
fe2.water();
}
}
class Car {
String color;
int door;
void drive() { // 운전하는 기능
System.out.println("drive, Brrrr~");
}
void stop() { // 멈추는 기능
System.out.println("stop!!!");
}
}
class FireEngine extends Car { // 소방차
void water() { // 물을 뿌리는 기능
System.out.println("water!!!");
}
}
참조변수가 가리키는 실제 객체의 멤버의 수를 넘으면 안된다.
만약 조상 멤버가 4개고 자식이 5개다.
5개를 넘으면 안된다. 형변환 되고 안되고 생략이 되고 안되고가 중요한 게 아니다.
에러 예제
class CastingTest1 {
public static void main(String args[]) {
Car car = new Car();
FireEngine fe = (FireEngine)c; //형변환 에러
fe.water();
}
}
class Car {
String color;
int door;
void drive() { // 운전하는 기능
System.out.println("drive, Brrrr~");
}
void stop() { // 멈추는 기능
System.out.println("stop!!!");
}
}
class FireEngine extends Car { // 소방차
void water() { // 물을 뿌리는 기능
System.out.println("water!!!");
}
}
컴파일 에러는 나지 않는다.
실행시 `ClassCastException`이 발생한다.
❓ 왜일까
실제 객체는 `Car`다. 즉 멤버가 4개다.
근데 `FireEngine`은 5개다. 실제 객체의 멤버 수를 넘을 수 없다.
→ 실제 객체인 `Car`에 `water()`가 존재하지 않는다.
❓ 왜 컴파일 단계에서 에러가 나지 않는가
컴파일러는 형변환 연산자만 써주면 타입만 맞다면 실제 객체가 `Car`인지 아닌지 알 수 없다.
그래서 컴파일은 정상적으로 되나 실행하면 에러가 터지는 것.
instanceof 연산자
- 참조변수의 형변환 가능여부 확인에 사용.
- 가능하면 true반환
public class InstanceofTest {
public static void main(String args[]) {
FireEngine2 fe = new FireEngine2();
Car2 car = new Car2();
if(fe instanceof FireEngine2) {
System.out.println("This is a FireEngine2 instance.");
}
if(fe instanceof Car2) {
System.out.println("This is a Car2 instance.");
}
if(fe instanceof Object) {
System.out.println("This is an Object instance.");
}
if(car instanceof FireEngine2 == false){
System.out.println("불가능");
}
System.out.println(fe.getClass().getName()); // 클래스의 이름을 출력
}
} // class
class Car2 {}
class FireEngine2 extends Car2 {}
❓ 참조변수의 형변환은 왜 하는가
→ 참조변수(리모컨)을 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해
다시 한번 말하지만 객체나 주소값이 바뀌지 않는다! 형만 바뀌는것이다.
❓ instanceof연산자는 언제 사용하나
→ 참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때(일종의 방어코드로 이해했다.)
'📝 끄적끄적 > 🖥️ 자바의 정석' 카테고리의 다른 글
[자바의 정석] - 인터페이스(interface) (0) | 2023.09.26 |
---|---|
[자바의 정석] - 다형성 (0) | 2023.09.25 |
[자바의 정석] - 추상 클래스와 추상메서드 (0) | 2023.09.25 |
[자바의 정석] 제어자, 캡슐화 (0) | 2023.09.24 |
[자바의 정석] 상속, 참조변수 super, 생성자 super() (0) | 2023.09.23 |
[자바의 정석] 생성자, 변수/멤버 변수의 초기화 (0) | 2023.09.22 |