Wie simulieren Java-Schnittstellen Mehrfachvererbung?


76

Ich lese "The Java Tutorial" (zum 2. Mal). Ich habe gerade (wieder) den Abschnitt über Schnittstellen durchgearbeitet, verstehe aber immer noch nicht, wie Java-Schnittstellen Mehrfachvererbung simulieren. Gibt es eine klarere Erklärung als das, was in dem Buch steht?



In diesem Blogbeitrag wurde erklärt, wie eine Mehrfachvererbung erreicht werden kann. erik-rasmussen.com/blog/2006/10/23/multiple-inheritance-in-java
Rakesh Juyal

3
@Tom: gemäß "The Java Tutorial" (4. Ausgabe, S. 142) "In Java kann eine Klasse nur von einer Klasse erben, aber mehr als eine Schnittstelle implementieren. Daher können Objekte mehrere Typen haben: den eigenen Typ Klasse und die Typen aller von ihnen implementierten Schnittstellen. Wenn eine Variable als Typ einer Schnittstelle deklariert wird, kann ihr Wert auf jedes Objekt verweisen, das von einer Klasse instanziiert wird, die die Schnittstelle implementiert. " Der Autor hat mich im letzten Satz verloren, aber die Erklärungen hier haben es (meistens) geklärt.
Jacknad

Antworten:


154

Angenommen, Sie haben zwei Arten von Dingen in Ihrer Domäne: Lastwagen und Küchen

LKWs haben eine driveTo () -Methode und Küchen eine cook () -Methode.

Nehmen wir nun an, Pauli beschließt, Pizzen von der Rückseite eines Lieferwagens zu verkaufen. Er will etwas, mit dem er fahren () und kochen () kann.

In C ++ würde er dazu Mehrfachvererbung verwenden.

In Java wurde dies als zu gefährlich angesehen, sodass Sie von einer Hauptklasse erben können. Sie können jedoch Verhaltensweisen von Schnittstellen "erben", die in jeder Hinsicht abstrakte Klassen ohne Felder oder Methodenimplementierungen sind.

In Java tendieren wir daher dazu, Mehrfachvererbung mithilfe von Delegierungen zu implementieren:

Pauli unterteilt einen LKW in eine Unterklasse und fügt dem LKW eine Küche in einer Mitgliedsvariablen namens Küche hinzu. Er implementiert die Küchenschnittstelle, indem er kitchen.cook () aufruft.

class PizzaTruck extends Truck implements Kitchen {
   Kitchen kitchen;

   public void cook(Food foodItem) {
      kitchen.cook(foodItem);
   }
}

Er ist ein glücklicher Mann, weil er jetzt Dinge tun kann wie;

pizzaTruck.driveTo(beach);
pizzaTruck.cook(pizzaWithExtraAnchovies);

Ok, diese dumme Geschichte sollte darauf hinweisen, dass es sich nicht um eine Simulation der Mehrfachvererbung handelt, sondern um eine echte Mehrfachvererbung mit der Maßgabe, dass Sie nur den Vertrag erben können, nur von leeren abstrakten Basisklassen, die als Schnittstellen bezeichnet werden.

(Update: Mit dem Erscheinen der Standardmethoden können Schnittstellen jetzt auch ein Verhalten bereitstellen, das vererbt werden soll.)


8
Was ist, wenn Küche keine Schnittstelle ist, sondern eine andere Klasse?
Bizmarck

1
Dann wird es explodieren.
Adam Arold

2
@bizmark: Dann erstellen Sie eine Schnittstelle Cookery (mit public void cook()), die Kitchen und PizzaTruck beide implementieren würden.
Splungebob

10
Was ist, wenn sowohl LKW als auch Küche Klassen mit Feldern sind und wir alle diese Felder in PizzaTruck benötigen? zB um PizzaTruck.shootPizzasBackwards () zu implementieren, das PizzaCount (ein Küchenfeld) reduziert und die Geschwindigkeit erhöht (ein LKW-Feld)
Hello World

1
Obwohl dies 2010 korrekt war, ist "... die in jeder Hinsicht abstrakte Klassen ohne Felder oder Methodenimplementierungen sind ..." dank defaultMethoden nicht mehr korrekt . Schnittstellen noch nicht Instanz Zustand haben, aber sie tun Methoden haben eine Klasse erben können.
TJ Crowder

19

Sie sind wahrscheinlich verwirrt, weil Sie die Mehrfachvererbung lokal in Bezug auf eine Klasse anzeigen, die Implementierungsdetails von mehreren Eltern erbt. Dies ist in Java nicht möglich (und führt häufig zu Missbrauch in Sprachen, in denen dies möglich ist).

Schnittstellen ermöglichen die mehrfache Vererbung von Typen , z. B. class Waterfowl extends Bird implements Swimmerkann a von anderen Klassen verwendet werden, als ob es a wäre Bird und als ob es a wäre Swimmer. Dies ist die tiefere Bedeutung der Mehrfachvererbung: Ein Objekt kann so handeln, als ob es zu mehreren nicht verwandten verschiedenen Klassen gleichzeitig gehört.


1
Verstärkt durch die Dokumente von Oracle: docs.oracle.com/javase/tutorial/java/IandI/… . Ich danke Ihnen vielmals für die Unterscheidung zwischen der Vererbung von Typen und der "traditionelleren" Definition der Vererbung, einschließlich der Implementierung. Ich habe tagelang versucht zu verstehen, wie Schnittstellen als eine Form der Mehrfachvererbung betrachtet werden können, und jetzt ist es klar. Java verwendet einfach eine andere Definition der Vererbung als ich erwartet hatte. Ich wünschte, ich könnte Ihnen 61 weitere Stimmen geben, weil ich denke, dass dies eine stärkere Antwort ist als die derzeit akzeptierte.
skrrgwasme

17

Hier ist eine Möglichkeit, eine Mehrfachvererbung über Schnittstellen in Java zu erreichen.

Was ist zu erreichen?
Klasse A erweitert B, C // Dies ist in Java nicht direkt möglich, kann aber indirekt erreicht werden.

class B{
   public void getValueB(){}
}

class C{
   public void getValueC(){}
}


interface cInterface{
   public getValueC();
}

class cChild extends C implemets cInterface{
    public getValueC(){

      // implementation goes here, call the super class's getValueC();

    }
}


// Below code is **like** class A extends B, C 
class A extends B implements cInterface{
   cInterface child =  new cChild();
   child.getValueC();
}

Vielen Dank. Das ist die Antwort für mich.
Enadun

1
@challenger Wenn Sie "cInterface" implementieren, müssten wir "getValueC ()" in Klasse A implementieren, oder?
Nick

10

angesichts der beiden folgenden Schnittstellen ...

interface I1 {
  abstract void test(int i);
}
interface I2 {
  abstract void test(String s);
}

Wir können beide mit dem folgenden Code implementieren ...

public class MultInterfaces implements I1, I2 {
  public void test(int i) {
    System.out.println("In MultInterfaces.I1.test");
  }
  public void test(String s) {
    System.out.println("In MultInterfaces.I2.test");
  }
  public static void main(String[] a) {
    MultInterfaces t = new MultInterfaces();
    t.test(42);
    t.test("Hello");
  }
}

Wir können zwei Objekte NICHT erweitern, aber wir können zwei Schnittstellen implementieren.


Was ist, wenn die beiden Methoden in I1 und I2 dieselbe Art von Argumenten haben?
Nivetha T

Dann hätten Sie nur eine Methode, der Compiler ist das egal, da er dasselbe tut. Sehen Sie die Antwort hier stackoverflow.com/questions/2801878/…
david99world

10

Schnittstellen simulieren keine Mehrfachvererbung. Java-Ersteller betrachteten die Mehrfachvererbung als falsch, daher gibt es in Java keine solche.

Wenn Sie die Funktionalität von zwei Klassen zu einer kombinieren möchten, verwenden Sie die Objektzusammensetzung. Dh

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}

Wenn Sie bestimmte Methoden verfügbar machen möchten, definieren Sie sie und lassen Sie sie den Aufruf an den entsprechenden Controller delegieren.

Hier können Schnittstellen nützlich sein - wenn Sie Component1Schnittstelle Interface1und Component2Geräte implementieren Interface2, können Sie diese definieren

class Main implements Interface1, Interface2

Damit Sie Objekte austauschbar verwenden können, wo es der Kontext zulässt.


5

Es ist ziemlich einfach. Sie können mehr als eine Schnittstelle in einem Typ implementieren. So könnten Sie beispielsweise eine Implementierung haben List, die auch eine Instanz von ist Deque(und Java tut ... LinkedList).

Sie können Implementierungen einfach nicht von mehreren übergeordneten Elementen erben (dh mehrere Klassen erweitern). Deklarationen (Methodensignaturen) sind kein Problem.


Ja, deshalb "simuliert" es die Mehrfachvererbung.
Erick Robertson

1
@Erik: Es implementiert tatsächlich Mehrfachvererbung, nur nicht Mehrfachvererbung der Implementierung.
Joachim Sauer

@Erick: "Simuliert" ist nur dann ein nützlicher Begriff, wenn Sie eine vorgefasste Vorstellung davon haben, wie MI aus einer anderen Sprache "sein sollte". Selbst dann ist es ein destruktiver Gedanke. Es ist Mehrfachvererbung, nur einzigartig gemacht.
Mark Peters

Nun, es erbt die Signaturen, aber nicht die Implementierung. Wenn Ihnen der Begriff "simulierte Mehrfachvererbung" nicht gefällt, wie wäre es dann mit "partieller Mehrfachvererbung"? Es ist eindeutig nicht dasselbe wie eine vollständige Mehrfachvererbung. Es scheint mir, dass der wichtigste Teil darin besteht, dass Sie, wenn Sie sagen "A erweitert B implementiert C", eine Funktion haben können, die einen Parameter vom Typ C nimmt und ihm ein A übergibt. C ist eine vollkommen gute Deklaration des Parametertyps, auch wenn sie keine Deklaration enthält. Sie können das Spielzeug nicht bekommen, aber zumindest bekommen Sie die Box.
Jay

Eigentlich werde ich in diesem Fall zurückpedalieren. Ich denke, es ist einfacher und korrekter, wenn "Vererbung" streng gehalten wird, um über das Erben der Implementierung zu sprechen.
Mark Peters

5

Weißt du was? Aus der Perspektive eines JavaScript-Entwicklers, der versucht zu verstehen, was zum Teufel mit diesem Zeug los ist, möchte ich auf ein paar Dinge hinweisen, und jemand sagt mir bitte, was ich hier vermisse, wenn ich es bin weit weg von der Marke.

Schnittstellen sind wirklich einfach. Dumm, wahnsinnig einfach. Sie sind so dumm, wahnsinnig einfach, wie die Leute anfangs denken, weshalb es zu diesem Thema so viele doppelte Fragen gibt, weil der einzige Grund, sie zu verwenden, von Leuten unklar gemacht wurde, die versuchen, mehr aus ihnen zu machen, als sie sind und dort ist ein weit verbreiteter Missbrauch in jeder serverseitigen Java-Codebasis, der ich jemals ausgesetzt war.

Warum sollten Sie sie verwenden? Meistens würdest du nicht. Sie würden sie sicherlich nicht die ganze Zeit benutzen wollen, wie viele zu denken scheinen. Aber bevor ich zu dem Zeitpunkt komme, an dem Sie möchten, lassen Sie uns darüber sprechen, was sie NICHT sind.

Schnittstellen sind NICHT:

  • in irgendeiner Weise eine Problemumgehung für jede Art von Vererbungsmechanismus, die Java fehlt. Sie haben nichts mit Vererbung zu tun, sie haben es nie getan und simulieren in keiner Weise etwas Vererbungsähnliches.
  • unbedingt etwas, das dir bei Sachen hilft, die du geschrieben hast, genauso wie es dem anderen hilft, etwas zu schreiben, das dazu gedacht ist, mit deinen Sachen verbunden zu werden.

Sie sind wirklich so einfach, wie Sie denken, dass sie auf den ersten Blick sind. Die Leute missbrauchen die ganze Zeit dumm, daher ist es schwer zu verstehen, worum es geht. Es ist nur Validierung / Test. Sobald Sie etwas geschrieben haben, das einer Benutzeroberfläche entspricht und funktioniert, wird das Entfernen dieses "Implementierungs" -Codes nichts mehr beschädigen.

Wenn Sie die Schnittstellen jedoch korrekt verwenden, möchten Sie sie nicht entfernen, da der nächste Entwickler über ein Tool verfügt, mit dem er eine Zugriffsebene für einen anderen Satz von Datenbanken oder Webdiensten schreiben kann, damit der Rest Ihrer App fortgesetzt werden kann Verwenden, weil sie wissen, dass ihre Klasse fehlschlägt, bis sie die 100% vollständig erwartete Schnittstelle eingerichtet haben. Alles, was Schnittstellen tun, ist, Ihre Klasse zu validieren und festzustellen, dass Sie tatsächlich eine Schnittstelle implementiert haben, wie Sie es versprochen haben. Nichts mehr.

Sie sind auch tragbar. Indem Sie Ihre Schnittstellendefinitionen verfügbar machen, können Sie Personen, die Ihren unbelichteten Code verwenden möchten, eine Reihe von Methoden zur Anpassung geben, damit ihre Objekte ihn korrekt verwenden können. Sie müssen die Schnittstellen nicht implementieren. Sie konnten sie einfach auf ein Stück Notizblockpapier schreiben und das noch einmal überprüfen. Aber mit der Schnittstelle haben Sie eher eine Garantie, dass nichts versuchen wird zu funktionieren, bis es eine richtige Version der fraglichen Schnittstelle hat.

Also, wird eine Schnittstelle wahrscheinlich nie mehr als einmal implementiert? Völlig nutzlos. Mehrfachvererbung? Hör auf nach dem Regenbogen zu greifen. Java vermeidet sie aus einem bestimmten Grund und zusammengesetzte / aggregierte Objekte sind ohnehin in vielerlei Hinsicht flexibler. Das heißt nicht, dass Schnittstellen Ihnen nicht dabei helfen können, auf eine Weise zu modellieren, die Mehrfachvererbung zulässt, aber es ist wirklich keine Vererbung in irgendeiner Form und sollte nicht als solche angesehen werden. Es wird nur garantiert, dass Ihr Code erst funktioniert, wenn Sie alle von Ihnen festgelegten Methoden implementiert haben.


Die Klassenvererbung kombiniert zwei etwas orthogonale Konzepte: (1) die Fähigkeit abgeleiteter Klassen, Mitglieder der Basisklasse so zu verwenden, als wären sie ihre eigenen; (2) die Fähigkeit einer Variablen vom Basisklassentyp, Verweise auf Objekte eines beliebigen abgeleiteten Typs zu enthalten. Aspekt Nr. 2 ist ein ausreichend wichtiger Teil der Vererbung, den ich sicherlich als "vererbungsähnlich" bezeichnen würde [zumal Aspekt Nr. 1 eine Annehmlichkeit ist, aber Aspekt Nr. 2 für OOP erforderlich ist]. Der wesentliche Zweck einer Schnittstelle besteht darin, Code mit einem Verweis auf eine Sache, von der bekannt ist, dass sie eine gewisse Funktionalität aufweist, zuzulassen, diese Funktionalität zu verwenden .
Supercat

2 fühlt sich aufgrund anderer Einschränkungen beim Sprachdesign eher wie ein Schlüsselaspekt für Java OOP an als wie ein Schlüsselaspekt von OOP oder Vererbung im Allgemeinen. Obwohl ich gerade herausgefunden habe, dass Sie Konstanten über eine Schnittstelle in Java definieren und erben können, würde ich das mehr als vererbungsähnlich nennen.
Erik Reppen

Die durch Vererbung definierte Beziehung "X-is-aY" gibt an, dass Code, der einen Verweis auf a akzeptieren kann, auch einen Verweis auf a Yakzeptieren kann X. Welchen Nutzen hätte eine solche Beziehung, wenn eine solche Substitution nicht möglich wäre?
Supercat

"Sobald Sie etwas geschrieben haben, das einer Benutzeroberfläche entspricht und funktioniert, wird das Entfernen dieses" implementierten "Codes nichts beschädigen." -> Dies ist falsch, was besonders deutlich wird, wenn es sich um leere Schnittstellen handelt (wie bei Markierungsschnittstellen: stackoverflow.com/questions/25850328/marker-interfaces-in-java )
hmijail trauert um den 12.

3

Es ist keine Simulation der Mehrfachvererbung. In Java können Sie nicht von zwei Klassen erben, aber wenn Sie zwei Schnittstellen implementieren, "scheint es, als hätten Sie von zwei verschiedenen Klassen geerbt", weil Sie Ihre Klasse als eine Ihrer beiden Schnittstellen verwenden können.

Zum Beispiel

interface MyFirstInteface{
    void method1();
}
interface MySecondInteface{
    void method2();
}
class MyClass implements MyFirstInteface, MySecondInteface{
    public void method1(){
        //Method 1
    }
    public void method2(){
        //Method 2
    }

    public static void main(String... args){
        MyFirstInterface mfi = new MyClass();
        MySecondInterface msi = new MyClass();
    }
}

Dies wird funktionieren und Sie können mfi und msi verwenden. Es scheint eine Mehrfachvererbung zu sein, aber nicht, weil Sie nichts erben, sondern nur die von den Schnittstellen bereitgestellten öffentlichen Methoden neu schreiben.


3

Sie müssen genau sein:

Java erlaubt die mehrfache Vererbung der Schnittstelle, jedoch nur die einmalige Vererbung der Implementierung.

Sie vererben die Schnittstelle in Java mehrfach wie folgt:

public interface Foo
{
    String getX(); 
}

public interface Bar
{
    String getY();
}

public class MultipleInterfaces implements Foo, Bar
{
    private Foo foo;
    private Bar bar;

    public MultipleInterfaces(Foo foo, Bar bar)
    {
        this.foo = foo;
        this.bar = bar;
    }

    public String getX() { return this.foo.getX(); }
    public String getY() { return this.bar.getY(); }
}

3

Übrigens ist der Grund, warum Java keine vollständige Mehrfachvererbung implementiert, der, dass es Mehrdeutigkeiten erzeugt. Angenommen, Sie könnten sagen "A erweitert B, C", und dann haben sowohl B als auch C die Funktion "void f (int)". Welche Implementierung erbt A? Mit dem Java-Ansatz können Sie eine beliebige Anzahl von Schnittstellen implementieren, aber Schnittstellen deklarieren nur eine Signatur. Wenn also zwei Schnittstellen Funktionen mit derselben Signatur enthalten, muss Ihre Klasse eine Funktion mit dieser Signatur implementieren. Wenn von Ihnen geerbte Schnittstellen Funktionen mit unterschiedlichen Signaturen haben, haben die Funktionen nichts miteinander zu tun, sodass von einem Konflikt keine Rede ist.

Ich sage nicht, dass dies der einzige Weg ist. C ++ implementiert eine echte Mehrfachvererbung, indem Prioritätsregeln festgelegt werden, deren Implementierung gewinnt. Die Autoren von Java beschlossen jedoch, die Mehrdeutigkeit zu beseitigen. Ob aus philosophischer Überzeugung, dass dies zu saubererem Code führte, oder weil sie nicht die ganze zusätzliche Arbeit machen wollten, weiß ich nicht.


Korrigieren Sie mich, wenn ich falsch liege, aber nach meinem Verständnis beseitigt C ++ auch die Möglichkeit, einer Basisklasse virtuelle Mitglieder hinzuzufügen, ohne Unterklassen neu zu kompilieren, und verliert auch die referenzielle Identität der Basisklasse. Wenn B das virtuelle Mitglied Q hat, erben X und Y beide B und überschreiben Q getrennt, und Z erbt sowohl X als auch Y, wenn a & Z in a & X und dann & B umgewandelt wird, ergibt sich ein anderes Ergebnis als beim Umwandeln von a & Z in a & Y und dann & B. .
Supercat

2

Es ist nicht fair zu sagen, dass Schnittstellen Mehrfachvererbung "simulieren".

Sicher, Ihr Typ kann mehrere Schnittstellen implementieren und so viele verschiedene Typen polymorph agieren. Sie werden jedoch offensichtlich kein Verhalten oder keine Implementierungen unter dieser Anordnung erben.

Schauen Sie sich im Allgemeinen die Komposition an, bei der Sie der Meinung sind, dass Sie möglicherweise mehrere Vererbungen benötigen.

ODER Eine mögliche Lösung, um eine Mehrfachvererbung zu erreichen, ist die Mixin-Oberfläche - http://csis.pace.edu/~bergin/patterns/multipleinheritance.html . Vorsichtig verwenden!


2

Sie tun es nicht.

Ich denke, dass die Verwirrung von Leuten kommt, die glauben, dass die Implementierung einer Schnittstelle eine Form der Vererbung darstellt. Es tut nicht; Die Implementierung kann einfach leer sein, kein Verhalten wird durch die Handlung erzwungen oder durch einen Vertrag garantiert. Ein typisches Beispiel ist die Clonable-Schnittstelle, die zwar auf viele großartige Funktionen anspielt, aber so wenig definiert, dass sie im Wesentlichen nutzlos und potenziell gefährlich ist.

Was erben Sie durch die Implementierung einer Schnittstelle? Bubkes! Hören Sie meiner Meinung nach auf, die Wörter Schnittstelle und Vererbung im selben Satz zu verwenden. Wie Michael Borgwardt sagte, ist eine Schnittstelle keine Definition, sondern ein Aspekt.


2

Sie können tatsächlich von mehreren konkreten Klassen "erben", wenn diese selbst Schnittstellen implementieren. innerclasseshelfen Ihnen dabei:

interface IBird {
    public void layEgg();
}

interface IMammal {
    public void giveMilk();
}

class Bird implements IBird{
    public void layEgg() {
        System.out.println("Laying eggs...");
    }
}

class Mammal implements IMammal {
    public void giveMilk() {
        System.out.println("Giving milk...");
    }
}

class Platypus implements IMammal, IBird {

    private class LayingEggAnimal extends Bird {}
    private class GivingMilkAnimal extends Mammal {}

    private LayingEggAnimal layingEggAnimal = new LayingEggAnimal();

    private GivingMilkAnimal givingMilkAnimal = new GivingMilkAnimal();

    @Override
    public void layEgg() {
        layingEggAnimal.layEgg();
    }

    @Override
    public void giveMilk() {
        givingMilkAnimal.giveMilk();
    }

}


2

Ich möchte auf etwas hinweisen, das mich in den Hintergrund gedrängt hat und aus C ++ stammt, wo Sie auch viele Implementierungen leicht erben können.

Eine "breite" Schnittstelle mit vielen Methoden bedeutet, dass Sie viele Methoden in Ihren konkreten Klassen implementieren müssen und diese nicht einfach für Implementierungen freigeben können.

Zum Beispiel:

interface Herbivore {
    void munch(Vegetable v);
};

interface Carnivore {
    void devour(Prey p);
}

interface AllEater : public Herbivore, Carnivore { };

class Fox implements AllEater {
   ... 
};

class Bear implements AllEater {
   ...
};

In diesem Beispiel können Fox und Bear keine gemeinsame Basisimplementierung für die Schnittstellenmethoden munchund gemeinsam nutzen devour.

Wenn die Basisimplementierungen so aussehen, möchten wir sie möglicherweise für Foxund verwenden Bear:

class ForestHerbivore implements Herbivore
    void munch(Vegetable v) { ... }
};

class ForestCarnivore implements Carnivore
    void devour(Prey p) { ... }
};

Aber wir können nicht beide erben. Die Basisimplementierungen müssen Mitgliedsvariablen in der Klasse sein, und die definierten Methoden können diese weiterleiten. Dh:

class Fox implements AllEater {
    private ForestHerbivore m_herbivore;
    private ForestCarnivore m_carnivore;

    void munch(Vegetable v) { m_herbivore.munch(v); }
    void devour(Prey p) { m_carnivore.devour(p); }
}

Dies wird unhandlich, wenn Schnittstellen wachsen (dh mehr als 5-10 Methoden ...)

Ein besserer Ansatz besteht darin, eine Schnittstelle als eine Aggregation von Schnittstellen zu definieren:

interface AllEater {
    Herbivore asHerbivore();
    Carnivore asCarnivore();
}

Dies bedeutet, dass Foxund müssen Bearnur diese beiden Methoden implementiert werden, und die Schnittstellen und Basisklassen können unabhängig von der aggregierten AllEaterSchnittstelle wachsen , die die implementierenden Klassen betrifft.

Weniger Kopplung auf diese Weise, wenn es für Ihre App funktioniert.


1

Ich glaube nicht.

Vererbung ist speziell eine implementierungsorientierte Beziehung zwischen Implementierungen. Schnittstellen liefern überhaupt keine Implementierungsinformationen, sondern definieren einen Typ. Um eine Vererbung zu haben, müssen Sie einige Verhaltensweisen oder Attribute speziell von einer übergeordneten Klasse erben.

Ich glaube, hier gibt es irgendwo eine Frage speziell zur Rolle von Schnittstellen und Mehrfachvererbung, aber ich kann sie jetzt nicht finden ...


1

Es gibt wirklich keine Simulation der Mehrfachvererbung in Java.

Manchmal wird gesagt, dass Sie mithilfe von Schnittstellen mehrere Vererbungen simulieren können, da Sie mehr als eine Schnittstelle pro Klasse implementieren und dann die Komposition (anstelle der Vererbung) in Ihrer Klasse verwenden können, um das Verhalten der mehreren Klassen zu erreichen, von denen Sie erben wollten zunächst.


1

Wenn es in Ihrem Objektmodell sinnvoll ist, können Sie natürlich von einer Klasse erben und auch eine oder mehrere Schnittstellen implementieren.


1

Es gibt Fälle, in denen Mehrfachvererbung sehr praktisch und schwer durch Schnittstellen zu ersetzen ist, ohne mehr Code zu schreiben. Beispielsweise gibt es Android-Apps, die Klassen verwenden, die von Activity und andere von FragmentActivity in derselben App abgeleitet sind. Wenn Sie eine bestimmte Funktion haben, die Sie in einer gemeinsamen Klasse freigeben möchten, müssen Sie in Java Code duplizieren, anstatt untergeordnete Klassen von Activity und FragmentsActivity von derselben SharedFeature-Klasse ableiten zu lassen. Und die schlechte Implementierung von Generika in Java hilft auch nicht, da das Schreiben von Folgendem illegal ist:

public class SharedFeature<T> extends <T extends Activity>

...
...

1

Mehrfachvererbung in Java wird nicht unterstützt.

Diese Geschichte der Unterstützung der Mehrfachvererbung über die Benutzeroberfläche haben wir Entwickler erfunden. Die Schnittstelle bietet Flexibilität als konkrete Klassen und wir haben die Möglichkeit, mehrere Schnittstellen mit einer einzigen Klasse zu implementieren. Dies ist nach Vereinbarung, wir halten uns an zwei Blaupausen, um eine Klasse zu erstellen.

Dies versucht, der Mehrfachvererbung näher zu kommen. Wir implementieren mehrere Schnittstellen, hier erweitern (erben) wir nichts. Die implementierende Klasse ist diejenige, die die Eigenschaften und das Verhalten hinzufügt. Die Implementierung wird nicht frei von den übergeordneten Klassen. Ich würde einfach sagen, es gibt keine Unterstützung für Mehrfachvererbung in Java.



1

Ich muss auch sagen, dass Java keine Mehrfachvererbung unterstützt.

Sie müssen die Bedeutung zwischen extendsund implementsSchlüsselwörtern in Java unterscheiden. Wenn wir verwenden extends, erben wir die Klasse tatsächlich nach diesem Schlüsselwort. Um alles zu vereinfachen, können wir jedoch nicht extendsmehr als einmal verwenden. Sie können jedoch beliebig viele Schnittstellen implementieren.

Wenn Sie eine Schnittstelle implementieren, besteht keine Wahrscheinlichkeit, dass Sie die Implementierung aller Methoden in jeder Schnittstelle verpassen (Ausnahme: Standardimplementierungen von in Java 8 eingeführten Schnittstellenmethoden). Sie wissen also jetzt genau, was mit den Dingen passiert dass Sie in Ihre neue Klasse eingebettet haben.

Warum Java keine Mehrfachvererbung zulässt, ist, dass Mehrfachvererbung den Code etwas komplexer macht. Manchmal können zwei Methoden übergeordneter Klassen aufgrund derselben Signaturen in Konflikt geraten. Wenn Sie jedoch gezwungen sind, alle Methoden manuell zu implementieren, erhalten Sie, wie oben erwähnt, das vollständige Verständnis darüber, was vor sich geht. Es macht Ihren Code für Sie verständlicher.

Wenn Sie weitere Informationen zu Java-Schnittstellen benötigen, lesen Sie diesen Artikel unter http://www.geek-programmer.com/introduction-to-java-interfaces/.


1

Zwischen zwei Java-Klassen ist eine direkte Mehrfachvererbung nicht möglich. In diesem Fall empfiehlt Java Use, um die Methode innerhalb der Schnittstelle zu verbinden und zu deklarieren und die Methode mit der Child-Klasse zu implementieren.

interface ParentOne{
   public String parentOneFunction();
}

interface ParentTwo{
    public String parentTwoFunction();
}

class Child implements ParentOne,ParentTwo{

   @Override
    public String parentOneFunction() {
        return "Parent One Finction";
    }

    @Override
    public String parentTwoFunction() {
        return "Parent Two Function";
    }

    public String childFunction(){
       return  "Child Function";
    }
}
public class MultipleInheritanceClass {
    public static void main(String[] args) {
        Child ch = new Child();
        System.out.println(ch.parentOneFunction());
        System.out.println(ch.parentTwoFunction());
        System.out.println(ch.childFunction());
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.