Skip to content

Latest commit

 

History

History
133 lines (118 loc) · 6.98 KB

Override.md

File metadata and controls

133 lines (118 loc) · 6.98 KB

Override

상속 관계에 있는 클래스에서 부모 클래스의 메서드를 재정의 하는 것입니다. 오버라이딩은 다형성을 실현하는 데 핵심적인 역할을 하며, 동적 디스패치를 가능하게 합니다.

기본 개념

  1. 정의
  • 메서드 오버라이딩은 서브클래스에서 부모 클래스의 메서드를 재저으이하는 것을 의미합니다.
  • 오버라이딩된 메서드는 부모 클래스와 동등한 이름, 반환 타입, 매개변수를 가져야 합니다.
  1. 목적
  • 부모 클래스의 기본 동작을 서브클래스에 맞게 변경할 수 있습니다.
  • 다형성을 실현하여, 동일한 인터페이스로 다양한동작을 수행할 수 있습니다.

오버라이딩의 규칙

  1. 메서드 시그니처
  • 오버라이딩되는 메서드는 부모 클래스의 메서드와 동일한 이름, 반환 타입, 매개변수를 가져야합니다.
  1. 접근 제어자
  • 오버라이딩 메서드는 부모 클래스의 메서드보다 더 좁은 접근 제어자를 가질 수 없습니다. 예를 들어, 부모 클래스의 메서드가 'protected'라면 오버라이딩 메서드는 'protected'나 'public'이어야 합니다.
  1. 예외
  • 오버라이딩 메서드는 부모 클래스의 메서드가 던질 수 있는 예외보다 더 넓은 범위의 예외를 던질 수 없습니다. 즉, 더 적은 수의 예외를 던지거나, 같은 예외를 던질 수 있습니다.
  1. @Override 애너테이션
  • @Override 애너테이션을 사용하여 메서드가 부모 클래스의 메서드를 오버라이드하고 있음을 명시할 수 있습니다. 이는 컴파일러가 올바르게 오버라이딩되고 있는지 확인하는 데 도움이 됩니다.
  • 이 애너테이션은 메서드가 부모 클래스나 인터페이스의 메서드를 오버라이드하고 있음을 컴파일러에 알리는 역할을 합니다. 이를 통해 오버라이드 의도와 실제 오버라이딩이 일치하는지 검증할 수 있습니다.
    • 컴파일 타임 검증
      • 컴파일러가 메서드가 실제로 무코 클래스 또는 인터페이스의 메서드를 올바르게 오버라이드하고 있는지 확인하도록 합니다.
      • 만약 오버라이드하려는 메서드가 부모 클래스나 인터페이스에 존재하지 않거나, 시그니처가 일치하지 않는다면 컴파일 오류가 발생합니다.
    • 오버라이드 의도 명시
      • 코드를 읽는 다른 개발자에게 이 메서드가 부모클래스나 인터페이스의 메서드를 오버라이드하고 있음을 명확히 알릴 수 있습니다.
class Animal {
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {

    @java.lang.Override
    public void sound() {
        System.out.println("Woof");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound(); // Woof
    }
}

동적 디스패치

  1. 정적 바인딩
  • 컴파일 타임에 어떤 메서드가 호출될지 결정하는 방식입니다. 예를 들어, 메서드 오버로딩은 정적 바인딩입니다.
  1. 동적 디스패치
  • 런타임에 어떤 메서드가 호출될지 결정하는 방식입니다. 메서드 오버라이딩은 동적 디스패치에 의해 작동합니다.
  • 객체의 실제 타입에 따라 메서드 호출이 결정됩니다.

vtable과 오버라이딩

자바에서 동적 디스패치는 vtable을 통해 구현됩니다.

  1. vtable
  • 각 클래스는 자신의 가상 메서드 테이블을 가집니다. 이 테이블은 메서드의 주소를 포함한 배열입니다.
  • 상위 클래스의 메서드를 오버라이딩하면, 서브클래스의 vtable에 해당 메서드의 주소가 갱신됩니다.
  1. 메서드 호출 과정
  • 객체의 실제 타입을 확인하여 vtable을 참조합니다.
  • 호출할 메서드의 주소를 vtable에서 찾아 실행합니다.

오버라이딩의 내부 동작

  1. 컴파일 타임
  • @Override 애너테이션을 통해 컴파일러가 메서드 시그니처를 확인하고, 올바르게 오버라이딩되었는지 검증합니다.
  • 각 클래스의 vtable을 생성합니다.
  1. 런타임
  • 객체가 생성될 때, 해당 객체는 자신의 클래스에 대응하는 vtable을 참조합니다.
  • 메서드 호출 시, 객체의 실제 타입에 따라 vtable을 통해 메서드 주소를 찾아 호출합니다.

오버라이딩의 장점

  1. 다형성
  • 동일한 인터페이스로 다양한 객체를 처리할 수 있습니다.
  • 코드의 유연성과 재사용성을 높입니다.
  1. 유지보수
  • 부모 클래스의 기본 동작을 변경하지 않고 서브클래스에서 동작을 변경할 수 있습니다.
  • 코드 변경 시 서브클래스의 영향 범위를 최소화할 수 있습니다.
  1. 확장성
  • 새로운 서브클래스를 추가하여 기능을 확장할 수 있습니다.
  • 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있습니다.

오버라이딩의 한계

  1. 성능
  • 동적 디스패치로 인한 약간의 성능 오버헤드가 발생할 수 있습니다.
  • 그러나 이는 대부분의 경우 무시할 수 있을 정도로 작습니다.
  1. 복잡성
  • 상속 계층이 깊어지면, 메서드 호출의 추적이 어려워질 수 있습니다.
  • 코드의 복잡성이 증가할 수 있습니다.

Covariant 반환 타입

자바에서는 오버라이딩 시 반환 타입이 부모 클래스 메서드의 반환 타입과 다를 수 있습니다. 이를 공변 반환 타입(Covariant Return Type)이라 합니다.
서브클래스에서 오버라이딩하는 메서드의 반환 타입을 부모 클래스의 메서드 반환 타입의 서브타입으로 변경할 수 있는 기능입니다.

class Animal {
    public Animal get() {
        return this;
    }
}

class Dog {
    
    @Override
    public Dog get() { //Animal의 서브 타입인 Dog 반환 가능
        return this;
    }
}

원리

  1. 상속 관계 유지
  • 부모 클래스의 메서드 반환 타입이 Animal일 때, 서브 클래스의 오버라이딩 메서드 반환 타입은 Animal의 서브클래스(Dog)가 될 수 있습니다.
  1. 컴파일 타임 체크
  • 컴파일러는 오버라이딩 메서드의 반환 타입이 부모 클래스 메서드 반환 타입의 서브타입인지 확인합니다. 서브타입이 아니면 컴파일 오류가 발생합니다.

공변 반환 타입의 유용성

  1. 타입 안정성
  • 반환 타입이 더 구체적이므로, 클라이언트 코드에서 형변환 없이 안전하게 사용할 수 있습니다.
  1. 코드 가독성
  • 반환 타입이 명확하여 코드의 가독성이 향상됩니다.
  1. 유연한 설계
  • 클래스 계층 구조에서 유연하고 재사용 가능한 메서드를 작성할 수 있습니다.

한계

공변 반환 타입은 타입만 변경할 수 있으며 매개변수 타입은 변경할 수 없습니다. 매개변수 타입을 변경하려면 메서드 오버로딩을 사용해야 합니다.