it-swarm.com.de

Sind die Standardwerte in JDK 8 eine Form der mehrfachen Vererbung in Java?

Mit einer neuen Funktion in JDK 8 können Sie eine vorhandene Schnittstelle hinzufügen und dabei die Binärkompatibilität beibehalten.

Die Syntax ist wie

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

Auf diese Weise haben alle vorhandenen Implementierungen von SomeInterface beim Upgrade auf diese neue Version nicht alle plötzlich Fehler in der Umgebung von newInterface().

Was passiert, wenn Sie zwei Schnittstellen implementieren, bei denen beide eine neue Standardmethode hinzugefügt haben, die Sie nicht implementiert haben? Lassen Sie mich mit einem Beispiel erklären.

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();

Wurde dies bereits in JDK 8 definiert?

Ich habe Java-Götter gefunden, die hier über etwas Ähnliches sprechen http://cs.oswego.edu/pipermail/lambda-lib/2011-February/000068.html , aber es ist Teil der privaten Mailingliste und ich kann sie nicht fragen direkt.

Weitere Informationen zur Verwendung von Standardwerten in JDK 8 und zur Erweiterung der Collection-Schnittstelle für die Unterstützung von Lambdas finden Sie hier: https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662. pdf

76
Pyrolistical

Die Videositzung, die Sie sich ansehen können, ist hier http://medianetwork.Oracle.com/video/player/1113272518001 Dies ist der Designer, der über die Funktion namens Virtual Extensions spricht. Er spricht auch darüber, dass dies die Abwärtskompatibilität nicht bricht.

9
Peter Lawrey

Die Antwort auf die doppelte Operation lautet:

Um ein Problem der Mehrfachvererbung zu lösen, muss eine Klasse, die zwei Schnittstellen implementiert, die eine Standardimplementierung für denselben Methodennamen und dieselbe Signatur bereitstellen, eine Implementierung der Methode bereitstellen. [Ganzer Artikel]

Meine Antwort auf Ihre Frage lautet: Ja, es ist eine Form der Mehrfachvererbung, weil Sie Verhalten von verschiedenen Elternteilen erben können. Was fehlt, ist das Erben von Zuständen, d.h. Attribute.

63
H-Man2

Ich weiß, das ist ein alter Beitrag, aber da ich mit diesem Zeug arbeite ...

Sie erhalten einen Fehler vom Compiler und sagen Ihnen:

 Die Klasse TimeTravelingStudent erbt nicht vorhandene Standardwerte für present () vom Typ Anwesenheit und Zeitleiste Der Verweis auf present ist mehrdeutig, sowohl die Methode present () in der Timeline als auch die Methode present () in der Anwesenheitsabstimmung.

8
Enkk

Kurz gesagt: Es handelt sich um einen Kompilierzeitfehler, der die Methode in der Implementierung von Hand überschreiben muss.


Zweck der Standardmethode

Der Hauptzweck der Einführung der Standardmethode in Java 8 besteht darin, die Schnittstelle erweiterbar zu machen, ohne vorhandene Implementierungen zu unterbrechen (es gibt so viele Java-Bibliotheken von Drittanbietern).

Und multiple inheritance soll wie in C++ eigentlich vermieden werden, das ist definitiv nicht der Zweck der Standardmethode in Java.


Wie überschreiben?

2 Optionen:

  • Überschreiben Sie die Methode mit einer eigenen Logik.
  • Überschreiben Sie die Methode, rufen Sie eine der Schnittstellenmethoden über super auf, format: <interface_name>.super.<method_name>();

Tipps:

  • die Methode von der Schnittstelle ist standardmäßig auf public gesetzt. Vergessen Sie nicht, das public-Schlüsselwort hinzuzufügen, wenn Sie es überschreiben.
4
Eric Wang

Meine Antwort auf Ihre Frage lautet: Ja, es ist eine Form der Mehrfachvererbung, weil Sie Verhalten von verschiedenen Elternteilen erben können. Was fehlt, ist das Erben von Zuständen, d.h. Attribute.

Ja, Sie können der Schnittstelle jedoch Getter und Setter hinzufügen, die die implementierenden Klassen dann implementieren müssen. Trotzdem erben die implementierenden Klassen keine Attribute. Also, AFAICS, es ist eher eine Traitelösung als eine Mehrfachvererbungslösung. 

4
OlliP

Es gibt zwei Szenarien:

1) Zuerst wurde das erwähnt, wo es keine spezifischste Schnittstelle gibt

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) Zweitens, wenn IS eine spezifischere Schnittstelle ist:

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

Wenn noch jemand nach einer Antwort sucht, falls eine Klasse zwei Schnittstellen mit derselben Standardmethode implementiert, muss die Klasse die Unbestimmtheit auflösen, indem sie eine eigene Implementierung bereitstellt. Weitere Informationen zur Funktionsweise der Vererbung in Standardmethoden finden Sie im Tutorial " this ".

2

"Wie werden wir die Methoden unterscheiden" war eine Frage, die auf Stackoverflow gestellt und auf diese Frage verwiesen wurde konkrete Methoden in Interfaces Java1.8

Das folgende Beispiel soll diese Frage beantworten:

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();
}
}

Klasse C über muss eine eigene konkrete Methode der Schnittstellen A und B implementieren.

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

Um eine konkrete Implementierung einer Methode von einer spezifischen Schnittstelle aufzurufen, können Sie instanziieren der Schnittstelle und explizit aufrufen die konkrete Methode dieser Schnittstelle

Der folgende Code ruft beispielsweise die konkrete Implementierung der Methode m () von Schnittstelle A auf:

new A(){}.m();

Die Ausgabe der oben genannten wäre:

Schnittstelle A: m ()

0
Mark Burleigh