메서드 재정의 Java의 런타임 메소드 바인딩 기능으로 인해 작동합니다. 따라서 Java 컴파일러가 메서드에 대해 정적 바인딩을 수행하도록 강제하면 파생 클래스에서 해당 메서드가 재정의되는 것을 방지할 수 있습니다.
Java에서 3가지 방법으로 메서드 재정의를 방지할 수 있습니다.
- 기본 클래스에서 메소드를 final로 지정
- 기본 클래스에서 메서드를 정적으로 만들기
- 기본 클래스에서 메서드를 비공개로 설정
최종 방법은 재정의할 수 없습니다.
메소드를 final로 만들면 파생 클래스가 이 특정 메소드를 재정의할 수 없다는 제한이 추가됩니다.
예
class Base { public void show() { System.out.println("Base class show() method"); } public final void test() { System.out.println("Base class test() method"); } } class Derived extends Base { public void show() { System.out.println("Derived class show() method"); } // can not override test() method because its final in Base class /* * public void test() { System.out.println("Derived class test() method"); } */ } public class Test { public static void main(String[] args) { Base ref = new Derived(); // Calling the final method test() ref.test(); // Calling the overridden method show() ref.show(); } }
출력
Base class test() method Derived class show() method
정적 메서드는 재정의할 수 없습니다.
정적 메서드는 개체가 아니라 클래스와 연결되어 있으므로 파생 클래스의 정적 메서드를 재정의할 수 없습니다. 그것은 우리가 정적 메소드를 호출할 때 JVM이 모든 비정적 메소드에 대해 하는 것처럼 이 참조를 전달하지 않는다는 것을 의미합니다. 따라서 정적 메서드에 대해 런타임 바인딩이 발생할 수 없습니다.
예
class Base { public void show() { System.out.println("Base class show() method"); } public static void test() { System.out.println("Base class test() method"); } } class Derived extends Base { public void show() { System.out.println("Derived class show() method"); } // This is not an overridden method, this will be considered as new method in Derived class public static void test() { System.out.println("Derived class test() method"); } } public class Test { public static void main(String[] args) { Base ref = new Derived(); // It will call the Base class's test() because it had static binding ref.test(); // Calling the overridden method show() ref.show(); } }
출력
Base class test() method Derived class show() method
비공개 메소드는 재정의할 수 없습니다.
기본 클래스의 전용 메서드는 파생 클래스에서 볼 수 없으므로 재정의할 수 없습니다.
예
class Base { public void show() { System.out.println("Base class show() method"); } private void test() { System.out.println("Base class test() method"); } } class Derived extends Base { public void show() { System.out.println("Derived class show() method"); } // This is not an overridden method, this will be considered as other method. public void test() { System.out.println("Derived class test() method"); } } public class Test { public static void main(String[] args) { Base ref = new Derived(); // Cannot call the private method test(), this line will give compile time error // ref.test(); // Calling the overridden method show() ref.show(); } }
출력
Derived class show() method