들어가며
끝으로 유용하게 사용할 수 있는
상속과 관련된 연산자 하나를
소개하고자 한다.
이 연산자의 피연산자는 참조변수와
클래스의 이름이다.
instanceof 연산자의 기본
연산자 instanceof는 참조변수가 참조하는
인스턴스의 '클래스'나
참조하는 인스턴스가 '상속하는 클래스'를
묻는 연산자이다.
예를 들면 다음과 같이 문장을 구성할 수 있다.
if (ca instanceof Cake)
....
위에서 ca는 참조변수이고 Cake는
클래스 이름이다.
그리고 ca가 참조하는 인스턴스가
Cake의 인스턴스이거나
Cake를 상속하는 클래스의 인스턴스이면
true를, 그렇지 않다면 false를 반환한다.
관련하여 다음 예제를 보자.
class Cake {}
class CheeseCake extends Cake {}
class StrawberryCheeseCake extends CheeseCake {}
class EatCakeOf {
public static void main(String[] arg) {
Cake cake = new StrawberryCheeseCake();
if(cake instanceof Cake) {
System.out.println("Cake instance or");
System.out.println("instance inherited by Cake \n");
}
if(cake instanceof CheeseCake) {
System.out.println("Cake instance or");
System.out.println("instance inherited by Cake \n");
}
if(cake instanceof StrawberryCheeseCake) {
System.out.println("Cake instance or");
System.out.println("instance inherited by Cake \n");
}
}
}
/* 실행 결과
Cake instance or
instance inherited by Cake
Cake instance or
instance inherited by Cake
Cake instance or
instance inherited by Cake
*/
예제에서 선언된 참조변수 Cake가
참조하는 인스턴스는
StrawberryCheeseCake 인스턴스다.
그런데 이 인스턴스의 클래스는 Cake를
상속하는 Cake를 상속하는 CheeseCake를
상속한다.
따라서 위 예제에서 등장하는 3개의
if문의 조건은 모두 true이다.
instanceof 연산자의 활용
다음과 같이 클래스가 정의되어 있는
상황을 고려해보자.
class Box{
public void simpleWrap() {}
}
class PaperBox extends Box{
public void paperWrap() {}
}
class GoldPaperBox extends PaperBox {
public void goldWrap() {}
}
그리고 위 클래스들의 인스턴스를
대상으로 하는
다음 메소드를 정의한다고 가정하자.
public void wrapBox(Box box) {
....
}
위에서 정의한 세 클래스의 인스턴스
모두 위 메소드의 인자로 전달될 수 있다.
따라서 위의 메소드를 다음과 같이
정의하고자 한다.
public void wrapBox(Box box) {
// box가 Box 인스턴스를 참조하면, simpleWrap 메소드 호출
// box가 PaperBox 인스턴스를 참조하면, paperWrap 메소드 호출
// box가 GoldPaperBox 인스턴스를 참조하면, goldWrap 메소드 호출
}
이와 같이 참조변수가 참조하는
인스턴스에 따라서
호출하는 메소드를 달리하는 코드를
작성하는 일은 간단하지 않다.
그러나 instanceof 연산자를 활용하면
비교적 쉽게 이러한 코드를 작성할 수 있다.
다음 예제에서 보여주듯이 말이다.
class Box{
public void simpleWrap() {
System.out.println("Simple Wrapping");
}
}
class PaperBox extends Box{
public void paperWrap() {
System.out.println("Paper Wrapping");
}
}
class GoldPaperBox extends PaperBox {
public void goldWrap() {
System.out.println("Gold Wrapping");
}
}
class Wrapping {
public static void main(String[] args) {
Box box1 = new Box();
PaperBox box2 = new PaperBox();
GoldPaperBox box3 = new GoldPaperBox();
wrapBox(box1);
wrapBox(box2);
wrapBox(box3);
}
public static void wrapBox(Box box) {
if (box instanceof GoldPaperBox)
((GoldPaperBox)box).goldWrap(); // 형 변환 후 메소드 호출
else if (box instanceof PaperBox)
((PaperBox)box).paperWrap(); // 형 변환 후 메소드 호출
else
box.simpleWrap();
}
}
/* 실행 결과
Simple Wrapping
Paper Wrapping
Gold Wrapping
*/
연산자 instanceof는 참조변수가
참조하느 인스턴스의 '클래스'나
참조하는 인스턴스가 '상속하는
클래스'를 묻는 연산자이므로
다음과 같이 이 연산자를 이해해도 된다.
연산자 instanceof는 명시적 형 변환의 가능성을 판단해주는 연산자이다.
예를 들어서 다음 if문의
연산 결과가 true이면,
if (box instanceof GoldPaperBox) {....}
이는 box가 참조하는 인스턴스가
GoldPaperBox 인스턴스 이거나
GoldPaperBox를 상속하는 클래스의
인스턴스라는 뜻으로,
다음과 같이 명시적으로 형 변환을
할 수 있다.
그렇게 명시적 형 변환을 하여, 형 변환된 인스턴스의 메소드를 호출할 수 있다.
if (box instanceof GoldPaperBox)
((GoldPaperBox)box).goldWrap();
참고 및 출처
|