다형성
다형성 (polymorphism)
- 여러 가지 형태를 가질 수 있는 능력
- 조상 타입 참조 변수로 자손 타입 객체를 다루는 것
다형성이란, 여러 가지 형태를 가질 수 있는 능력을 의미한다. 이것은,사전적 의미이고,
다형성이란, "조상 타입 참조 변수로 자손 타입 객체를 다루는 것" 이다.
이것이 무슨 말이냐면, 아래 예시를 보자.
Tv클래스가 있다.
그리고, Tv클래스를 부모로 하는 자식 SmartTv클래스가 있다.
Tv클래스는 멤버가 5개이다. SmartTv에는 멤버가 2개 추가되어서, 상속받은 것까지 모두 포함하면 총 7개이다.
지금까지는, Tv객체를 다룰 때에는, Tv타입의 참조변수를 이용했다.
SmartTv객체를 다룰 때는, SmartTv타입의 참조변수를 이용했다.
즉, 다루고자 하는 객체의 타입과 참조변수의 타입이 일치했다.
그런데, 다형성이라는 것은
다루고자 하는 객체의 타입과 참조변수의 타입이 불일치한데, OK다. (조상 자손인 관계만!!)
이렇게, SmartTv객체를 Tv타입의 참조변수로 다룰 수 있다.
이것이 다형성이다.
일반적으로는 다루고자 하는 객체의 타입과 참조변수의 타입이 일치하는데,
불일치하게되면(다형성) 어떤 장점이 있을까?
2가지 장점이 존재한다. 이 장점 때문에 다형성이 중요하고, 다형성이 객체지향개념에 굉장한 유연함을 준다.
다형성의 장점에 대해서 알아보기 전에,
- 객체와 참조변수의 타입이 일치할 떄와 일치하지 않을 때의 차이?
에 대해서 알아보자.
원래는 참조변수 타입과 객체타입이 일치했었다.
그런데, Tv클래스가 SmartTv클래스의 조상일 때는 위의 예시처럼 참조변수 타입과 객체의 타입이 불일치해도 OK이다.
그러면, 차이가 있을텐데, 차이가 뭘까?
첫번째 문장에 대한 그림이다. 실제 객체가 무엇인지가 중요한데,
객체는 SmartTv인스턴스이다.
SmartTv를 SmartTv타입의 참조변수 s로 다룬다.
이때, SmartTv클래스의 멤버는 7개이다. 즉, 리모컨의 버튼이 7개이다. (5개는 부모 Tv것, 2개는 자기자신 것)
즉,SmartTv타입의 참조변수 s도 버튼이 7개 있는 것이고,
실제 SmartTv객체의 멤버도 7개이다.
따라서 SmartTv리모컨으로는 실제 SmartTv의 멤버7개를 모두 사용할 수 있다.
리모컨의 버튼도 7개, SmartTv의 기능도 7개. 즉, 모든 기능을 사용할 수 있다.
그런데, 두번째의 경우,
리모컨이 Tv리모컨이다. (참조변수가 Tv타입이므로..)
그런데, 제품은 SmartTv이다. 가지고 있는 멤버가 7개이다.
근데, Tv리모컨에는 버튼이 5개밖에 없다.(Tv클래스에 정의된 5개의 멤버에 대한 버튼)
그러면, 실제로 SmartTv가 7개의 멤버를 가지고 있어도, Tv리모컨을 이용해서 실제로 사용할 수 있는 멤버는 5개 뿐이다.
즉, 실제 객체가 가진 기능 중 일부만 사용가능하다.
"일부만 사용할 수 있는 것 같은데, 이게 왜 다형성의 장점이죠?"
라고 질문 할 수도 있겠지만,
일부만 사용할 수 있는점이, 장점이 되기도 한다.
조상타입의 참조변수로 자손의 객체를 사용하면 자손멤버가 아무리 많아도, 조상타입이 가진 멤버의 기능만 사용할 수 있다.
이번에는, 반대의 경우에 대한 내용이다.
- 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수는 없다.
첫번째 문장은 앞서 보앗던 다형성 예시처럼, 조상타입의 참조변수로 자손객체를 다루는 것이므로 OK이다.
반면에, 두번째 문장은 자손타입의 참조변수로 조상타입의 객체를 다루려는 것인데, 이것은 허용하지 않아서 에러가난다.
두번째 경우는, 왜 허용하지 않는지 알아보자.
우선, 첫번째 경우, 리모컨에 버튼이 5개만 있고, 객체에 멤버가 7개 있다. 따라서 객체의 멤버 7개중에 5개만 사용이 가능하다.
즉, 기능이 7개인데 5개(일부)만 사용하는 것은 OK이다. (다형성)
그런데 반대로, 리모컨의 버튼은 7개이고, 실제 객체가 가진 멤버는 5개라면,
리모컨이 사용할 수 있는 멤버가 더 많은 경우인데,
만약에 리모컨에서 실제 객체에 없는 기능을 누른다면, 없는 것을 호출해서 에러가 발생 한다.
그래서 자손타입의 참조변수로 조상 타입의 객체를 가리키는 것을 허용하지 않는다.
다형성 간단 정리
Q. 참조변수의 타입은 인스턴스의 타입과 반드시 일치해야 하나요?
A. 아니다. 일치하는 것이 보통이지만 일치하지 않을 수도 있다.
Q. 참조변수가 조상타입일 때와 자손타입일 때의 차이?
A. 참조변수로 사용할 수 있는 멤버의 갯수가 달라진다.
Q. 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 있나요?
A. 아니다. 허용하지 않는다.
'JAVA' 카테고리의 다른 글
instanceof 연산자 (0) | 2022.04.03 |
---|---|
참조변수의 형변환 (0) | 2022.04.03 |
캡슐화 (0) | 2022.04.01 |
접근 제어자 (0) | 2022.04.01 |
제어자, static, final, abstract (0) | 2022.04.01 |