각진 세상에 둥근 춤을 추자

[Java] 다운캐스팅과 instanceof 본문

Java

[Java] 다운캐스팅과 instanceof

circle.j 2022. 9. 20. 15:59

상위 클래스(Animal)를 하위 클래스(Human)이 상속받는 경우, Animal ani = new Human(); 이라는 코드를 쓸 수 있다. 
이때, 하위 클래스는 상위 클래스의 자료형인 Animal을 사용한다. 

그렇기 때문에 Animal 클래스에서 선언한 메서드와 멤버 변수만 사용할 수 있다.

만약, 필요에 따라 하위 클래스가 원래의 자료형인 Human으로 되돌아가야 하는 경우에는 어떻게 할까?

상위 클래스로 형 변환되었던 하위 클래스를 다시 원래의 자료형으로 형 변환하는 것을 다운 캐스팅(down casting)이라고 한다.

 

다운 캐스팅을 할 때 주의해야 할 점이 있다.

상속 관계를 살펴 보면 모든 인간은 동물이지만 반대로 모든 동물은 인간이 아니다. 

따라서 다운 캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야 변환 시 오류를 최소화 할 수 있다.

이를 확인하는 예약어가 바로 instanceof이다. 

 

Animal hAnimal = new Human();

if (hAnimal instanceof Human){		// hAnimal의 인스턴스 자료형이 Human형이라면 
	Human human = (Human)hAnimal;	// 인스턴스 hAnimal을 Human형으로 다운 캐스팅한다.

 

원래의 인스턴스형으로 다운 캐스팅하는 프로그램을 작성해 본다.

상위 클래스인 Animal 클래스를 상속받은 여러 동물 클래스를 생성한다.

생성된 Human 클래스, Tiger클래스 , Eagle클래스에는 각각 다른 메서드도 추가로 구현한다.

 

package ch08_6;

import java.util.ArrayList;

// 상위클래스 Animal
	class Animal{
		public void move() {
			System.out.println("동물이 움직인다.");
		}
	}
	
	// Animal을 상속받은 Human 클래스 (하위 클래스)
	class Human extends Animal {
		public void move() {
			System.out.println("사람이 두 발로 걷는다.");
		}
		public void readBook() {
			System.out.println("사람이 책을 읽는다.");
		}
	}
	
	// Animal을 상속받은 Tiger 클래스 (하위 클래스)
	class Tiger extends Animal {
		public void move() {
			System.out.println("호랑이가 네 발로 뛴다.");
		}
		public void hunt() {
			System.out.println("호랑이가 사냥을 한다.");
		}
	}
	
	// Animal을 상속받은 Eagle 클래스 (하위 클래스)
	class Eagle extends Animal{
		public void move() {
			System.out.println("독수리가 하늘을 난다.");
		}
		public void flying() {
			System.out.println("독수리가 날개를 쭉 펴고 멀리 날아간다.");
		}
	}
	

public class AnimalTest {
	ArrayList<Animal> aniList = new ArrayList<Animal>();
	
	public static void main(String[] args) {
		
		AnimalTest aTest = new AnimalTest();
		aTest.addAnimal();
		System.out.println("원래의 자료형으로 다운 캐스팅");
		aTest.testCasting();
	}
	
	public void addAnimal() {
		aniList.add(new Human());
		aniList.add(new Tiger());
		aniList.add(new Eagle());
		
		for (Animal ani : aniList) {
			ani.move();
		}
	}
	
	public void testCasting() {
		for (int i=0; i<aniList.size(); i++) {	// 모든 배열 요소를 하나씩 돌면서
			Animal ani = aniList.get(i);	// Animal 형으로 가지고 온다
			if (ani instanceof Human) {	// Human이면
				Human h = (Human)ani;	// Human 형으로 다운 캐스팅
				h.readBook();
			}else if(ani instanceof Tiger) {
				Tiger t = (Tiger)ani;
				t.hunt();
			}else if(ani instanceof Eagle) {
				Eagle e = (Eagle)ani;
				e.flying();
			}else {
				System.out.println("지원되지 않는 형입니다.");
			}
		}
	}
	
}

'Java' 카테고리의 다른 글

[Java] 템플릿 메서드  (0) 2022.09.20
[Java] 추상 클래스  (0) 2022.09.20
[Java] 다형성 활용하기  (0) 2022.09.20
[Java] 다형성 - VIP 고객 클래스  (0) 2022.09.20
[Java] 다형성  (0) 2022.09.19