자바 - 재정의
이전 장에서 우리는 슈퍼클래스와 서브클래스에 대해 이야기했습니다. 클래스가 상위 클래스에서 메서드를 상속하는 경우 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
위의 예에서 b Dog 클래스에서 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에 껍질이라는 이름의 메서드가 없기 때문에 컴파일 시간 오류가 발생합니다.
메서드 재정의 규칙
-
인수 목록은 재정의된 메서드의 인수 목록과 정확히 동일해야 합니다.
-
반환 유형은 수퍼 클래스의 원래 재정의된 메서드에서 선언된 반환 유형과 같거나 하위 유형이어야 합니다.
-
액세스 수준은 재정의된 메서드의 액세스 수준보다 더 제한적일 수 없습니다. 예:슈퍼클래스 메소드가 public으로 선언된 경우 하위 클래스에서 재정의하는 메소드는 private이거나 protected일 수 없습니다.
-
인스턴스 메소드는 서브클래스에 상속된 경우에만 재정의할 수 있습니다.
-
final로 선언된 메소드는 재정의할 수 없습니다.
-
static으로 선언된 메서드는 재정의할 수 없지만 다시 선언할 수 있습니다.
-
메서드를 상속할 수 없으면 재정의할 수 없습니다.
-
인스턴스의 슈퍼클래스와 동일한 패키지 내의 서브클래스는 private 또는 final로 선언되지 않은 슈퍼클래스 메서드를 재정의할 수 있습니다.
-
다른 패키지의 하위 클래스는 public 또는 protected로 선언된 비최종 메서드만 재정의할 수 있습니다.
-
재정의 메서드는 재정의된 메서드가 예외를 throw하는지 여부에 관계없이 확인되지 않은 예외를 throw할 수 있습니다. 그러나 재정의하는 메서드는 재정의된 메서드에 의해 선언된 것보다 새롭거나 더 광범위한 확인된 예외를 throw해서는 안 됩니다. 재정의 메서드는 재정의된 메서드보다 더 좁거나 더 적은 예외를 throw할 수 있습니다.
-
생성자는 재정의할 수 없습니다.
슈퍼 키워드 사용
재정의된 메소드의 수퍼클래스 버전을 호출할 때 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