Java Polymorphism
자바 다형성 (Java Polymorphism): 개념 및 사용법
- *다형성(Polymorphism)**은 객체 지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 하나의 객체가 여러 가지 형태를 가질 수 있는 특성을 의미합니다. 자바에서 다형성은 부모 클래스 참조 변수가 자식 클래스의 객체를 참조할 수 있고, 동일한 메서드 호출이 다르게 동작하도록 하는 기능을 제공합니다. 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.
이 글에서는 자바에서 다형성의 개념, 사용법, 장점 및 다양한 예제를 다룹니다.
다형성이란?
다형성은 동일한 이름의 메서드나 객체가 다른 상황에서 다르게 동작하는 성질을 말합니다. 자바에서 다형성은 두 가지 방식으로 구현됩니다:
- 컴파일타임 다형성 (Compile-time Polymorphism): 메서드 오버로딩을 통해 구현됩니다.
- 런타임 다형성 (Runtime Polymorphism): 메서드 오버라이딩과 상속을 통해 구현됩니다.
1. 컴파일타임 다형성 (Compile-time Polymorphism)
컴파일타임 다형성은 **메서드 오버로딩(Method Overloading)**을 통해 구현됩니다. 메서드 오버로딩은 같은 이름의 메서드를 여러 번 정의하되, 매개변수의 타입이나 개수를 다르게 하는 방식입니다.
메서드 오버로딩 예제
class Calculator {
// 두 정수를 더하는 메서드
public int add(int a, int b) {
return a + b;
}
// 세 정수를 더하는 메서드
public int add(int a, int b, int c) {
return a + b + c;
}
// 두 실수를 더하는 메서드
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(10, 20)); // 출력: 30
System.out.println(calc.add(10, 20, 30)); // 출력: 60
System.out.println(calc.add(10.5, 20.3)); // 출력: 30.8
}
}
결과:
30
60
30.8
위 예제에서 add()
메서드는 매개변수의 수와 타입에 따라 서로 다른 동작을 하게 됩니다. 이는 컴파일타임에 결정되므로 컴파일타임 다형성이라고 합니다.
2. 런타임 다형성 (Runtime Polymorphism)
런타임 다형성은 **메서드 오버라이딩(Method Overriding)**을 통해 구현됩니다. 메서드 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 방식으로, 객체의 타입에 따라 같은 이름의 메서드가 다르게 동작할 수 있습니다.
메서드 오버라이딩 예제
class Animal {
public void sound() {
System.out.println("Some generic animal sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // 부모 클래스의 객체
Animal myDog = new Dog(); // 자식 클래스의 객체
Animal myCat = new Cat(); // 자식 클래스의 객체
myAnimal.sound(); // 출력: Some generic animal sound
myDog.sound(); // 출력: Bark (오버라이딩된 메서드 호출)
myCat.sound(); // 출력: Meow (오버라이딩된 메서드 호출)
}
}
결과:
Some generic animal sound
Bark
Meow
위 예제에서 sound()
메서드는 부모 클래스인 Animal
에서 정의되었지만, 자식 클래스인 Dog
와 Cat
에서
재정의되었습니다. 각 객체의 타입에 따라 다르게 동작하며, 런타임 시에 어떤 메서드를 호출할지 결정되므로 런타임 다형성이라고 합니다.
자바에서의 다형성 구현
자바에서 다형성은 다음과 같은 방식으로 구현됩니다:
- 메서드 오버로딩: 하나의 클래스 내에서 동일한 메서드 이름을 가지되, 매개변수 목록이 다른 여러 메서드를 정의하는 방식입니다.
- 메서드 오버라이딩: 상속받은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 방식입니다.
- 다형적 변수 (Polymorphic Variables): 부모 클래스 타입의 참조 변수가 자식 클래스 타입의 객체를 참조할 수 있는 특성을 말합니다.
다형적 변수 (Polymorphic Variables)
자바에서 부모 클래스의 참조 변수는 자식 클래스의 객체를 참조할 수 있습니다. 이 특성을 이용하면 하나의 참조 변수가 여러 가지 형태의 객체를 참조할 수 있습니다.
다형적 변수 예제
class Animal {
public void sound() {
System.out.println("Some generic animal sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal animal; // 부모 클래스 타입의 참조 변수
animal = new Dog(); // Dog 객체 참조
animal.sound(); // 출력: Bark
animal = new Cat(); // Cat 객체 참조
animal.sound(); // 출력: Meow
}
}
결과:
Bark
Meow
위 예제에서 Animal
타입의 참조 변수 animal
이 Dog
객체와 Cat
객체를 모두 참조할 수 있습니다.
객체의 타입에 따라 sound()
메서드가 다르게 동작합니다.
다형성의 장점
1. 코드의 유연성
다형성을 사용하면 부모 클래스의 참조 변수를 통해 여러 자식 클래스를 처리할 수 있으므로 코드의 유연성이 증가합니다. 새로운 클래스를 추가해도 기존 코드를 수정할 필요 없이 확장할 수 있습니다.
2. 코드의 재사용성
부모 클래스의 메서드를 자식 클래스에서 재사용할 수 있어 코드 중복을 줄이고, 필요한 경우 메서드를 오버라이딩하여 자식 클래스에 맞게 동작을 수정할 수 있습니다.
3. 유지보수성 향상
코드를 확장하거나 수정할 때 부모 클래스만 수정하면 자식 클래스에서도 해당 변경 사항을 적용할 수 있습니다. 이를 통해 유지보수성이 향상됩니다.
다형성과 인터페이스
다형성은 인터페이스를 통해서도 구현될 수 있습니다. 인터페이스는 클래스가 구현해야 할 메서드의 틀을 제공하며, 여러 클래스에서 동일한 인터페이스를 구현하여 다양한 동작을 정의할 수 있습니다.
인터페이스를 사용한 다형성 예제
interface Animal {
void sound(); // 추상 메서드
}
class Dog implements Animal {
@Override
public void sound() {
System.out.println("Bark");
}
}
class Cat implements Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal animal; // 인터페이스 타입의 참조 변수
animal = new Dog(); // Dog 객체 참조
animal.sound(); // 출력: Bark
animal = new Cat(); // Cat 객체 참조
animal.sound(); // 출력: Meow
}
}
결과:
Bark
Meow
위 예제에서 Animal
인터페이스를 구현한 Dog
와 Cat
클래스가 각각 다른 동작을 정의하였으며, 인터페이스 타입의 참조 변수를 통해
다형성을 구현하였습니다.
요약
- *다형성(Polymorphism)**은 하나의 객체가 여러 형태를 가질 수 있는 성질로, 자바에서는 메서드 오버로딩과 메서드 오버라이딩을 통해 구현됩니다.
- 컴파일타임 다형성은 메서드 오버로딩을 통해 이루어지며, 런타임 다형성은 메서드 오버라이딩과 상속을 통해 구현됩니다.
- 다형적 변수를 통해 부모 클래스 참조 변수가 자식 클래스 객체를 참조할 수 있습니다.
- 인터페이스를 통해 다형성을 구현하면, 인터페이스 타입
의 참조 변수를 사용하여 다양한 객체를 처리할 수 있습니다.
다형성의 장점:
- 유연성: 하나의 참조 변수로 다양한 객체를 다룰 수 있음.
- 재사용성: 부모 클래스의 메서드를 재사용하면서 자식 클래스에서 오버라이딩 가능.
- 확장성: 새로운 클래스 추가 시 기존 코드의 수정 없이 확장 가능.
다형성은 자바 객체 지향 프로그래밍에서 중요한 개념으로, 코드의 확장성과 유지보수성을 높이고 재사용성을 극대화할 수 있습니다.