Java 다형성, 다운캐스팅

김정훈·2024년 4월 20일

Java

목록 보기
18/48

다형성

다형성이란 하나의 코드가 여러 자료형으로 구현되어 실행되는 것을 말합니다.

다형성의 장점

다형성을 활용한 프로그램의 확장성

  • 상위 클래스에서 공통 부분의 메서드를 제공하고, 하위 클래스에서는 그에 기반한 추가 요소를 덧붙여 구현하면 코드 양도 줄어들고 유지보수도 편리합니다.
  • 필요에 따라 상속받은 모든 클래스를 하나의 상위 클래스로 처리할 수 있고 다형성에 의해 각 클래스의 여러 가지 구현을 실행 할 수 있으므로 프로그램을 쉽게 확장할 수 있습니다.
  • 다형성을 잘 활용하면 유연하면서도 구조화된 코드를 구현하여 확장성 있고 유지보수하기 좋은 프로그램을 개발할 수 있습니다.

1. 다운 캐스팅과 instanceof

instanceof 연산자

  • instancce : 실체 - 실제로 존재한다.
    클래스라고 하는 객체의 정의(존재x) → new → 힙공간에 존재(생성된 객체)

  • instanceof : 객체의 생성된 출처를 확인하는 연산자
    c instanceof C : c라고 하는 참조변수가 가리키는 객체가 C클래스로 부터 만든 객체인가?(객체의 포함관계)

  • 이 연산자는 어느 객체 변수가 어느 클래스 타입인지 판별해 true/false를 반환해준다. 사용시 주의할 점은 instanceof 연산자는 객체에 대한 클래스(참조형) 타입에만 사용할 수 있다는 점이다. (int, double 같은 primitive 타입에는 사용 불가능)

public class Ex03 {
    public static void main(String[] args) {
        C c = new C();
        A a = c;
        System.out.println(c instanceof C); //true
        System.out.println(c instanceof B); //true
        System.out.println(c instanceof A); //true
        System.out.println(a instanceof C); //true
    }
}

2. 다운캐스팅

위와 같은 계층 구조에서 상위 클래스를 자료형으로 선언하는 Animal ani = new Human(); 업캐스팅을 사용할수있다. 이때 생성된 인스턴스 Human은 Animal형 입니다. 이렇게 Animal형으로 형 변환이 이루어진 경우에는 Animal 클래스에서 선언한 메서드와 멤버 변수만 사용할 수 있습니다.

다시 말해 Human 클래스에 더 많은 메서드가 구현되어 있고 다양한 멤버 변수가 있다고 하더라도 자료형이 Animal형인 상태에서는 사용할 수가 없습니다. 따라서 필요에 따라 다시 원래 인스턴스의 자료형(여기에서는 Human 형)으로 되돌아가야 하는 경우가 있습니다.

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

그렇지만 다운캐스팅을 하게되면 자바에서는 다운 캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야 변환할 때 오류를 막을 수 있습니다.


아래는 원래 자료형이 다르게 업캐스팅한 두객체를 생성하고, 다운캐스팅을 할때의 오류를 보여줍니다.
D클래스를 참조해준 A클래스 타입(자료형)으로 생성된 ad객체
C클래스를 참조해준 A클래스 타입(자료형)으로 생성된 ac객체
C클래스 자료형인 c참조변수에 ad,ac객체를 대입하면 오류가 발생

public class Ex04 {
    public static void main(String[] args) {
        A ad = new D(); 
        //업캐스팅(D클래스로 객체를 생성하고, 그 주소를 A자료형인 ad참조변수에 대입)
        A ac = new C(); //업캐스팅
        
        //C c = ad; 오류발생
        //C c = ac; 오류발생
        //C c = (C)ad; 강제형변환도 오류발생
        if(ad instanceof C){ //false
            C c = (C)ad; //다운캐스팅
        }
        if(ac instanceof C){ //true
            C c = (C)ac; //다운캐스팅
        }
    }
}
package exam03;

import exam01.A;

public class Ex01 {
    public static void main(String[] args) {
        Human human = new Human();  //자료형을 Human, Animal가능
        //human.move();

        Tiger tiger = new Tiger(); //자료형을 Tiger, Animal가능
        //tiger.move();

        Bird bird = new Bird(); //자료형을 Bird, Animal가능
        //bird.move();

        Animal[] animals = new Animal[3];
        animals[0] = human;
        animals[1] = tiger;
        animals[2] = bird;

        for(int i=0; i< animals.length; i++){
            animals[i].move();
        }
    }
}
public class Ex02 {
    public static void main(String[] args) {
        Animal[] animals = {new Human(), new Bird(), new Tiger()};
        for(Animal animal : animals){
            animal.move();
        }

    }
}
package exam03;

public class Ex02 {
    public static void main(String[] args) {
        Animal[] animals = {new Human(), new Bird(), new Tiger()};
        for(Animal animal : animals){
            animal.move();
            if(animal instanceof  Human){ 
                Human human = (Human)animal;//다운캐스팅
                human.reading();
            }else if(animal instanceof Tiger){
                Tiger tiger = (Tiger) animal;//다운캐스팅
                tiger.hunting();
            }
            //human.reading(); //animal이 human bird tiger을 다가지고있어서 오류

        }

    }
}
profile
안녕하세요!

0개의 댓글