[java] 인터페이스를 구현하는 추상 클래스가 인터페이스 메서드 중 하나의 선언 / 구현을 놓칠 수있는 이유는 무엇입니까?

인터페이스를 구현하기 위해 추상 클래스를 사용할 때 Java에서 흥미로운 일이 발생합니다. 인터페이스의 메서드 중 일부가 완전히 누락 될 수 있지만 (즉, 추상 선언이나 실제 구현이 존재하지 않음) 컴파일러가 불평하지 않습니다.

예를 들어 다음과 같은 인터페이스가 있습니다.

public interface IAnything {
  void m1();
  void m2();
  void m3();
}

다음 추상 클래스는 경고 나 오류없이 즐겁게 컴파일됩니다.

public abstract class AbstractThing implements IAnything {
  public void m1() {}
  public void m3() {}
}

이유를 설명해 주시겠습니까?



답변

클래스가 추상적 인 경우 정의에 따라 인스턴스화 할 하위 클래스를 만들어야하기 때문입니다. 하위 클래스는 추상 클래스가 생략 한 인터페이스 메서드를 구현하기 위해 컴파일러에 의해 필요합니다.

예제 코드에 AbstractThing따라 m2메서드 를 구현하지 않고 의 하위 클래스를 만들고 컴파일러가 제공하는 오류를 확인하십시오. 이 방법을 구현해야합니다.


답변

완벽합니다.
추상 클래스를 인스턴스화 할 수는 없지만 추상 클래스를 사용하여 m1 () 및 m3 ()에 대한 공통 구현을 수용 할 수 있습니다.
그래서 만약 m2 () 구현은 각 구현 다르지만 M1 및 m3는 없다. 다른 m2 구현만으로 다른 구체적인 IAnything 구현을 만들고 AbstractThing에서 파생하여 DRY 원칙을 준수 할 수 있습니다. 인터페이스가 추상 클래스에 대해 완전히 구현되었는지 확인하는 것은 헛된 일입니다.

업데이트 : 흥미롭게도 C #이 이것을 컴파일 오류로 강제한다는 것을 알았습니다. 이 시나리오의 추상 기본 클래스에서 메서드 서명을 복사하고 ‘abstract public’접두사를 붙여야합니다. (매일 새로운 것 🙂


답변

괜찮아. 위의 내용을 이해하려면 먼저 추상 클래스의 특성을 이해해야합니다. 그 점에서 인터페이스와 유사합니다. 이것이 오라클이 여기에서 말하는 입니다.

추상 클래스는 인터페이스와 유사합니다. 인스턴스화 할 수 없으며 구현 여부에 관계없이 선언 된 메서드 혼합이 포함될 수 있습니다.

따라서 인터페이스가 다른 인터페이스를 확장 할 때 어떤 일이 발생하는지 생각해야합니다. 예를 들어 …

//Filename: Sports.java
public interface Sports
{
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

//Filename: Football.java
public interface Football extends Sports
{
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

… 보시다시피, 이것도 완벽하게 잘 컴파일됩니다. 단순히 추상 클래스와 마찬가지로 인터페이스를 인스턴스화 할 수 없기 때문입니다. 따라서 “부모”에서 메서드를 명시 적으로 언급 할 필요가 없습니다. 그러나 모든 부모 메서드 서명은 암시 적으로 확장 인터페이스의 일부가되거나 추상 클래스를 구현합니다. 따라서 적절한 클래스 (인스턴스화 할 수있는 클래스)가 위를 확장하면 모든 단일 추상 메서드가 구현되었는지 확인해야합니다.

도움이되는 희망 … 그리고 Allahu ‘alam!


답변

인터페이스는 메소드 구현이 없지만 선언 만있는 클래스를 의미합니다.
한편, 추상 클래스는 구현없이 선언 만있는 일부 메서드와 함께 일부 메서드를 구현할 수있는 클래스입니다.
추상 클래스에 대한 인터페이스를 구현하면 추상 클래스가 인터페이스의 모든 메서드를 상속했음을 의미합니다. 따라서 추상 클래스에서 모든 메서드를 구현하는 것은 중요하지 않지만 추상 클래스 (상속에 의해)가되므로 추상 클래스는 여기에서 구현하지 않고 인터페이스에 일부 메서드를 남길 수 있습니다. 그러나이 추상 클래스가 특정 클래스에 의해 상속 될 때 구현되지 않은 모든 메서드를 추상 클래스에 구현해야합니다.


답변

주어진 인터페이스 :

public interface IAnything {
  int i;
  void m1();
  void m2();
  void m3();
}

이것이 Java가 실제로 보는 방식입니다.

public interface IAnything {
  public static final int i;
  public abstract void m1();
  public abstract void m2();
  public abstract void m3();
}

따라서 다른 클래스를 확장 abstract하는 abstract클래스 의 경우처럼 이러한 메서드 중 일부 (또는 전체)를 구현하지 않은 채로 둘 수 있습니다.abstract 클래스를 .

때 , 모든 것을 규칙 방법이 파생에서 구현해야이 만 콘크리트에 적용 되지 않습니다 구현 (즉,implementinterfaceinterfaceclassclassabstract 자체).

당신은 참으로 만들 계획이라면 abstract class그것을 밖으로을, 다음에했습니다 말한다 아무런 규칙이없는 implement모든 interface(이러한 경우에 파생 선언하는 필수주의 방법 class으로는 abstract)


답변

추상 클래스가 인터페이스를 구현할 때

인터페이스 섹션에서 인터페이스를 구현하는 클래스는 인터페이스의 모든 메소드를 구현해야한다는 점을 언급했습니다. 그러나 클래스가 추상으로 선언 된 경우 인터페이스의 모든 메서드를 구현하지 않는 클래스를 정의 할 수 있습니다. 예를 들면

abstract class X implements Y {
    // implements all but one method of Y
}
class XX extends X {
    // implements the remaining method in Y 
} 

이 경우 클래스 X는 Y를 완전히 구현하지 않기 때문에 추상이어야하지만 실제로 클래스 XX는 Y를 구현합니다.

참조 : http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html


답변

메서드를 구현하는 데 추상 클래스가 필요하지 않습니다. 따라서 인터페이스를 구현하더라도 인터페이스의 추상 메서드는 추상을 유지할 수 있습니다. 추상이 아닌 구체적인 클래스에서 인터페이스를 구현하려고하고 추상 메서드를 구현하지 않으면 컴파일러는 다음과 같이 알려줍니다. 추상 메서드를 구현하거나 클래스를 추상으로 선언합니다.