web-dev-qa-db-ger.com

Java, warum die Schnittstelle erweitert wird

Ich frage mich, unter welchen Umständen erweitern wir eine Schnittstelle von einer Schnittstelle? Weil zum Beispiel 

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

Ist es nicht gleichbedeutend mit 

interface A{
    public void method1();
}
interface B{
    public void method2();     
}
class C implements A, B{
    @Override public void method1(){}
    @Override public void method2(){}
}

Gibt es wichtige Gründe dafür?

30
peter

Die wesentlichen Gründe hängen völlig davon ab, was die Schnittstelle tun soll.

Wenn Sie eine Schnittstelle Fahrzeug und eine Schnittstelle Fahren haben, ist es selbstverständlich, dass alle Fahrzeuge fahren können. Ohne Schnittstellenvererbung wird jede andere Autoklasse erforderlich sein

class ChevyVolt implements Vehicle, Drivable
class FordEscort implements Vehicle, Drivable
class ToyotaPrius implements Vehicle, Drivable

und so weiter.

Wie gesagt, alle Fahrzeuge sind fahrbar, so dass es einfacher ist, Folgendes zu haben:

class ChevyVolt implements Vehicle
class FordEscort implements Vehicle
class ToyotaPrius implements Vehicle

Mit Fahrzeug wie folgt:

interface Vehicle extends Drivable

Und muss nicht darüber nachdenken.

46
Spencer Ruport

Ja, das gibt es: Es ist wie sonst wo Erbschaft. Wenn B eine Spezialisierung von A ist, sollte es so geschrieben werden. Das zweite zeigt an, dass die Klasse zufällig 2 Schnittstellen ohne Beziehung zwischen ihnen implementiert.

Aus der Sicht des Endergebnisses könnten Sie anstelle der Handhabung einer Hierarchie nur mehrere Schnittstellen verwenden (genau wie Sie es vermeiden könnten, vererbtes Verhalten in einer Klassenhierarchie zu verwenden). Dies würde jedoch die Informationen stärker zerstreuen und als (wenn nicht mehr) signifikant die Absicht des Softwaremodells verschleiern.

12
Matt Whipple

Ja, es gibt einen großen Unterschied.

In Ihrem ersten Beispiel ist Ihre neue Schnittstelle B so definiert, dass sie sich von A aus erstreckt. In Zukunft jede Klasse, die B automatisch implementiert implementiert A. Grundsätzlich sagen Sie dem Compiler: "Hier ist, was es bedeutet, ein A zu sein, hier ist, was es bedeutet, ein B zu sein, und oh, übrigens, alle Bs sind auch As! " Damit können Sie Dinge sagen wie ...

class C implements B {
    ... you implement all of the methods you need...
    ...blah...
    ...blah...
}
A myNewA = new C();

und das funktioniert gut.

In Ihrem zweiten Beispiel deklarieren Sie B jedoch nicht als Erweiterung von A, sodass der obige Code nicht funktioniert. Wenn Sie versuchen, einer Referenz für A eine Instanz von (der zweiten Art von) C zuzuweisen, wird dies beanstandet, da Sie dem Complier nicht mitgeteilt haben, dass "alle B's sind wirklich A's. " (d. h. es gibt keine Beziehung zwischen B und C)

5
Bob Gilmore

Wenn Sie nicht möchten, dass B ohne A implementiert wird, können Sie B um A erweitern.

Beispiel:

interface LivingThing{
public void eat();
}

interface Dog extends LivingThing{
public void Bark();
}

Es ist möglich, ein lebendes Tier zu sein, ohne ein Hund zu sein, aber es ist nicht möglich, ein Hund zu sein, ohne ein lebendes Tier zu sein. Wenn es bellen kann, kann es auch essen, aber das Gegenteil trifft nicht immer zu.

2
WVrock

Was Sie sagen, ist richtig, aber es geht nicht nur darum, unsere Arbeit zu erledigen. Was ist, wenn die Anforderung so ist:

1) Stellen Sie sich vor, es gibt 10 Schnittstellen, die nicht gleichzeitig entworfen sind. Für z. Die AutoCloseable-Schnittstelle in Java 7. Es wurde eine neue Funktion zum automatischen Schließen hinzugefügt, die erst nach Java 6 verfügbar war.

2) Wenn Sie eine Schnittstelle C entworfen haben, die eine Markierungsschnittstelle ist, und alle Klassen, die von einer bestimmten Klasse B abgeleitet wurden, markiert haben sollen, ist die beste Lösung, B zu verwenden, C zu erweitern und die Implementierung der C-Elemente nicht überall vorzunehmen.

Es gibt viele weitere Gründe. Wenn Sie sich das Gesamtbild der Klassen und Hierarchien ansehen, erhalten Sie die Antwort möglicherweise selbst.

Glücklich zu helfen. Dharam

1
dharam

es gibt nur einen Kommentar in

interface A{
    public void method1();
}
interface B extends A{
    public void method2();
}
class C implements B{
    @Override public void method1(){}
    @Override public void method2(){}
}

wenn Sie A deklarieren a = new C ();

sie können nicht Methode2 () aufrufen; weil Schnittstelle A nichts über Elemente in Schnittstelle B weiß, selbst wenn Sie Methoden in Klasse C implementieren

0
Moamen Adel

Der Hauptunterschied hier ist, dass in Ihrem ersten Beispiel B A und dann einige ist. Das heißt, Schnittstelle B ruft method1 () und method2 () auf, wobei A und B wie im zweiten Teil getrennt sind (Schnittstelle B schließt method1 () NICHT ab) und Klasse C implementiert A und B. In beiden Fällen wird Klasse1 durch Klasse C überschrieben () und method2 (). Ich hoffe das hilft!

0
Nick