web-dev-qa-db-ja.com

JDK 8のデフォルトはJavaの多重継承の形式ですか?

JDK 8の新機能により、バイナリ互換性を維持しながら、既存のインターフェイスに追加できます。

構文は次のようなものです

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

SomeInterfaceのすべての既存の実装でこの方法を使用すると、この新しいバージョンにアップグレードするときに、newInterface()の周囲で突然コンパイルエラーが発生することはありません。

これは適切ですが、実装していない新しいデフォルトのメソッドを両方とも追加した2つのインターフェイスを実装するとどうなりますか?例で説明しましょう。

_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の一部として定義されていますか?

Java神がここで似たようなことについて話している 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

78
Pyrolistical

視聴するビデオセッションはこちら http://medianetwork.Oracle.com/video/player/1113272518001 これは、Virtualという機能について話しているデザイナーです拡張機能。彼はまた、これが後方互換性を壊さないことについても語っています。

9
Peter Lawrey

複製操作に対する答えは次のとおりです。

多重継承の問題を解決するには、同じメソッド名とシグネチャのデフォルト実装を提供する2つのインターフェースを実装するクラスがメソッドの実装を提供する必要があります。 [記事全文]

あなたの質問に対する私の答えは次のとおりです。はい、それは複数の継承の形式です。なぜなら、異なる親から行動を継承できるからです。欠けているのは、状態を継承することです。 e。、属性。

64
H-Man2

私はこれが古い投稿であることを知っていますが、私はこのもので作業しているので...

コンパイラからエラーが発生し、次のことを伝えます。

TimeクラスTimeTravelingStudentは、AttendanceおよびTimelineからpresentへの参照からpresent()の無関係なデフォルトを継承します。Timelineのメソッドpresent()とAttendanceのメソッドpresent()の両方があいまいです。

8
Enkk

twoシナリオがあります:

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)次に、ある場合ISはより具体的なインターフェイスです

   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
    }
5
Andrejs

つまり、コンパイル時のエラーであり、実装内で手動でメソッドをオーバーライドする必要があります。


デフォルト方式の目的

Java 8でデフォルトのメソッドを導入する主な目的は、既存の実装を壊さずにインターフェースを拡張可能にすることです(サードパーティJavaライブラリが非常に多くあります)。

そして、C++のような_multiple inheritance_は実際に回避することを目的としています。これはJavaのデフォルトメソッドの目的ではありません。


オーバーライドする方法

2つのオプション:

  • メソッドを独自のロジックでオーバーライドします。
  • メソッドをオーバーライドし、superを介してインターフェイスのメソッドの1つを呼び出します。形式は<interface_name>.super.<method_name>();です

チップ:

  • インターフェースからのメソッドはデフォルトでpublicなので、オーバーライドするときにpublicキーワードを追加することを忘れないでください。
4
Eric Wang

あなたの質問に対する私の答えは次のとおりです。はい、それは複数の継承の形式です。なぜなら、異なる親から行動を継承できるからです。欠けているのは、状態を継承することです。 e。、属性。

はい。ただし、インターフェイスにゲッターとセッターを追加して、実装クラスで実装する必要があります。それでも、実装クラスは属性を継承しません。ですから、AFAICS、それは多重継承スタイルのソリューションというよりも、特性スタイルのソリューションに似ています。

4
OlliP

誰かがまだ答えを探している場合、クラスが同じデフォルトメソッドで2つのインターフェースを実装する場合、クラスは独自の実装を提供することで曖昧さを解決する必要があります。デフォルトのメソッドでの継承の仕組みの詳細については、 this チュートリアルをご覧ください。

2

「メソッドをどのように区別するか」は、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()");   
 }

特定のインターフェイスからメソッド具体的な実装を呼び出すには、 instantiate the interface and explicitly call the concrete method of that interface

たとえば、次のコードはconcreteメソッドの実装を呼び出します m() from interface A

new A(){}.m();

上記の出力は次のようになります。

インターフェイスA:m()

0
Mark Burleigh