topic난이도 · 약 30

다형성(Polymorphism)

하나의 참조 타입으로 여러 구현체를 다룰 수 있는 성질. 업캐스팅 + 동적 바인딩의 조합.

#Java#객체지향#동적바인딩#실기핵심
왜 배우는가

유지보수성과 확장성의 핵심. 신규 자식 클래스가 추가돼도 기존 코드는 수정하지 않아도 되는 OCP(개방-폐쇄 원칙)를 가능하게 한다. 실기 코드 추적의 최빈출 주제.

다형성은 세 가지 메커니즘이 결합된 결과다. ① — 자식 객체를 부모 타입 변수에 담는 단계. ② — 자식이 부모 메서드를 재정의하는 단계. ③ — 실행 시점에 실제 객체의 메서드가 호출되는 단계. 이 셋이 모두 성립해야만 진짜 다형성이다.

① 업캐스팅Parent p = new Child()자식 객체를 부모 타입 변수에② 오버라이딩자식이 재정의@Override로 부모 메서드 교체③ 동적 바인딩실행 시점 결정실제 객체의 메서드가 호출세 메커니즘이 결합되어야 "다형성"이 성립한다
다형성 = 업캐스팅 + 오버라이딩 + 동적 바인딩의 합성

예를 들어 도형 계층을 생각해 보자. Shape를 부모 추상 클래스로 두고 Circle·Square·Triangle이 상속받아 각자의 방식으로 `area()`를 구현한다.

«abstract»ShapeCirclearea() = πr²Squarearea() = s²Trianglearea() = bh/2▷ 속 빈 삼각형은 UML 상속(Generalization) 기호
Shape를 추상 클래스로 하여 세 자식이 area()를 각기 다르게 구현
java
abstract class Shape {
    abstract double area();
}
class Circle extends Shape {
    double r;
    Circle(double r) { this.r = r; }
    double area() { return 3.14 * r * r; }
}
class Square extends Shape {
    double s;
    Square(double s) { this.s = s; }
    double area() { return s * s; }
}

// ★ 여기가 다형성의 힘
Shape[] shapes = { new Circle(2), new Square(3) };
double total = 0;
for (Shape sh : shapes) total += sh.area();
System.out.println(total); // 21.56

Circle과 Square를 동일한 Shape 배열에 섞어 담을 수 있고, 반복문은 어떤 자식이든 신경 쓰지 않고 area()만 호출한다. 나중에 Triangle을 추가해도 이 반복문은 한 줄도 수정할 필요 없다. 이것이 의 실체다.

핵심은 세 번째 단계인 이다. 아래 인터랙션에서 참조 변수에 담는 객체를 바꿔 보자. 같은 호출 `ref.sound()`이 실행 시점의 실제 객체에 따라 어떻게 다른 메서드로 이어지는지 직접 확인할 수 있다.

참조 변수에 담을 객체 선택:
Animal ref = new Dog();ref.sound();class Dogsound() {print("멍멍")}class Catsound() {print("야옹")}class Cowsound() {print("음메")}dispatch> 멍멍

참조 타입은 항상 Animal이지만, 실행되는 sound()는 **실제 객체의 클래스**에 따라 달라진다.

업캐스팅(자식→부모)은 자동. 다운캐스팅(부모→자식)은 명시적 + `instanceof` 검사가 안전하다.

java
Shape s = new Circle(5);     // 업캐스팅 (자동)
if (s instanceof Circle) {
    Circle c = (Circle) s;   // 다운캐스팅 (명시적)
    System.out.println(c.r);
}

주의 함정: 필드는 (선언 타입 따라), 메서드는 (실제 객체 따라). 이 차이가 실기 최상급 함정이다.

개념 딥다이브

동적 바인딩 더 깊이 파기

참조 타입과 실제 객체가 다를 때, JVM이 어떻게 실행할 메서드를 찾는지 단계별로 체험해 보자.

인터랙티브 페이지 열기
실기 드릴 2문항
code실기 드릴 · 코드 추적

다음 코드의 출력은?

java
class A {
    int x = 10;
    int getX() { return x; }
}
class B extends A {
    int x = 20;
    int getX() { return x; }
}
public class Test {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.x + "," + a.getX());
    }
}
edit실기 드릴 · 단답형

하나의 참조 변수가 여러 타입의 객체를 참조하고, 호출하는 메서드의 실체가 실행 시점에 결정되는 객체지향의 성질은?