[Java] 다형성(Polymorphism)이란?
다형성(Polymorphism)이란?
다형성이란 프로그램 언어 각 요소들(상수, 변수, 식, 객체, 메소드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다.
또는 여러 형태를 받아들일 수 있는 성질, 상황에 따라 의미를 다르게 부여할 수 있는 특성 등으로 정의를 하기도 한다.
정리하면 다형성이란 하나의 타입에 여러 객체를 대입할 수 있는 성질로 이해하면 될 것이다.
다형성을 활용하면 기능을 확장하거나, 객체를 변경해야할 때 타입 변경 없이 객체 주입만으로 수정이 일어나게 할 수 있다. 또한 상속을 사용한다면 중복되는 코드까지 제거할 수 있으므로 더욱 객체 지향 설계와 가까워질 수 있다.
다형성을 구현하는 방법
다형성을 구현하는 여러 방법 중 대표적으로 알려져있는 오버로딩, 오버라이딩, 함수형 인터페이스에 대해 설명하고자 한다.
1. 오버로딩(Overloading)
오버로딩이란 동일한 이름의 메소드가 다른 반환 타입, 다른 매개변수의 개수나 타입을 가질 수 있는 것이다. 오버로딩에는 생성자 오버로딩, 메소드 오버로딩이 있다.
public class PrintStream {
// ...
public void println() {
this.newLine();
}
public void println(boolean x) {
synchronized(this) {
this.print(x);
this.newLine();
}
}
public void println(char x) {
synchronized(this) {
this.print(x);
this.newLine();
}
}
public void println(int x) {
synchronized(this) {
this.print(x);
this.newLine();
}
}
// ...
}
오버로딩은 여러 종류의 타입을 받아들여 결국엔 같은 기능을 하도록 만들기 위한 작업이다. 이 역시 메소드를 동적으로 호출할 수 있으니 다형성이라고 할 수 있다. 하지만 메소드를 오버로딩하는 경우 요구사항이 변경되었을 때 모든 메소드에서 수정이 수반되므로 필요한 경우에만 적절히 고려하여 사용하는 것이 좋을 듯 하다. 또한, 오버로딩이 아니라 직관적인 메소드명을 사용하여 여러개의 메소드를 만드는 것 또한 상황에 따라 적용할 수 있는 방법 중 하나다.
2. 오버라이딩(Overriding)
오버라이딩은 상위 클래스의 메서드를 하위 클래스에서 재정의하는 것을 말한다. 따라서 여기서는 상속의 개념이 추가된다.
public class Bird {
public void fly() {
System.out.println("푸드덕 푸드덕");
}
public void cry() {
System.out.println("꽥꽥");
}
}
public class Duck extents Bird {
public void swim() {
System.out.println("오리 수영한다");
}
@Override
public void fly() {
System.out.println("오리는 날 수 없다");
}
}
public class Chicken extents Bird {
@Override
public void cry() {
System.out.println("꼬끼오");
}
}
상위 클래스에 구현된 기능을 하위 클래스가 필요에 맞게 재정의하고 있다. 오버라이드 다형성을 잘 활용하면 기능의 확장과 객체의 수정에 유연한 구조를 가져갈 수 있다.
3. 함수형 인터페이스(Functional Interface)
함수형 인터페이스(Functional Interface)란, 람다식을 사용하기 위한 API로 자바에서 제공하는 인터페이스에 구현할 메소드가 하나 뿐인 인터페이스를 의미한다. 함수형 인터페이스는 enum과 함께 사용한다면 다형성의 장점을 경험할 수 있다.
정리하며
객체 지향 5원칙인 SOLID 원칙 중 개방-폐쇄 원칙(OCP; Open-Closed Principle)과 의존 역전 원칙(DIP; Dependency Inversion Principle)은 다형성을 기본으로 하고 있다. 다형성을 잘 활용하는 것이 코드의 중복을 줄이면서 변경과 확장에 유연한 객체 지향적인 코드를 작성하는데 유용하다는 것을 알 수 있다.
정리하면 다형성은 하나의 타입에 여러 객체를 대입할 수 있는 성질이고, 이것을 구현하기 위해서는 여러 객체들 중 공통 특성으로 타입을 추상화하고 그것을 상속(인터페이스라면 구현)해야한다. 이 특성들을 유기적으로 잘 활용했을 때, 비로소 객체 지향에 가까운 코드를 작성할 수 있을 것이라 생각한다.
참고
https://tecoble.techcourse.co.kr/post/2020-10-27-polymorphism/