프로그래밍 공방

[Java의 정석] Chapter 7. 다형성 / Polymorphism 본문

개발/Java

[Java의 정석] Chapter 7. 다형성 / Polymorphism

hyosupsong 2021. 2. 1. 21:12

다형성 : Polymorphism

여러가지 형태를 가질 수 있는 성질

조상 클래스 타입의 참조 변수로 자손 클래스의 인스턴스를 참조할 수 있게 한다.(반대는 불가능)

1
2
3
4
5
class TV {}
class CaptionTv extends TV {}
 
TV tv = new CaptionTv();
CaptionTV ctv = new CaptionTv();
cs

* 둘 다 같은 타입의 인스턴스지만 참조 변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.

참조 변수의 형변환

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

자손 -> 조상 (up-casting) : 생략 가능
조상 -> 자식 (down-casting) : 생략 불가

1
2
3
4
5
6
7
class TV {}
class CaptionTv extends TV {}
TV tv = new CaptionTv();
 
CaptionTv ctv = new CaptionTv();
TV tv = ctv;
CaptionTv ctv2 = (CaptionTv)tv;
cs

형변환은 참조 변수의 타입을 변환하는 것이지 인스턴스를 변환하는 것은 아니기 때문에 참조 변수의 형변환은 인스턴스에 아무 영향을 끼치지 않는다.

단지, 참조 변수의 형변환을 통해서 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 개수를 조절하는 것 뿐이다.

주의 ) 참조하는 실제 인스턴스가 조상 클래스인 경우는 down casting으로의 형변환이 불가능하다.

1
2
TV tv = new TV();
CaptionTv ctv2 = (CaptionTv)tv;    // 에러
cs

* 컴파일 시에는 참조 변수간의 타입만 확인하기 때문에 실행 시 생성되는 인스턴스의 타입은 알지 못한다. 따라서 컴파일 시에는 문제가 없지만 실행시에 에러가 발생하여 비정상적으로 종료가 된다.

instanceof

참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아내기 위한 연산자

boolean 참조변수 instanceof 타입(클래스명)

true면 해당 타입으로 형변환이 가능 (참조 변수가 가리키고 있는 실제 인스턴스부터 조상까지 전부 true를 반환한다.)

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

조상 클래스에 선언된 멤버변수와 자손 클래스에 선언된 멤버변수의 이름이 같다면 참조변수의 타입에 따라 다른 결과를 얻는다.

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

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
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");
    }
}
 
class BindingTest {
    public static void main(String[] args) {
        Parent p = new Child();
        Child c = new Child();
 
        System.out.println("p.x = " + p.x);    // 100
        p.method();                            // Child Method
 
        System.out.println("c.x = " + c.x);    // 200
        c.method();                            // Child Method
    }
}
cs