다형성이란 프로그래밍 언어가 갖고 있는 자료형 체계의 성질을 설명하는 단어로, 프로그램 언어 각 요소(상수, 변수, 오브젝트, 메소드 등)이 다양한 자료형에 속하는 것이 허용되는 성질을 의미한다.
즉, 다형성이란 프로그램 언어의 각 요소가 '여러 가지 형태를 가질 수 있는 능력'이라고 이해할 수 있다.
객체지향의 사실과 오해(일명 토끼책)에 따르면 다형성이란 서로 다른 유형의 객체가 동일한 메시지를 수신할 때 서로 다른 메서드를 이용해 메시지를 처리하는 것이다. 이런 관점에서 이해한다면 다형성은 하나의 메시지와 하나 이상의 메서드 사이의 관계이며, 하나의 객체는 동일한 역할을 수행할 수 있는 다른 객체로 대체할 수 있다는 것을 의미한다.
다형성의 장점은 객체들의 대체 가능성으로 인해 설계가 유연하고 재사용이 가능하다는 것이다. 다형성이 보장될 경우, 송신자가 수신자의 종류를 모르더라도 메시지를 전송하는 것이 가능하며, 송신자에게 어떠한 영향 없이 수신자를 교체, 추가하는 것이 가능하다. 따라서 책임을 완수할 수 있는 새로운 유형의 객체를 정의함으로써 객체들의 협력의 범위를 넓힐 수 있다.
- 다형성은 송신자와 수신자 간의 객체 타입에 대한 결합도를 메시지에 대한 결합도로 낮춤으로써 달성된다.
- 상위 클래스 타입의 객체 참조 변수에서 하위 클래스가 오버라이딩한 메서드를 자동으로 호출해주기 때문에 코드를 깔끔하게 유지할 수 있다.
Java에서는 한 타입의 참조 변수로 여러 타입의 객체를 참조하는 것을 허가하여 다형성을 구현하였다.
public class Tv {
boolean power;
int channel;
void power() {
power = !power;
}
void channelUp() {
++channel;
}
void channelDown() {
--channel;
}
}
class SmartTv extends Tv {
boolean caption;
void displayCaption(String text) {
if (caption) {
System.out.println(text);
}
}
}
예를 들어 위와 같이 Tv와 Tv 클래스를 상속하는 SmartTv 클래스가 있다고 하자.
인스턴스의 자료형과 참조변수의 자료형을 통일시킨다면 Tv t = new Tv();
혹은 SmartTv s = new SmartTv();
로 인스턴스를 생성할 수 있다.
그런데 java에서는 다형성이 구현되어있기 때문에 조상 타입의 참조변수로 자손 타입의 인스턴스를 참조하는 것이 가능하다. (반대는 안 된다.)
SmartTv s = new SmartTv();
Tv t = new SmartTV();
단, 한 가지 주의해야 할 사항이 있다.
SmartTV 인스턴스의 참조변수 타입을 Tv로 지정하면, SmartTv(생성되는 인스턴스)가 갖고있는 멤버를 모두 사용할 수 있는 것이 아닌 Tv(참조변수)에 정의되어 있는 멤버만 사용할 수 있다는 것이다. 따라서 위와 같이 인스턴스를 생성한다면 SmartTv에만 있는 caption과 displayCaption을 t.caption
또는 t.displayCaption
과 같은 형태로 사용할 수 없다.
멤버의 사용 범위와 비슷하게, 상위 클래스 타입의 객체 참조 변수를 사용하더라도 하위 클래스에서 overriding한 메서드가 호출된다.
class Parent {
void parentMethod() {
System.out.println("I love 🍍");
}
}
class Child extends Parent {
// overriding (재정의: 상위 클래스의 메서드와 같은 메서드 이름, 같은 인자 리스트)
void parentMethod() {
System.out.println("I love 🍇");
}
// overloading (중복정의: 같은 메서드 이름, 다른 인자 리스트)
void parentMethod(int i) {
System.out.println("I love 🍎");
}
}
Parent p = new Child();
와 같이 부모 클래스 타입의 참조변수로 Child 클래스의 인스턴스를 참조한다음 p.parentMethod();
를 실행하면 I love 🍇
가 출력되는 것을 확인할 수 있다.
void buy(Product p) {
money = -= p.price;
bonusPoint += p.bonusPoint;
}
Source
아직은 잘모르는 개념이지만 나중에 도움이 될 것 같아서 정독 했습니다!
필요한 개념이 되면 다시 찾아올게요!