[java] JDK 8의 기본값은 Java에서 다중 상속의 한 형태입니까?

JDK 8의 새로운 기능을 사용하면 바이너리 호환성을 유지하면서 기존 인터페이스에 추가 할 수 있습니다.

구문은 다음과 같습니다.

public interface SomeInterface() {
  void existingInterface();
  void newInterface() default SomeClass.defaultImplementation;
}

이러한 방식으로 기존의 모든 구현 SomeInterface에서이 새 버전으로 업그레이드 할 때 갑자기 newInterface().

이것은 깔끔하지만 구현하지 않은 새로운 기본 메서드를 추가 한 두 개의 인터페이스를 구현할 때 어떤 일이 발생합니까? 예를 들어 설명하겠습니다.

public interface Attendance {
   boolean present() default DefaultAttendance.present;
}

public interface Timeline {
   boolean present() default DefaultTimeline.present;
}

public class TimeTravelingStudent implements Attendance, Timeline {

}

// which code gets called?
new TimeTravelingStudent().present();

아직 JDK 8의 일부로 정의 되었습니까?

나는 http://cs.oswego.edu/pipermail/lambda-lib/2011-February/000068.html 에서 비슷한 것에 대해 이야기하는 자바 신을 찾았 지만 개인 메일 링 목록의 일부이며 직접 요청할 수 없습니다.

JDK 8에서 기본값을 사용하는 방법과 람다를 지원하도록 Collection 인터페이스를 확장하는 방법에 대한 자세한 내용은
https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf를 참조하십시오.



답변

복제 작업에 대한 대답은 다음과 같습니다.

다중 상속 문제를 해결하려면 동일한 메서드 이름과 서명에 대한 기본 구현을 제공하는 두 인터페이스를 구현하는 클래스가 메서드 구현을 제공해야합니다. [전체 기사]

귀하의 질문에 대한 제 대답은 다음과 같습니다. 예, 여러 부모로부터 행동을 상속받을 수 있기 때문에 다중 상속의 한 형태입니다. 빠진 것은 상태, 즉 속성을 상속하는 것입니다.


답변

나는 이것이 오래된 게시물이라는 것을 알고 있지만, 나는이 일을하고 있기 때문에 …

컴파일러에서 다음과 같은 오류가 발생합니다.

 TimeTravelingStudent 클래스는 출석 유형에서 present ()에 대한 관련없는 기본값을 상속하고 현재에 대한 타임 라인 참조가 모호합니다. 둘 다 타임 라인의 present () 메서드와 출석 일치의 메서드 present ()입니다.


답변

거기 시나리오 :

1) 먼저 언급했는데 가장 구체적인 인터페이스없는 경우

public interface A {
   default void doStuff(){ /* implementation */ }
}

public interface B {
   default void doStuff() { /* implementation */ }
}

public class C implements A, B {
// option 1: own implementation
// OR
// option 2: use new syntax to call specific interface or face compilation error
  void doStuff(){
      B.super.doStuff();
  }
}

2) 둘째, 보다 구체적인 인터페이스가있는 경우 :

   public interface A {
       default void doStuff() { /* implementation */ }
    }

    public interface B extends A {
       default void doStuff() { /* implementation */ }
    }

    public class C implements A, B {
    // will use method from B, as it is "closer" to C
    }


답변

귀하의 질문에 대한 제 대답은 다음과 같습니다. 예, 여러 부모로부터 행동을 상속받을 수 있기 때문에 다중 상속의 한 형태입니다. 빠진 것은 상태, 즉 속성을 상속하는 것입니다.

예,하지만 구현 클래스가 구현해야하는 인터페이스에 getter 및 setter를 추가 할 수 있습니다. 그럼에도 불구하고 구현 클래스는 속성을 상속하지 않습니다. 따라서 AFAICS는 다중 상속 스타일 솔루션이 아니라 특성 스타일 솔루션과 비슷합니다.


답변

요컨대, 컴파일 시간 오류이며 구현시 수동으로 메서드를 재정의해야합니다.


기본 방법의 목적

Java 8에 기본 메소드를 도입하는 주요 목적은 기존 구현을 손상시키지 않고 인터페이스를 확장 가능하게 만드는 것입니다 (타사 Java 라이브러리가 너무 많습니다).

그리고 multiple inheritanceC ++에서 와 같이 실제로는 피하도록되어 있습니다. 이것은 자바에서 기본 메소드의 목적이 아닙니다.


재정의하는 방법

2 가지 옵션 :

  • 자체 논리로 메서드를 재정의합니다.
  • 메서드를 재정의하고 super, 형식을 통해 인터페이스의 메서드 중 하나를 호출 합니다.<interface_name>.super.<method_name>();

팁 :

  • 인터페이스의 메소드는 기본적으로 공용이므로 public재정의 할 때 키워드 를 추가하는 것을 잊지 마십시오 .


답변

누군가가 여전히 답을 찾고 있다면, 클래스가 동일한 기본 메소드로 두 개의 인터페이스를 구현하는 경우 클래스는 자체 구현을 제공하여 명확성을 해결해야합니다. 기본 메서드의 상속이 작동하는 방법에 대한 자세한 내용 은 자습서를 참조하십시오.


답변

“어떻게 메소드를 구별 할 것인가”는 Stackoverflow에 제기 된 질문 이며 Java1.8 인터페이스의 구체적인 메소드를 참조했습니다.

다음은 그 질문에 답해야하는 예입니다.

interface A{
default public void m(){
System.out.println("Interface A: m()");
}
}

interface B{
default public void m(){
System.out.println("Interface B: m()");
}
}

 class C implements A,B {

 public void m(){
  System.out.println("Concrete C: m()");
 }

public static void main(String[] args) {
   C aC = new C();
   aC.m();
   new A(){}.m();
   new B(){}.m();
}
}

위의 클래스 C 는 인터페이스 A와 B 의 고유 한 구체적인 방법구현해야합니다 . 즉 :

 public void m(){
  System.out.println("Interface C: m()");
 }

통화에 구체적인 구현방법 A로부터 특정 인터페이스를 수행 할 수 있습니다 인스턴스화 인터페이스를 하고 명시 적으로 호출 구체적인 방법을 이의 인터페이스를

예를 들어 다음 코드는 인터페이스 A 에서 m () 메서드 의 구체적인 구현을 호출합니다 .

new A(){}.m();

위의 출력은 다음과 같습니다.

인터페이스 A : m ()