다형성
같은 타입의 참조 변수가 실제 객체 종류에 따라 다르게 동작하는 성질입니다 (Polymorphism).
오버라이딩 vs 오버로딩
| 오버라이딩 (Overriding) | 오버로딩 (Overloading) | |
|---|---|---|
| 정의 | 부모 메서드를 자식이 재정의 | 같은 이름, 다른 파라미터로 여러 메서드 선언 |
| 결정 시점 | 런타임 (동적 바인딩) | 컴파일 타임 (정적 바인딩) |
| 조건 | 이름·파라미터·반환 타입 동일 | 파라미터 타입/개수/순서가 달라야 함 |
| 접근 제어자 | 같거나 더 넓게만 가능 | 제한 없음 |
// 오버로딩: 같은 이름, 다른 시그니처
class Printer {
void print(String s) { System.out.println(s); }
void print(int n) { System.out.println(n); }
void print(String s, int n) { System.out.println(s + n); }
}
// 오버라이딩: 부모 메서드 재정의
class Animal {
String sound() { return "..."; }
}
class Dog extends Animal {
@Override
String sound() { return "멍멍"; } // 런타임에 Dog의 메서드 호출
}
동적 바인딩 (런타임 다형성)
Animal a = new Dog(); // 업캐스팅 — Animal 타입에 Dog 인스턴스
a.sound(); // "멍멍" — 런타임에 실제 타입(Dog)의 메서드 실행
Animal[] animals = { new Dog(), new Cat(), new Bird() };
for (Animal animal : animals) {
System.out.println(animal.sound()); // 각자 다르게 동작
}
컴파일 타임:
a는 Animal 타입 → Animal의 메서드만 호출 가능 런타임: 실제 객체는 Dog → Dog의 오버라이딩된 메서드 실행
업캐스팅 / 다운캐스팅
// 업캐스팅 (자동 — 안전)
Animal a = new Dog();
// 다운캐스팅 (명시적 — 위험)
Dog d = (Dog) a; // O 실제로 Dog이므로 OK
Cat c = (Cat) a; // X ClassCastException 런타임 에러
// instanceof로 사전 확인
if (a instanceof Dog dog) { // Java 16+ 패턴 매칭
dog.fetch();
}
인터페이스 다형성
interface Drawable {
void draw();
}
class Circle implements Drawable {
public void draw() { System.out.println("원 그리기"); }
}
class Square implements Drawable {
public void draw() { System.out.println("사각형 그리기"); }
}
List<Drawable> shapes = List.of(new Circle(), new Square());
shapes.forEach(Drawable::draw); // 각자 다르게 동작
static 메서드는 다형성 적용 안 됨
class Parent {
static void hello() { System.out.println("Parent"); }
void greet() { System.out.println("Parent"); }
}
class Child extends Parent {
static void hello() { System.out.println("Child"); } // 오버라이딩 아님, 숨김(hiding)
@Override
void greet() { System.out.println("Child"); }
}
Parent p = new Child();
p.hello(); // "Parent" — 컴파일 타임 타입 기준
p.greet(); // "Child" — 런타임 타입 기준 (다형성)
핵심 정리
-
오버라이딩: 런타임 다형성의 핵심 — 부모 타입 참조로도 자식 메서드가 실행됨
-
오버로딩: 같은 이름으로 다양한 파라미터 지원 — 컴파일 타임에 결정
-
static 메서드는 오버라이딩 불가 — 참조 변수의 컴파일 타임 타입 기준으로 호출됨