다형성 (Polymorphism)

하나의 객체가 여러 개의 자료형을 가질 수 있는 것을 말한다.

상속과 연관이 있으며, 조상 클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있다.

즉, 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 한다.



예제 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
class TV {
    boolean power;
    int channel;
 
    void power() { ... };
    void channelUp() { ... };
    void channelDown() { ... };
}
 
class CaptionTV extends TV {
    String text;
    void caption() { ... };
}
cs



1
Tv tv = new CaptionTv();
cs

Tv 클래스와 CaptionTv 클래스가 상속관계에 있을 경우, 

조상클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조하는 것이 가능하다.


1
2
Tv tv = new CaptionTv();
CaptionTv ctv = new CaptionTv();
cs

tv 변수는 Tv 클래스에서 정의되지 않은 맴버인 text와 caption()을 사용할 수 없다.

tv와 ctv 모두 같은 타입의 인스턴스이지만, 참조변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.


1
2
3
4
5
6
Tv tv = null;
CaptionTv ctv1 = new CaptionTv();
CaptionTv ctv2 = null;
 
tv = ctv1; // 형변환 생략가능 (up-casting)
ctv2 = (CaptionTv) tv;  // 형변환 생략불가 (Down-casting)
cs

Tv 타입의 tv를 자손인 CaptionTv 타입으로 변환하는 것은 참조변수가 다룰 수 있는 멤버의 개수를 늘리는 것이므로,

실제 인스턴스 멤버 개수보다 참조변수가 사용하는 멤버의 개수가 더 많아져 문제가 발생할 수 있기에 형변환을 생략하지 않는다.



instanceof 연산자

특정 객체가 특정 클래스의 객체인지를 조사할 때 사용되는 자바의 내장 키워드

instanceof 왼쪽에는 참조변수를, 오른쪽에는 클래스명이 피연산자로 위치하며, 연산의 결과로 true/false를 리턴한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyInstance {
    public static void main (String args[]) {
        FireEngine fe = new FireEngine();
    
        if (fe instanceof FireEngine) {
            System.out.println("FireEngine 인스턴스");
        }
        if (fe instanceof Car) {
            System.out.println("Car 인스턴스");
        }
        if (fe instanceof Object) {
            System.out.println("오브젝트 인스턴스");
        }
    }
}
 
class Car { ... }
 
class FireEngine extends Car { ... }
cs

결과

FireEngine 인스턴스

Car 인스턴스

오브젝트 인스턴스

즉, instanceof는 fe 객체가 FireEngine, Car, Object으로 만들어진 객체인가를 묻는 조건식이다. 



다형성은 메서드의 매개변수에도 적용된다.

1
2
3
4
5
6
7
8
9
10
11
12
class Product {
    int price, bonuspoint;
}
 
class Tv extends Product { ... }
class Computer extends Product { ... }
class Audio extends Product { ... }
 
class Buyer {
    int money = 1000;
    int bonuspoint = 0;
}
cs

위와 같은 코드가 있을 때, Buyer 클래스에 물건을 구입하는 메서드를 추가할 것이다.


1
2
3
4
5
6
7
8
9
10
11
void buy (TV tv){
    money = money - tv.price;
    bonuspoint = bonuspoint + tv.bonuspoint;
}
 
void buy (Computer computer){
    money = money - computer.price;
    bonuspoint = bonuspoint + computer.bonuspoint;
}
 
...
cs

Tv, Computer, Audio 각각의 buy의 메서드가 필요하고, 제품에 대한 종류가 늘어난다면 새로운 buy() 를 추가해야할 것이다.


1
2
3
4
5
6
7
8
9
10
void buy (Product p){
    money = money - p.price;
    bonuspoint = bonuspoint + p.bonuspoint;
}
 
Buyer b = new Buyer();
Tv tv = new Tv();
Computer computer = new Computer();
b.buy(tv);
b.buy(computer);
cs

다형성을 적용한다면 위와 같은 하나의 메서드로 간단히 처리할 수 있다.

Product 클래스의 자손타입의 참조변수면 어느 것이나 매개변수로 받아들일 수 있다.


즉, 하나의 타입으로 다양한 실행결과를 얻을 수 있으며, 코드 재사용성이 높아지고 유지보수에 용이하다.



다형성은 또 다른 말로 메서드나 클래스를 다양한 방법으로 동작하는 것을 말한다.

오버로딩, 오버라이딩, 인터페이스 등이 다형성을 이용한다.




참고 출처

- 자바의 정석 책

https://wikidocs.net/269


+ Recent posts