다형성은 하나의 객체가 여러 가지 형태를 가질 수 있는 특성
같은 메서드나 연산자가 객체의 타입에 따라 다르게 동작
컴파일 타임 다형성 (Compile-Time Polymorphism)
class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}
public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(1, 2)); // 3
System.out.println(calc.add(1.5, 2.5)); // 4.0
System.out.println(calc.add(1, 2, 3)); // 6
}
}
런타임 다형성(Run-Time Polymorphism)
class Animal {
public void sound() {
System.out.println("Some 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 animal1 = new Dog();
Animal animal2 = new Cat();
animal1.sound(); // Bark
animal2.sound(); // Meow
}
}
Upcasting : 부모 클래스의 참조 변수를 사용해 자식 클래스 객체를 참조. 공통된 부모 클래스 타입으로 여러 자식 객체를 처리 가능.
Animal animal = new Dog(); // 업캐스팅
animal.sound(); // Bark
Downcasting : 업캐스팅된 객체를 다시 자식 클래스 타입으로 변환. 반드시 instanceof로 타입 검사를 수행한 후 변환해야 함.
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 다운캐스팅
dog.sound(); // Bark
}
Dynamic Binding(동적 바인딩) - 호출될 메서드가 실행 시점에 결정. 런타임 다형성을 가능하게 하는 핵심 원리.