[Java] #27 상속 5 (instanceof)

febCho·2024년 1월 9일
0

Java

목록 보기
51/53

instanceof는 상속 관계일 때 생성된 객체가 해당 자료형을 사용할 수 있는지 검증할 때 사용한다.

다음 예제를 보자.

package kr.s24.object3.instanceoftest;

//부모 클래스
class Parent{
	@Override
	public String toString() {
		return "Parent 클래스";
	}
}

//자식 클래스
class Child extends Parent{
	@Override
	public String toString() {
		return "Child 클래스";
	}
}
public class InstanceofMain01 {
	public static void main(String[] args) {
		Parent p = new Parent();
		
		//Child ch = (Child)p;
		
		if(p instanceof Child) {
			//생성된 객체가 Child 타입을 사용할 수 있음
			Child ch2 = (Child)p;
			System.out.println(ch2);
			System.out.println("~~~~~~~~~~~~~~");
		}else {
			//생성된 객체가 Child 타입을 사용할 수 없음
			System.out.println(p);
			System.out.println("+++++++++++++++");
		}
		
	}
}
  • Parent
  1. 우선 부모 클래스인 Parent는 모든 클래스에 자동으로 상속되는 Object의 toString() 메서드를 재정의하였다. 따라서 부모 클래스의 참조자료형을 출력할 경우 객체의 참조값이 반환되는 대신, 'Parent 클래스'를 반환한다.
  • Child
  1. 자식 클래스인 Child는 Parent를 상속 받아, Parent의 toString() 메서드를 재정의하여 'Child 클래스'를 반환하도록 하였다.
  • InstanceofMain01
  1. 메인 메서드에서 객체 생성 시, 자식 클래스가 아닌 부모 클래스의 타입을 사용한다.
    ex. Parent p = new Parent();

  2. 이와 같이 생성할 경우, 부모 클래스와 Object 클래스만 메모리에 올라간다. 따라서 메모리에 Child가 없기 때문에 Parent 객체인 p를 Child ch = (Child)p;와 같이 형변환 해줄 수 없다.
    주의할 점은 위 코드 작성 시 컴파일 오류는 없으나 실행 시 오류가 발생한다는 점이다.

  3. 이때 instanceof를 사용해 생성된 객체인 p가 Child라는 자료형을 사용할 수 있는지 테스트할 수 있다.
    ex. if(p instanceof Child)

  4. 만약 Child를 사용할 수 있다면 Child ch2 = (Child)p; 형변환을 하고, 참조자료형 ch2를 출력하면 재정의된 toString()에 따라 아래와 출력될 것이다.

출력 예시)
Child 클래스
~~~~~~~~~~~~~~
  1. 하지만 앞서 말한 것처럼 메모리에 Parent와 Object만 올라간 상황에서 p는 Child 자료형을 사용할 수가 없다. 따라서 else로 빠져 아래와 같이 출력된다.
출력)
Parent 클래스
+++++++++++++++

instanceof를 확실히 이해하기 위해 이번에는 생성된 객체가 사용할 수 있는 자료형일 때 어떻게 출력되는지를 보자.

package kr.s24.object3.instanceoftest;

//부모 클래스
class Car{
	public void drive() {
		System.out.println("주행~~");
	}
	public void stop() {
		System.out.println("정지!!");
	}
}

//자식 클래스
class FireEngine extends Car{
	public void water() {
		System.out.println("물 뿌리기");
	}
}
public class InstanceofMain02 {
	public static void main(String[] args) {
		FireEngine fe = new FireEngine();
		
		if(fe instanceof FireEngine) {
			System.out.println("This is a FireEngine instance");
		}
		
		if(fe instanceof Car) {
			System.out.println("This is a Car instance");
		}
		
		if(fe instanceof Object) {
			System.out.println("This is an Object instance");
		}
		
	}
}
  1. 자식 클래스인 FireEngine은 부모 클래스인 Car를 상속 받는다.

  2. 그리고 InstanceOfMain02 클래스의 메인 메서드에서 FireEngine 객체를 생성한다.
    ex. FireEngine fe = new FireEngine();

  3. instanceof를 통해 FireEngine 타입인 fe가 각각 FireEngine, Car, Object로 형변환 될 수 있는지(사용할 수 있는지) 체크해본다.

  4. FireEngine은 Car를 상속 받았고, Car는 Object를 자동으로 상속 받기에 FireEngine과 함께 Car, Object 모두 메모리에 올라가 있다. 따라서 FireEngine이 Car와 Object를 모두 사용할 수 있으므로 출력 결과는 다음과 같다.

출력)
This is a FireEngine instance
This is a Car instance
This is an Object instance
profile
Done is better than perfect.

0개의 댓글