안녕! 이미 Java 메서드를 사용하고 있으며 이에 대해 많이 알고 있습니다. 메서드 재정의 작동 방식 - 1이름은 같지만 인수 목록이 다른 여러 메서드가 있는 클래스를 본 적이 있을 것입니다. 그런 경우에 메서드 오버로딩을 사용했다는 것을 기억할 것입니다. 오늘은 다른 상황을 살펴보겠습니다. 하나의 공통 메서드가 있지만 호출되는 클래스에 따라 다른 작업을 수행해야 한다고 상상해 보십시오. 이 동작을 어떻게 구현합니까? 이를 이해하기 위해 Animal동물을 나타내는 부모 클래스를 가져오고 speak그 안에 메서드를 만들어 봅시다.
public class Animal {

   public void speak() {

       System.out.println("Hello!");
   }
}
이제 막 프로그램을 작성하기 시작했지만 아마도 잠재적인 문제를 볼 수 있을 것입니다. 세상은 많은 동물로 가득 차 있고 모두 다르게 "말합니다": 고양이 야옹, 오리 꽥꽥, 뱀 쉿쉿 소리 등. 우리의 목표는 간단합니다 메서드 재정의 작동 방식 - 2. 말하는 방법을 많이 만들지 않으려고 합니다. meow()야옹, 쉭쉭거리는 등의 메소드를 만드는 대신 메소드가 호출될 hiss()때 뱀이 쉭쉭대고 고양이가 야옹하고 개가 짖기를 원합니다 . 메서드 재정의speak() 를 사용하여 쉽게 달성할 수 있습니다 . Wikipedia에서는 이 용어를 다음과 같이 설명합니다. 메서드 재정의는 객체 지향 프로그래밍에서 하위 클래스 또는 하위 클래스가 상위 클래스 또는 상위 클래스 중 하나에서 이미 제공한 메서드의 특정 구현을 제공할 수 있도록 하는 언어 기능입니다. 기본적으로 맞습니다. 재정의를 사용하면 부모 클래스의 일부 메서드를 가져와 각 파생 클래스에서 고유한 구현을 작성할 수 있습니다. 하위 클래스의 새 구현은 상위 클래스의 구현을 "대체"합니다. 예를 들어 어떻게 보이는지 봅시다. 우리 클래스의 자손 4명을 만들어 봅시다 Animal.
public class Bear extends Animal {
   @Override
   public void speak() {
       System.out.println("Growl!");
   }
}
public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}


public class Snake extends Animal {

   @Override
   public void speak() {
       System.out.println("Hiss!");
   }
}
다음은 미래를 위한 작은 생활 꿀팁입니다. 상위 클래스의 메서드를 재정의하려면 IntelliJ IDE 에서 파생 클래스의 코드로 이동하고 Ctrl+O를 누르고 메뉴에서 메서드 재정의...를 선택합니다 . 처음부터 단축키 사용에 익숙해지십시오. 그들은 코딩 속도를 높일 것입니다! 원하는 동작을 얻기 위해 몇 가지 작업을 수행했습니다.
  1. 각 자손 클래스에서 부모 클래스의 메서드와 동일한 이름으로 메서드를 만들었습니다.
  2. 우리는 메서드에 부모 클래스와 동일한 이름을 부여하는 것이 아니라 그 동작을 재정의하고 싶다고 컴파일러에 알렸습니다. 컴파일러에 대한 이 "메시지"는 @Override 주석을 통해 전달됩니다.
    메서드 위의 @Override 주석은 컴파일러(및 코드를 읽는 다른 프로그래머)에게 "걱정하지 마십시오. 이것은 실수나 실수가 아닙니다. 이 메서드가 이미 존재한다는 것을 알고 있으며 재정의하고 싶습니다. .

  3. 우리는 각 자손 클래스에 필요한 구현을 작성했습니다. 메서드가 호출 되면 speak()뱀은 쉭쉭거리고 곰은 으르렁거립니다.
이것이 프로그램에서 어떻게 작동하는지 봅시다:
public class Main {

   public static void main(String[] args) {

       Animal animal1 = new Dog();
       Animal animal2 = new Cat();
       Animal animal3 = new Bear();
       Animal animal4 = new Snake();

       animal1.speak();
       animal2.speak();
       animal3.speak();
       animal4.speak();
   }
}
콘솔 출력:

Woof! 
Meow! 
Growl! 
Hiss!
좋습니다. 모든 것이 제대로 작동합니다! 유형이 상위 클래스인 참조 변수 4개를 생성 Animal하고 하위 클래스의 서로 다른 개체 4개를 할당했습니다. 결과적으로 각 개체는 다르게 동작합니다. 각 파생 클래스에 대해 재정의된 메서드는 클래스 의 speak()기존 메서드를 대체합니다 (단순히 콘솔에 "Speaking: " 표시). 메서드 재정의에는 몇 가지 제한 사항이 있습니다. speak()Animal메서드 재정의 작동 방식 - 3
  1. 재정의된 메서드는 부모 클래스의 메서드와 동일한 인수를 가져야 합니다.

    speak부모 클래스의 메서드가 a를 입력으로 사용하는 경우 String자손 클래스의 재정의된 메서드도 a를 String입력으로 사용해야 합니다. 그렇지 않으면 컴파일러에서 오류가 발생합니다.

    public class Animal {
    
       public void speak(String s) {
    
           System.out.println("Speaking: " + s);
       }
    }
    
    public class Cat extends Animal {
    
       @Override // Error!
       public void speak() {
           System.out.println("Meow!");
       }
    }

  2. 재정의된 메서드는 부모 클래스의 메서드와 동일한 반환 형식을 가져야 합니다.

    그렇지 않으면 컴파일 오류가 발생합니다.

    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    
    public class Cat extends Animal {
    
       @Override
       public String speak() {         // Error!
           System.out.println("Meow!");
           return "Meow!";
       }
    }

  3. 재정의된 메서드의 액세스 한정자도 원본과 다를 수 없습니다.

    public class Animal {
    
       public void speak() {
    
           System.out.println("Hello!");
       }
    }
    
    public class Cat extends Animal {
    
       @Override
       private void speak() {      // Error!
           System.out.println("Meow!");
       }
    }
Java에서 메서드 재정의는 다형성을 구현하는 한 가지 방법입니다. 즉, 주요 이점은 앞에서 언급한 유연성입니다. 우리는 클래스의 간단하고 논리적인 계층 구조를 구축할 수 있습니다 . 각 speak()클래스는 특정 동작 (개 짖는 소리, 고양이 울음 소리)을 갖지만 인터페이스는 단일 인터페이스입니다.bark()meow()