본문 바로가기

Java

[Java] 다형성

다형성(polymorphism)

여러 가지 형태를 가질 수 있는 능력.




참조변수의 형변환

기본형 변수와 같이 참조변수도 형변환이 가능하다. 단, 서로 상속관계에 있는 클래스 사이에서만 가능하다.

자손타입 → 조상타입(Up-casting) : 형변환 생략 가능

자손타입 ← 조상타입(Down-casting) : 형변환 생략 불가



Car 클래스와 Car 클래스를 상속받은 FireEngine 클래스가 있을 때, 가능한 형변환은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Car {
    String color;
    int door;
    void drive() {
    }
    void stop() {
    }
}
 
class FireEngine extends Car {
    void water() {
    }
}
cs


1
2
3
4
5
6
Car car = null;
FireEngine fe1 = new FireEngine();
FireEngine fe2 = null;
 
car = fe1;                    // Up-casting
fe2 = (FireEngine)car;        // Down-casting
cs


형변환은 참조변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조변수의 형변환은 인스턴스에 아무런 영향을 미치지 않는다. 단지 참조변수의 형변환을 통해서, 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위(개수)를 조절하는 것 뿐이다.



instanceof 연산자

참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용한다.

'참조변수 instanceof 타입'과 같은 형식으로 사용한다.

instanceof를 이용한 연산결과로 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

1
2
3
4
5
FireEngine fe = new FireEngine();
 
if(fe instanceof FireEngine) {
    ...
}
cs


'참조변수.getClass().getName()'은 참조변수가 가리키고 있는 인스턴스의 클래스 이름을 문자열로 반환한다.

1
System.out.println(fe.getClass().getName());    // FireEngine
cs




참조변수와 인스턴스의 연결

멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우, 참조변수의 타입에 따라 멤버변수가 호출된다.

반면 메서드의 경우에는 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드)가 호출된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Main {
 
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();
        
        System.out.println("p.x = " + p.x);
        p.method();
        
        System.out.println("c.x = " + c.x);
        c.method();
    }
}
 
class Parent {
    int x = 100;
    
    void method() {
        System.out.println("Parent Method");
    }
}
 
class Child extends Parent {
    int x = 200;
    
    void method() {
        System.out.println("Child Method");
    }
}
cs


- 실행 결과




매개변수의 다형성

1
2
3
4
5
6
7
8
9
10
11
12
13
class Product {
    int price;
    int bonusPoint;
}
 
class Tv extends Product {}
class Computer extends Product {}
class Audio extends Product {}

class Buyter {
    int money = 1000;
    int bonusPoint = 0;
}
cs

다음과 같이 Product 클래스와 Product 클래스를 상속받은 Tv, Computer, Audio 클래스가 있고,

물건을 구입하는 사람인 Buyer 클래스가 있다.


Buyer 클래스에 물건을 구입하는 메서드를 추가하기 위해서 아래와 같이 구현한다면, Product 클래스를 상속받은 모든 클래스에 대해 같은 메서드를 추가해주어야 한다.

1
2
3
void buy(Tv t) {
    //...
}
cs


그러나 메서드의 매개변수에 다형성을 적용하면 하나의 메서드로 간단히 해결할 수 있다.

1
2
3
void buy(Product p) {
    //...
}
cs


매개변수가 Product 타입의 참조변수라는 것은 메서드의 매개변수로 Product 클래스의 자손타입의 참조변수면 어느 것이나 매개변수로 받아들일 수 있다는 뜻이다.






참고자료

자바의 정석

'Java' 카테고리의 다른 글

[Java] 추상클래스와 인터페이스  (0) 2019.01.03
[Java] Vector 클래스  (0) 2019.01.03
[Java] 제어자  (0) 2019.01.01
[Java] 상속  (0) 2019.01.01
[Java] 생성자  (0) 2019.01.01