본문 바로가기
공부/자바

다형성(polymorphism)

by xladmt 2024. 5. 31.

다형성이란?

자바에서 다형성이란 한 타입의 참조변수로 여러 타입의 객체로 참조할 수 있도록 함으로써 조상 클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 하였다. 

 

class Tv{
    boolean power;
    int channel;
    
    void power(){}
    void channelUp(){}
    void channelDown(){}
}
class CaptionTv extends Tv{
    String text;
    void caption(){}
}

 

Tv와 CaptionTv 클래스가 서로 상속관계에 있을 경우, 다음과 같이 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조하도록 하는 것도 가능하다.

Tv t = new CaptionTv();   // 조상 타입의 참조변수로 자손 인스턴스를 참조

 

 

  • 인스턴트를 같은 타입의 참조변수로 참조하는 것과 조상타입의 참조변수로 참조하는 것의 차이
CaptionTv c = new CaptionTv();
Tv t = new CaptionTv();

- 인스턴스가 CaptionTv타입이라 할지라도,참조변수 t로는 CaptionTv 인스턴스의 모든 멤버를 사용할 수 없다. Tv타입의 참조변수로는 CaptionTv 인스턴스 중에서 Tv클래스의 멤버들(상속받은 멤버 포함)만 사용할 수 있다.

- 따라서, 생성된 CaptionTv인스턴스의 멤버 중에서 Tv클래스에 정의 되지 않은 멤버, text와 caption()은 참조변수 t로 사용이 불가능하다.

- 둘 다 같은 타입의 인스턴스지만 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다. 참조변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 한다.

조상타입의 참조변수로 자손타입의 인스턴스를 참조할 수 있다. 
반대로 자손타입의 참조변수로 조상타입의 인스턴스를 참조할 수는 없다.

 

다형성의 장점

① 다형적 매개변수
② 하나의 배열로 여러 종류 객체 다루기

 

 

참조변수의 형변환

자손타입 -------> 조상타입(Up-casting)       : 형변환 생략가능
자손타입 <------- 조상타입(Down-casting)   : 형변환 생략불가
  • 형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다.
  • 단지 참조변수의 형변환을 통해서, 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것 뿐이다.

 

서로 상속관계에 있는 타입간의 형변환은 양방향으로 자유롭게 수행될 수 있으나, 참조변수가 가리키는 이스턴스의 자손타입으로 형변환은 허용되지 않는다. 그래서 참조변수가 가리키는 인스턴스의 타입이 무엇인지 확인하는 것이 중요하다.

 

 

instanceof 연산자

참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof연산자를 사용한다. 어떤 타입에 대한 instanceof연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

① 형변환 전, instanceof로 확인
② 확인 결과 true이면 형변환

 

코드로 이해하기

class InstanceofTest{
    public static void main(String args[]){
        FireEngine fe = new FireEngine();

        if(fe instanceof FireEngine){
            System.out.println("FireEngine instance");
        }

        if(fe instanceof Car){
            System.out.println("Car instance");
        }

        if(fe instanceof Object){
            System.out.println("Object instance");
        }

        System.out.println(fe.getClass().getName()); // 클래스 이름 출력
       }
}

class Car {}
class FireEngine extends Car {}

// 출력 결과
// FireEngine instance
// Car instance
// Object instance
// FireEngine

 

 

[참고]

Java의 정석 (남궁성 저)

'공부 > 자바' 카테고리의 다른 글

인터페이스(interface)  (0) 2024.05.31
추상 클래스(abstract class)  (0) 2024.05.31
제어자(modifier)  (0) 2024.05.31
Package & import  (0) 2024.05.31
오버라이딩(overriding)  (0) 2024.05.31