이 글은 자바에서 오버로딩과 재작성 사이의 차이점을 자세히 분석하기 위해 예제를 사용합니다. 관심 있는 친구들이 참고할 수 있습니다.
1. 과부하:
(1) 메소드 오버로딩은 클래스가 통일된 방식으로 다양한 유형의 데이터를 처리하는 수단입니다. 동일한 이름을 가진 여러 함수가 동시에 존재하며 매개변수의 수/유형이 다릅니다.
오버로딩은 클래스의 다형성을 나타냅니다.
(2) Java 메소드 오버로딩은 이름은 같지만 매개변수와 정의가 다른 여러 메소드를 작성할 수 있음을 의미합니다.
메소드를 호출할 때 전달된 매개변수의 수와 유형에 따라 사용할 메소드를 결정합니다. 이것이 다형성입니다.
(3) 오버로딩 시 메소드 이름은 동일해야 하지만, 매개변수의 종류와 개수가 다르고, 반환값의 종류도 같거나 다를 수 있습니다. 반환 유형은 오버로드된 함수를 구별하는 기준으로 사용될 수 없습니다.
다음은 오버로딩의 예입니다.
package c04.answer;//패키지 이름입니다//이 프로그램의 첫 번째 프로그래밍 방법입니다. 먼저 기본 메서드에서 Dog 클래스 인스턴스를 만든 다음 Dog 클래스 생성자에서 this 키워드를 사용하여 호출합니다. 다른 껍질 방법. 서로 다른 오버로드된 메소드 껍질은 매개변수 유형에 따라 구별됩니다. //참고: 컴파일러는 생성자를 제외한 다른 곳에서는 생성자를 호출하는 것을 금지합니다. package c04.answer;public class Dog {Dog(){this.bark();}void bark()//bark() 메서드는 오버로드된 메서드입니다 {System.out.println(/"no barking!/"); this.bark(/"female/", 3.4);}void짖음(문자열 m,double l)//참고: 오버로드된 메서드의 반환 값은 동일합니다. {System.out.println(/"a짖는 개!/");this.bark(5, /"China/");} voidbark(int a,String n)//오버로드된 메서드는 반환 값으로 구분할 수 없으며 "매개변수 유형"과 "클래스 이름"으로만 구분할 수 있습니다. {System.out.println(/"a Howling dog/") ; }공개 정적 무효 메인(문자열[] args){개 dog = new Dog();//dog.bark(); [페이지]//dog.bark(/"male/", /"yellow/");//dog.bark(5, / "중국/");
2. 재정의
(1) 상위 클래스와 하위 클래스 간의 다형성, 상위 클래스의 기능을 재정의합니다. 하위 클래스에 정의된 메서드가 상위 클래스와 동일한 이름과 매개변수를 갖는 경우 해당 메서드가 재정의되고 있다고 말합니다. 에서 하위 클래스는 동일한 메서드를 다시 작성할 필요 없이 상위 클래스의 메서드를 상속할 수 있습니다.
그러나 때로는 하위 클래스가 상위 클래스의 메서드를 변경 없이 상속하기를 원하지 않지만 특정 수정을 하려고 하므로 메서드를 다시 작성해야 합니다.
메서드 재정의는 메서드 덮어쓰기라고도 합니다.
(2) 하위 클래스의 메서드가 상위 클래스의 메서드와 메서드 이름, 반환 유형, 매개변수 목록이 동일한 경우 새 메서드가 원래 메서드를 덮어씁니다.
상위 클래스에 원래의 메소드가 필요한 경우 현재 클래스의 상위 클래스를 참조하는 super 키워드를 사용할 수 있습니다.
(3) 하위 클래스 함수의 액세스 수정 권한은 상위 클래스의 액세스 수정 권한보다 작을 수 없습니다.
다음은 다시 작성하는 예입니다.
개념: 객체 메서드를 호출하는 메커니즘입니다.
동적 바인딩에 대한 자세한 내용은 다음과 같습니다.
1. 컴파일러는 객체가 선언한 유형과 메소드 이름을 확인하여 모든 후보 메소드를 얻습니다. 위 예제에서 Base 클래스의 테스트를 주석 처리하려고 하면 컴파일이 통과되지 않습니다.
2. 오버로드 결정: 컴파일러는 메소드 호출의 매개변수 유형을 확인하고 위의 후보 메소드 중에서 하나만 선택합니다(이 프로세스 중에 암시적인 유형 변환이 발생합니다).
컴파일러가 둘 이상을 찾거나 아무것도 찾지 못하면 컴파일러는 오류를 보고합니다. 위 예제에서 Base 클래스의 테스트(바이트 b)를 주석 처리해 보면 실행 결과는 1 1입니다.
3. 메소드 유형이 priavte static final이고 Java가 정적 컴파일을 사용하는 경우 컴파일러는 호출할 메소드를 정확히 알 수 있습니다.
4. 프로그램이 실행되고 동적 바인딩을 사용하여 메서드를 호출할 때 가상 머신은 개체의 실제 유형과 일치하는 메서드 버전을 호출해야 합니다.
예제에서 b가 가리키는 실제 유형은 TestOverriding이므로 b.test(0)는 하위 클래스의 테스트를 호출합니다.
그러나 하위 클래스는 test(byte b)를 재정의하지 않으므로 b.test((byte)0)는 상위 클래스의 test(byte b)를 호출합니다.
상위 클래스의 (바이트 b)가 주석 처리되면 두 번째 단계에서 암시적 유형이 int로 변환되고 최종적으로 하위 클래스의 테스트(int i)가 호출됩니다.
3. 학습 요약:
다형성은 객체 지향 프로그래밍의 특징이며 메서드와는 아무런 관련이 없습니다.
간단히 말하면, 동일한 메소드가 서로 다른 입력 데이터에 따라 서로 다른 처리를 수행할 수 있습니다. 즉, 메소드 오버로딩 - 서로 다른 매개변수 목록을 사용하는 것입니다(정적 다형성).
하위 클래스가 상위 클래스에서 동일한 메서드를 상속하고 동일한 입력 데이터를 사용하지만 상위 클래스와 다르게 응답하려는 경우 상위 클래스 메서드를 재정의해야 합니다.
즉, 하위 클래스에서 이 메서드를 다시 작성합니다. - 동일한 매개변수, 다른 구현(동적 다형성)
OOP의 세 가지 주요 특징은 상속, 다형성, 캡슐화입니다.
공용 클래스 Base{void test(int i){System.out.print(i);}void test(byte b){System.out.print(b);}} 공용 클래스 TestOverriding은 Base{void test(int i)를 확장합니다. ){i++;System.out.println(i);}public static void main(String[]agrs){Base b=new TestOverriding();b.test(0)b.test((byte)0)}}
이때 출력 결과는 1 0 인데, 이는 런타임 시 동적 바인딩의 결과이다.
재정의의 주요 장점은 하위 클래스에 특정한 특성을 정의할 수 있다는 것입니다.
publicclassFather{publicvoidspeak(){System.out.println(Father);}} publicclassSonextendsFather{publicvoidspeak(){System.out.println("son");}}
이를 다형성이라고도 합니다. 재정의 메서드는 상속 관계에만 존재할 수 있습니다. 재정의 메서드는 부모 클래스의 비공개 메서드만 재정의할 수 있습니다.
위의 예에서 Father 클래스의 talk() 메서드가 private인 경우 Son 클래스는 Father 클래스의 talk() 메서드를 재정의할 수 없습니다. 이때 Son 클래스의 talk() 메서드는 다음에 정의된 talk() 메서드와 동일합니다. 아들 수업.
Father 클래스의 talk() 메서드가 최종적으로 완료되면 메서드가 public, protected 또는 default로 수정되는지 여부에 관계없이 Son 클래스는 Father 클래스의 talk() 메서드를 전혀 재정의할 수 없습니다.
코드를 컴파일하려고 하면 컴파일러에서 오류가 발생합니다. 예:
publicclassFather{finalpublicvoidspeak(){System.out.println("Father");}}publicclassSonextendsFather{publicvoidspeak(){System.out.println("son");}}//컴파일러는 오류를 보고합니다.
Father 클래스의 talk() 메서드가 기본적으로 수정되면 동일한 패키지에 있는 하위 클래스에 의해서만 재정의될 수 있습니다. 동일한 패키지에 없으면 재정의할 수 없습니다.
Father 클래스의 talk() 메서드가 프로토타입화되면 동일한 패키지의 하위 클래스에 의해 재정의될 뿐만 아니라 다른 패키지의 하위 클래스에 의해 재정의될 수도 있습니다.
메서드 재정의 규칙:
1. 매개변수 목록은 재정의된 메서드와 정확히 동일해야 합니다. 그렇지 않으면 재작성이라고 할 수 없지만 오버로드라고 할 수 있습니다.
2. 반환 유형은 항상 재정의된 메서드의 반환 유형과 동일해야 합니다. 그렇지 않으면 덮어쓰기가 아니라 오버로드라고 할 수 없습니다.
3. 액세스 수정자 제한은 재정의된 메서드의 액세스 수정자보다 커야 합니다(공개>보호>기본>비공개).
4. 재정의된 메서드는 새로운 확인된 예외나 재정의된 메서드 선언보다 더 넓은 확인된 예외를 발생시켜서는 안 됩니다. 예를 들어:
상위 클래스의 메서드는 확인된 예외 IOException을 선언합니다. 이 메서드를 재정의하는 경우 IOException의 하위 클래스에 대한 예외만 발생시킬 수 있으며 확인되지 않은 예외는 발생시킬 수 있습니다.
그리고 오버로드된 규칙은 다음과 같습니다.
1. 다른 매개변수 목록이 있어야 합니다.
2. 매개변수 목록이 다른 한, 비난하지 않는 반환 유형을 가질 수 있습니다.
3. 다양한 액세스 수정자가 있을 수 있습니다.
4. 다양한 예외가 발생할 수 있습니다.
재작성과 오버로딩의 차이점은 다음과 같습니다.
다형성을 재정의하면 오버로드된 메서드를 호출할 때 코드 입력량을 크게 줄일 수 있습니다. 동일한 메서드 이름이 다른 매개변수로 전달되는 한 다른 함수나 반환 값을 가질 수 있습니다.
재작성과 오버로딩을 잘 활용하면 명확하고 간결한 구조의 클래스를 설계할 수 있다. 코드를 작성하는 과정에서 재작성과 오버로딩이 아주 중요한 역할을 한다고 할 수 있다.