Java 재정의/오버로드
Override
Override는 액세스를 허용하는 상위 클래스 메서드의 구현 프로세스를 하위 클래스에서 다시 작성하는 것입니다! 반환 값이나 형식 매개변수는 변경할 수 없습니다. 즉, 쉘은 변경되지 않고 코어는 다시 작성됩니다!
재정의의 장점은 하위 클래스가 필요에 따라 자체 동작을 정의할 수 있다는 것입니다.
즉, 하위 클래스는 필요에 따라 상위 클래스의 메서드를 구현할 수 있습니다.
객체 지향 원칙에서 재정의는 기존 메서드를 재정의할 수 있음을 의미합니다.
class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ System.out.println("狗可以跑和走"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 } }
위 예제의 컴파일 및 실행 결과는 다음과 같습니다.
动物可以移动 狗可以跑和走
위 예제에서 볼 수 있듯이 b는 Animal 타입에 속하지만 Dog의 move 메소드를 실행합니다. 수업.
컴파일 단계에서는 매개변수의 참조 유형만 확인하기 때문입니다.
그러나 런타임 시 JVM(Java Virtual Machine)은 개체 유형을 지정하고 개체의 메서드를 실행합니다.
그래서 위의 예에서 컴파일이 성공한 이유는 Animal 클래스에 move 메소드가 존재하기 때문입니다. 그러나 런타임에는 특정 객체의 메소드가 실행됩니다.
다음 예를 생각해 보세요.
class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ System.out.println("狗可以跑和走"); } public void bark(){ System.out.println("狗可以吠叫"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal 对象 Animal b = new Dog(); // Dog 对象 a.move();// 执行 Animal 类的方法 b.move();//执行 Dog 类的方法 b.bark(); } }
위 예의 컴파일 및 실행 결과는 다음과 같습니다.
TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); ^
이 프로그램은 참조 유형인 Animal에 bark 메서드가 없기 때문에 컴파일 오류가 발생합니다.
메서드 규칙 재작성
매개변수 목록은 재정의된 메서드의 목록과 정확히 동일해야 합니다. 반환 유형은 재정의된 메서드의 반환 유형과 정확히 동일해야 합니다. 액세스 권한은 상위 클래스에서 재정의된 메서드의 액세스 권한보다 낮을 수 없습니다. 예: 상위 클래스의 메서드가 public으로 선언된 경우 하위 클래스에서 해당 메서드를 재정의할 때 해당 메서드를 protected로 선언할 수 없습니다.
상위 클래스의 멤버 메서드는 해당 하위 클래스에 의해서만 재정의될 수 있습니다.
final로 선언된 메서드는 재정의될 수 없습니다.
static으로 선언된 메서드는 재정의할 수 없지만 다시 선언할 수 있습니다.
하위 클래스와 상위 클래스가 동일한 패키지에 있는 경우 하위 클래스는 private 및 final로 선언된 메서드를 제외하고 상위 클래스의 모든 메서드를 재정의할 수 있습니다.
하위 클래스와 상위 클래스가 동일한 패키지에 없는 경우 하위 클래스는 공개 및 보호로 선언된 상위 클래스의 최종이 아닌 메서드만 재정의할 수 있습니다.
재정의된 메서드는 재정의된 메서드가 예외를 발생시키는지 여부에 관계없이 강제로 적용되지 않은 모든 예외를 발생시킬 수 있습니다. 그러나 재정의된 메서드는 새로운 필수 예외 또는 재정의된 메서드에 의해 선언된 것보다 더 광범위한 필수 예외를 발생시킬 수 없으며 그 반대의 경우도 마찬가지입니다.
생성자는 재정의될 수 없습니다.
메서드를 상속받을 수 없으면 이 메서드를 재정의할 수 없습니다.
Super 키워드 사용
하위 클래스에서 상위 클래스의 재정의된 메서드를 호출해야 하는 경우 super 키워드를 사용하세요.
class Animal{ public void move(){ System.out.println("动物可以移动"); } } class Dog extends Animal{ public void move(){ super.move(); // 应用super类的方法 System.out.println("狗可以跑和走"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Dog 对象 b.move(); //执行 Dog类的方法 } }
위 예제의 컴파일 및 실행 결과는 다음과 같습니다.
动物可以移动 狗可以跑和走
Overload(오버로드)
Overloading(오버로딩)은 클래스에 있고 메서드 이름은 동일하지만 매개 변수가 다릅니다. 반환 유형은 동일하거나 다를 수 있습니다.
오버로드된 각 메서드(또는 생성자)에는 고유한 매개 변수 유형 목록이 있어야 합니다.
생성자만 오버로드될 수 있습니다
오버로드 규칙
오버로드된 메서드는 매개변수 목록을 변경해야 합니다.
오버로드된 메서드는 반환 유형을 변경할 수 있습니다.
오버로드된 메서드 액세스 한정자는 변경될 수 있습니다.
오버로드된 메서드는 새롭거나 더 넓은 범위의 확인된 예외를 선언할 수 있습니다.
메서드는 동일한 클래스 또는 하위 클래스에서 오버로드될 수 있습니다.
Instance
public class Overloading { public int test(){ System.out.println("test1"); return 1; } public void test(int a){ System.out.println("test2"); } //以下两个参数类型顺序不同 public String test(int a,String s){ System.out.println("test3"); return "returntest3"; } public String test(String s,int a){ System.out.println("test4"); return "returntest4"; } public static void main(String[] args){ Overloading o = new Overloading(); System.out.println(o.test()); o.test(1); System.out.println(o.test(1,"test3")); System.out.println(o.test("test4",1)); } }
덮어쓰기와 오버로드의 차이
차이점 | 오버로딩 방식 | 오버라이딩 방식 |
---|---|---|
매개변수 목록 | 수정 필수 | 수정 불가 |
반환 유형 | 수정 가능 | 수정 불가 |
예외 | 수정 가능 | 축소 또는 삭제 가능, 새롭거나 더 광범위한 예외가 발생해서는 안 됩니다 |
access | 수정 가능 | 더 엄격한 제한을 해서는 안 됩니다(제한이 낮아질 수 있음) |