Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바 다중 레벨 상속에서의 런타임 다형성, 메서드 오버라이딩 완벽 이해

런타임 다형성과 메서드 오버라이딩

메서드 오버라이딩(Method Overriding)은 자바에서 런타임 다형성(Runtime Polymorphism)을 구현하는 대표적인 방법입니다. 서브클래스가 슈퍼클래스에 정의된 메서드와 동일한 시그니처(메서드 이름, 매개변수 목록)를 가진 메서드를 재정의하는 것을 의미합니다.

여기서 중요한 점은 컴파일 시점과 실행 시점의 동작 차이입니다.

  • 컴파일 타임: 참조 변수의 타입을 기준으로 메서드 호출이 유효한지 검사합니다.
  • 런타임: JVM이 실제 객체의 타입을 확인하고, 해당 객체에 속한 메서드를 실행합니다.

다중 레벨 상속에서의 오버라이딩

자바에서는 다중 레벨 상속(Multilevel Inheritance) 구조의 어느 단계에서든 메서드를 오버라이딩할 수 있습니다. 즉, 조상 클래스부터 최하위 자손 클래스까지 각 단계마다 같은 메서드를 재정의할 수 있으며, 실제로 실행되는 메서드는 참조 변수가 아닌 객체의 실제 타입에 따라 결정됩니다.

예제 코드

class Animal {
    public void move() {
        System.out.println("Animals can move");
    }
}
class Dog extends Animal {
    public void move() {
        System.out.println("Dogs can walk and run");
    }
}
class Puppy extends Dog {
    public void move() {
        System.out.println("Puppy can move.");
    }
}
public class Tester {
    public static void main(String args[]) {
        Animal a = new Animal(); // Animal 참조 변수 + Animal 객체
        Animal b = new Puppy();  // Animal 참조 변수 + Puppy 객체
        a.move(); // Animal 클래스의 메서드 실행
        b.move(); // Puppy 클래스의 메서드 실행
    }
}

실행 결과

Animals can move
Puppy can move.

코드 분석

위 예제는 세 단계의 상속 구조(Animal → Dog → Puppy)를 보여줍니다. 핵심 내용은 다음과 같습니다.

  1. Animal a = new Animal(); — 참조 변수와 객체 모두 Animal 타입이므로, a.move() 호출 시 Animal 클래스의 move() 메서드가 실행됩니다.
  2. Animal b = new Puppy(); — 참조 변수는 Animal 타입이지만 실제 객체는 Puppy입니다. 컴파일러는 참조 타입인 Animal에 move() 메서드가 존재하는지만 확인하고, 런타임에는 JVM이 객체의 실제 타입(Puppy)을 파악하여 Puppy 클래스에서 오버라이딩된 move() 메서드를 실행합니다.

이처럼 참조 변수의 타입이 아니라 객체의 실제 타입이 어떤 메서드가 실행될지 결정하기 때문에, 이를 동적 바인딩(Dynamic Binding) 또는 런타임 다형성이라고 부릅니다. 이 특성을 활용하면 하나의 인터페이스로 여러 형태의 객체를 유연하게 처리할 수 있어 코드의 확장성과 유지보수성이 크게 향상됩니다.