Java/Java Study

[객체지향] 다형성, Polymorphism - Part1

모모토 2021. 4. 26. 18:16
반응형

● 서로 상속관계에 있는 클래스 사이에서, 조상 클래스 타입의 참조 변수로 자손 클래스의 인스턴스를 참조할 수 있도록 하는 것을 다형성이라고 부른다.

 

 

위 문장만으론 다형성에 대한 감이 오질 않으니 코드를 보면서 객체를 생성해보자

 

class Tv {
	boolean power;
	int channel;
	
	void power() {}
	void channelUp() {}
	void channelDown() {}
}

class CaptionTv extends Tv {
	String text;
	void caption() {}
}

 

위의 코드를 참조하여 Tv와 CaptionTv의 객체를 생성하면 다음과 같다.

 

Tv tv1 = new Tv();

CaptionTv tv2 = new CaptionTv();

 

일반적인 객체 생성은 위처럼 Tv인스턴스를 다루기 위해서는 Tv타입과 일치하는 참조 변수만을 사용하여 객체를 생성하였는데, 다형성을 적용하면 다음과 같이 객체를 생성할 수 있다.

 

Tv tv1 = new CaptionTv();

 

바로 조상 클래스 타입의 참조 변수로 자손 클래스 타입의 인스턴스를 참조하도록 하는 것이 가능해지는 것이다. 단 주의해야 할 것은 상속관계일 때만 가능하다는 것이다. 그렇다면 이러한 방식의 객체 생성은 기존과 무엇이 다를까? 

 

바로 참조 변수의 타입에 따라 사용할 수 있는 멤버의 개수가 달라진다.

 

위의 코드를 참조하면 Tv클래스의 멤버 변수는 5개이다.

boolean power;

int channel;
void power() {}
void channelUp() {}
void channelDown() {}

 

이 클래스를 상속받은 CaptionTv의 멤버 변수는 자신의 멤버변수 2개와 상속받은 멤버변수 5개를 합하여 7개이다.

boolean power;
int channel;
void power() {}
void channelUp() {}
void channelDown() {}

String text;
void caption() {}

 

CaptionTv타입의 참조 변수로는 CaptionTv클래스에 정의된 멤버변수 2개와 Tv로부터 상속받은 멤버변수 5개를 사용 가능하지만 Tv타입의 참조 변수로 CaptionTv 객체를 생성해도 CaptionTv의 멤버 변수를 제외한 자기 자신의 멤버 변수 5개밖에 사용할 수 없다.

 

Tv tv1 = new CaptionTv();

CaptionTv tv2 = new CaptionTv(); 

 

tv1.power(); // Ok

tv2.power(); // Ok

tv1.caption(); // Error -> Tv타입 참조 변수 t1으로는 CaptionTv타입 인스턴스의 모든 멤버 변수를 사용할 수 없다.

tv2.caption(); // Ok

 

그렇다면 반대는 가능할까?

 

CaptionTv tv2 = new Tv();

 

결론부터 말하면 불가능하다. 그 이유는 CaptionTv로 가리킬 수 있는 멤버 변수는 위에서 말했듯 7가지의 멤버 변수이지만 Tv인스턴스의 멤버 변수는 5개밖에 안되기 때문에 불가능하다. 좀 더 이해가 가기 쉽게 설명하자면 CaptionTv타입의 참조 변수는 7개의 버튼이 있는 리모컨이고 이 리모컨으로 Tv인스턴스를 다룰 수 있다. 하지만 Tv인스턴스는 멤버 변수가 5개 즉 기능이 5개밖에 없는 Tv인데 버튼이 7개인 리모컨으로 조작하다 보면 2개의 버튼은 작동하지 않는다. 현실에서 이러한 리모컨과 Tv는 불량품이다. 프로그래밍에서도 마찬가지다. 이러한 오류를 막기 위해서 자손 타입의 참조 변수로 조상 타입의 인스턴스를 참조하는 것은 불가능하다.

 

위에서 설명했던 다형성에 대하여 아주 간단하게 정리하자면 다음과 같다.

 

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

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

참조 변수가 사용할 수 있는 멤버의 개수는 인스턴스의 멤버 개수보다 같거나 적어야 한다.

참조 변수의 타입이 참조 변수가 참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 개수를 결정한다.


 

아마 다형성이 무엇인지는 알았지만, 이런 생각이 들것이다.

 

그래서 다형성은 도대체 왜 배우고 , 조상타입으로 자손타입의 멤버변수를 호출하는 것이 무슨 의미가 있겠냐는 것이다.

 

이러한 의구심을 풀려면 앞으로 다형성에 관해서 좀 더 다루고 난 후 뒤이을 포스팅에서 다형성을 쓰는 목적과 장점에 관해서도 다룰 예정이니 지금은 위에서 다룬 다형성의 개념을 이해하는데 중점을 두는 게 우선과제이다.