다형성이란?
- 다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다.
- 자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있습니다.
- 다형성은 상속, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.
- 다시말해서 다형성이란, 하나의 객체 혹은 메소드가 여러 타입을 참조할 수 있음을 의미합니다.
- 다형성은 크게 객체의 다형성과, 메소드의 다형성으로 구분됩니다.
객체 다형성
- 객체 다형성은 객체가 상속된 부모 객체의 인스턴스로 할당될 수 있음을 의미합니다.
class TV
{
// 메소드
}
class SmartTV extends TV
{
// 메소드
}
- 위와 같이 SmartTV 가 TV를 상속받고있다.
public class Main {
public static void main(String[] args)
{
// 객체와 인스턴스 타입 일치
TV tv = new TV();
// 객체와 인스턴스 타입 일치
SmartTV smart = new SmartTV();
// SmartTV는 TV의 자식 객체이므로 다형성이 적용되어 허용
TV tv2 = new SmartTV();
// 불가능
SmartTV smart2 = new TV();
}
}
- TV와 SmartTV는 엄연히 다른 객체임에도 불구하고 인스턴스가 정상적으로 생성되는 것을 볼 수 있다.
- 이러한 객체의 다형성은 객체를 상속했을 때 뿐만 아니라, 인터페이스를 상속할때도 가능하다.
interface Movable
{
void move(boolean direction);
}
class Unit implements Movable
{
@Override
public void move(boolean direction)
{
// 동작
}
public void work(String act)
{
// 동작
}
}
- 위와 같이 Unit 객체가 인터페이스 Movable 를 상속 받았다.
public class Main
{
public static void main(String[] args)
{
Movable movable = new Unit();
// Movable에 존재하는 메소드이므로 호출 가능
movable.move(true);
// Movable엔 없는 Unit만의 고유 메소드이므로 호출 불가능
movable.work("run");
}
}
- Unit 객체를 Movable로 생성할 수 있다.
- 위와 같이 객체의 다형성을 사용하면 동일한 객체를 상속받은 여러 객체를 다루기도 매우 편리하다.
class UnitA implements Movable
{
@Override
public void move(boolean direction)
{
work("run");
}
private void work(String act)
{
System.out.println("work: " + act);
}
}
class UnitB implements Movable
{
@Override
public void move(boolean direction)
{
doing(3);
}
private void doing(int num)
{
System.out.println("doing: " + num);
}
}
class UnitC implements Movable
{
@Override
public void move(boolean direction)
{
active(true);
}
private void active(boolean flag)
{
System.out.println("active: " + flag);
}
}
public class Main
{
public static void main(String[] args)
{
Movable movable = switch (new Random().nextInt(3))
{
case 0 -> new UnitA();
case 1 -> new UnitB();
case 2 -> new UnitC();
default -> null;
};
movable.move(true);
}
}
- 위와 같이 동일한 인터페이스 Movable 를 상속받은 여러 객체가 있다면, 이 객체들은 각각 개별적인 객체지만, Movable 를 상속받고 있기 때문에, 세 객체 모두 다형성을 통해서 Movable 인스턴스로 할당할 수 있다.
메소드 다형성
- 메소드가 서로 동일한 이름을 가지더라도, 입력받는 파라미터가 다르면 각각 개별적인 메소드로 취급함을 의미한다.
- 예시는 아래와 같다.
/**
* 컨버터 클래스
*/
public class Converter
{
/**
* 변환 함수
*
* @param num: [int] 숫자
*/
public void convert(int num)
{
System.out.println(new StringBuilder().append("int: ").append(num));
}
/**
* 변환 함수
*
* @param text: [String] 문자열
*/
public void convert(String text)
{
System.out.println(new StringBuilder().append("String: ").append(text));
}
/**
* 변환 함수
*
* @param flag: [boolean] T/F
*/
public void convert(boolean flag)
{
System.out.println(new StringBuilder().append("boolean: ").append(flag));
}
/**
* 변환 함수
*
* @param c: [char] 문자
*/
public void convert(char c)
{
System.out.println(new StringBuilder().append("char: ").append(c));
}
}
- 위와같이 매개변수가 다르면 다형성이 인정된다.
- 하지만 반환값의 경우 다형성이 적둉되지 않는다. -> 나머지는 모두 같고 반환값만 다르면 다형성이 적용되지 않는다.
정리
- 객체의 다형성은 생산성에 초점이 맞춰져있다.
- 동일한 메소드로 여러 타입의 데이터를 처리하거나, 공통 상속된 객체를 처리함으로써 중복된 코드 요소를 제거하고 개발 편의성을 높여준다.
REFERENCES