자바-재정의

이전 장에서 우리는 슈퍼 클래스와 서브 클래스에 대해 이야기했습니다. 클래스가 수퍼 클래스에서 메서드를 상속하는 경우 final로 표시되지 않은 경우 메서드를 재정의 할 수 있습니다.

재정의의 이점은 하위 클래스 유형에 특정한 동작을 정의하는 기능입니다. 즉, 하위 클래스가 요구 사항에 따라 상위 클래스 메서드를 구현할 수 있습니다.

객체 지향 용어에서 재정의는 기존 메서드의 기능을 재정의하는 것을 의미합니다.

예를 살펴 보겠습니다.

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");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

이것은 다음 결과를 생성합니다-

산출

Animals can move
Dogs can walk and run

위의 예에서는 bDog 클래스에서 move 메서드를 실행하는 Animal 유형입니다. 그 이유는 다음과 같습니다. 컴파일 타임에 참조 유형을 확인합니다. 그러나 런타임에서 JVM은 객체 유형을 파악하고 해당 특정 객체에 속하는 메소드를 실행합니다.

따라서 위의 예에서는 Animal 클래스에 move 메서드가 있으므로 프로그램이 제대로 컴파일됩니다. 그런 다음 런타임에 해당 개체에 특정한 메서드를 실행합니다.

다음 예를 고려하십시오-

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");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

이것은 다음 결과를 생성합니다-

산출

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error

이 프로그램은 b의 참조 유형 Animal에 bark라는 이름의 메서드가 없기 때문에 컴파일 시간 오류가 발생합니다.

메서드 재정의 규칙

  • 인수 목록은 재정의 된 메서드의 목록과 정확히 동일해야합니다.

  • 반환 유형은 수퍼 클래스의 원래 재정의 된 메서드에서 선언 된 반환 유형의 하위 유형이거나 동일해야합니다.

  • 액세스 수준은 재정의 된 메서드의 액세스 수준보다 더 제한적일 수 없습니다. 예 : 수퍼 클래스 메소드가 public으로 선언되면 하위 클래스의 대체 메소드는 private 또는 protected가 될 수 없습니다.

  • 인스턴스 메서드는 하위 클래스에서 상속 된 경우에만 재정의 할 수 있습니다.

  • final로 선언 된 메서드는 재정의 할 수 없습니다.

  • static으로 선언 된 메서드는 재정의 할 수 없지만 다시 선언 할 수 있습니다.

  • 메서드를 상속 할 수 없으면 재정의 할 수 없습니다.

  • 인스턴스의 수퍼 클래스와 동일한 패키지 내의 서브 클래스는 private 또는 final로 선언되지 않은 모든 수퍼 클래스 메서드를 재정의 할 수 있습니다.

  • 다른 패키지의 하위 클래스는 public 또는 protected로 선언 된 최종 메서드가 아닌 메서드 만 재정의 할 수 있습니다.

  • 재정의 메서드는 재정의 된 메서드가 예외를 throw하는지 여부에 관계없이 모든 uncheck 예외를 throw 할 수 있습니다. 그러나 재정의 메서드는 재정의 된 메서드에 의해 선언 된 것보다 새롭거나 광범위한 검사 된 예외를 throw해서는 안됩니다. 재정의 메서드는 재정의 된 메서드보다 더 좁거나 더 적은 예외를 throw 할 수 있습니다.

  • 생성자는 재정의 할 수 없습니다.

super 키워드 사용

재정의 된 메서드의 슈퍼 클래스 버전을 호출 할 때 super 키워드가 사용됩니다.

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

이것은 다음 결과를 생성합니다-

산출

Animals can move
Dogs can walk and run