Java Multiple Inheritance

168

Um zu verstehen, wie man die Mehrfachvererbungsprobleme von Java löst, habe ich eine klassische Frage, die geklärt werden muss.

Nehmen wir an, ich habe eine Klasse, Animaldie Unterklassen hat, Birdund Horseich muss eine Klasse machen Pegasus, die sich von Birdund Horsenach Pegasussowohl einem Vogel als auch einem Pferd erstreckt.

Ich denke, das ist das klassische Diamantproblem. Von dem, was ich die klassische Art und Weise versteht , kann dies zu lösen , ist das zu machen Animal, Birdund HorseKlassen - Schnittstellen und implementieren Pegasusvon ihnen.

Ich habe mich gefragt, ob es einen anderen Weg gibt, um das Problem zu lösen, bei dem ich noch Objekte für Vögel und Pferde erstellen kann. Wenn es einen Weg gäbe, auch Tiere erschaffen zu können, wäre das großartig, aber nicht notwendig.

Sheli
quelle
6
Ich denke, Sie können die Klassen manuell erstellen und als Mitglieder speichern (Komposition statt Vererbung). Bei der Proxy- Klasse ( docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html ) ist dies möglicherweise eine Option, obwohl Sie auch die Schnittstellen benötigen.
Gábor Bakos
4
@RAM dann sollte es Bird nicht verlängern, sondern ein Verhalten haben, das es ihm ermöglicht, einen Flug zu nehmen. : D Problem gelöst
Yogesh
11
Genau. Wie wäre es mit einer Schnittstelle CanFly. :-)
Überraschte Kokosnuss
28
Ich denke, das ist der falsche Ansatz. Sie haben Tiere - Pferde, Vögel. Und Sie haben Eigenschaften - Fliegen, Fleischfresser. Ein Pegasus ist kein HorseBird, sondern ein Pferd, das fliegen kann. Die Eigenschaften sollten in Schnittstellen. Also public class Pegasus extends Horse implements Flying.
Boris die Spinne
12
Ich verstehe, warum Sie denken, dass es falsch ist und sich nicht an die Regeln der Biologie hält und Ihre Besorgnis schätzt, aber in Bezug auf das Programm, das ich erstellen muss und das tatsächlich mit Banken zu tun hat, war dies der beste Ansatz für mich. Da ich meine eigentlichen Probleme nicht posten wollte, da dies gegen die Regeln verstoßen würde, habe ich das Beispiel ein wenig geändert. Danke aber ...
Sheli

Antworten:

115

Sie könnten Schnittstellen für Tierklassen (Klasse in der biologischen Bedeutung) erstellen, z. B. public interface Equidaefür Pferde und public interface AvialaeVögel (ich bin kein Biologe, daher können die Begriffe falsch sein).

Dann können Sie noch eine erstellen

public class Bird implements Avialae {
}

und

public class Horse implements Equidae {}

und auch

public class Pegasus implements Avialae, Equidae {}

Hinzufügen aus den Kommentaren:

Um doppelten Code zu reduzieren, können Sie eine abstrakte Klasse erstellen, die den größten Teil des allgemeinen Codes der Tiere enthält, die Sie implementieren möchten.

public abstract class AbstractHorse implements Equidae {}

public class Horse extends AbstractHorse {}

public class Pegasus extends AbstractHorse implements Avialae {}

Aktualisieren

Ich möchte noch ein Detail hinzufügen. Wie Brian bemerkt , wusste das OP dies bereits.

Ich möchte jedoch betonen, dass ich vorschlage, das Problem der "Mehrfachvererbung" mit Schnittstellen zu umgehen, und dass ich nicht empfehle, Schnittstellen zu verwenden, die bereits einen konkreten Typ darstellen (wie z. B. Bird), sondern eher ein Verhalten (auf das sich andere beziehen) Ententypisierung, was auch gut ist, aber ich meine nur: die biologische Klasse der Vögel, Avialae). Ich empfehle auch nicht, Schnittstellennamen zu verwenden, die mit einem Großbuchstaben 'I' beginnen, z. B. IBirdwas nur nichts darüber aussagt, warum Sie eine Schnittstelle benötigen. Das ist der Unterschied zu der Frage: Erstellen Sie die Vererbungshierarchie mithilfe von Schnittstellen, verwenden Sie bei Bedarf abstrakte Klassen, implementieren Sie bei Bedarf konkrete Klassen und verwenden Sie gegebenenfalls die Delegierung.

Moritz Petersen
quelle
9
Welches ... ist genau das, was die OP sagt, dass sie wissen, dass Sie im Q. tun können
Brian Roach
4
Da Pegasus bereits ein Pferd ist (das fliegt), denke ich, dass Sie mehr Code wiederverwenden könnten, wenn Sie Horse erweitern und Avialae implementieren.
Pablo Lozano
8
Ich bin mir nicht sicher, ich habe noch keinen Pegasus gesehen. In diesem Fall würde ich jedoch lieber ein verwenden AbstractHorse, mit dem auch Zebras oder andere pferdeartige Tiere gebaut werden können.
Moritz Petersen
5
@MoritzPetersen Wenn Sie wirklich Abstraktionen wiederverwenden und aussagekräftige Namen vergeben AbstractEquidaemöchten , ist dies wahrscheinlich besser geeignet als AbstractHorse. Es wäre seltsam, wenn ein Zebra ein abstraktes Pferd ausstrecken würde. Übrigens eine gute Antwort.
Afsantos
3
Das Implementieren von Ententypisierung würde auch das DuckImplementieren einer Klasse beinhalten Avialae?
Margarciaisaia
88

Es gibt zwei grundlegende Ansätze zum Kombinieren von Objekten:

  • Das erste ist Vererbung . Wie Sie bereits festgestellt haben, können Sie aufgrund der Vererbungsbeschränkungen hier nicht das tun, was Sie benötigen.
  • Der zweite ist Zusammensetzung . Da die Vererbung fehlgeschlagen ist, müssen Sie die Komposition verwenden.

Dies funktioniert so, dass Sie ein Tierobjekt haben. Innerhalb dieses Objekts fügen Sie dann weitere Objekte hinzu, die die gewünschten Eigenschaften und Verhaltensweisen angeben.

Beispielsweise:

  • Vogel erweitert Tier implementiert IFlier
  • Pferd erstreckt Tiergeräte IHerbivore, IQuadruped
  • Pegasus erstreckt Tiergeräte IHerbivore, IQuadruped, IFlier

Jetzt IFliersieht es einfach so aus:

 interface IFlier {
     Flier getFlier();
 }

BirdSieht also so aus:

 class Bird extends Animal implements IFlier {
      Flier flier = new Flier();
      public Flier getFlier() { return flier; }
 }

Jetzt haben Sie alle Vorteile der Vererbung. Sie können Code wiederverwenden. Sie können eine Sammlung von IFliers haben und alle anderen Vorteile des Polymorphismus usw. nutzen.

Sie haben jedoch auch die Flexibilität von Composition. Sie können so viele verschiedene Schnittstellen und zusammengesetzte Hintergrundklassen auf jeden Typ anwenden Animal- mit so viel Kontrolle, wie Sie über die Einrichtung der einzelnen Bits benötigen.

Strategiemuster alternativer Ansatz zur Komposition

Ein alternativer Ansatz, der davon abhängt, was und wie Sie tun, besteht darin, dass die AnimalBasisklasse eine interne Sammlung enthält, um die Liste der verschiedenen Verhaltensweisen zu führen. In diesem Fall verwenden Sie am Ende etwas, das näher am Strategiemuster liegt. Das bietet Vorteile in Bezug auf die Vereinfachung des Codes (zum Beispiel Horsemuss nichts über Quadrupedoder bekannt sein Herbivore), aber wenn Sie nicht auch den Schnittstellenansatz verwenden, verlieren Sie viele Vorteile des Polymorphismus usw.

Tim B.
quelle
Eine ähnliche Alternative könnte auch die Verwendung von Typklassen sein, obwohl diese in Java nicht so natürlich sind (Sie müssen Konvertermethoden verwenden usw.). Dieses Intro kann hilfreich sein, um auf die Idee zu kommen: typeclassopedia.bitbucket.org
Gábor Bakos
1
Dies ist eine viel bessere Lösung als der in der akzeptierten Antwort empfohlene Ansatz. Wenn ich beispielsweise später der Bird-Oberfläche "Schnabelfarbe" hinzufügen möchte, habe ich ein Problem. Pegasus ist ein Komposit, das Elemente von Pferden und Vögeln aufnimmt, aber weder vollständig von Pferd noch von Vogel. Die Verwendung von Komposition ist in diesem Szenario durchaus sinnvoll.
JDB erinnert sich noch an Monica
Aber getFlier()hat für jeden und jede Art von Vogel neu implementiert werden.
SMUsamaShah
1
@ LifeH2O Teilen Sie sie in Blöcke mit gemeinsam genutzten Funktionen auf und geben Sie ihnen diese. dh Sie haben könnten MathsTeacherund EnglishTeacherbeide erben Teacher, ChemicalEngineer, MaterialsEngineeretc vererben Engineer. Teacherund Engineerbeide implementieren Component. Das hat Persondann nur eine Liste von Components, und Sie können ihnen die richtigen Components dafür geben Person. dh person.getComponent(Teacher.class), person.getComponent(MathsTeacher.class)usw.
Tim B
1
Dies ist die beste Antwort. Als Faustregel steht die Vererbung für "ist" und eine Schnittstelle für "kann". Ein Pegasus ist ein Tier, das fliegen und laufen kann. Ein Vogel ist ein Tier, das fliegen kann. Ein Pferd ist ein Tier, das laufen kann.
Robear
43

Ich habe eine blöde Idee:

public class Pegasus {
    private Horse horseFeatures; 
    private Bird birdFeatures; 

   public Pegasus(Horse horse, Bird bird) {
     this.horseFeatures = horse;
     this.birdFeatures = bird;
   }

  public void jump() {
    horseFeatures.jump();
  }

  public void fly() {
    birdFeatures.fly();
  }
}
Pavel Janicek
quelle
24
Es wird funktionieren, aber ich mag diese Art von Ansatz (Wrappper) nicht, weil Pegasus dann ein Pferd zu haben scheint, stattdessen ist es ein Pferd.
Pablo Lozano
Danke dir. Ich konnte mir nicht helfen, die Idee zu veröffentlichen. Ich weiß irgendwie, dass es dumm ist, aber ich habe nicht gesehen, warum es dumm ist ...
Pavel Janicek
3
Es ist fast wie eine nicht gefundene Version des Kompositionsansatzes aus Tim Bs Antwort.
Stephan
1
Dies ist mehr oder weniger die akzeptierte Methode, obwohl Sie auch so etwas wie IJumps mit einer "Sprung" -Methode haben sollten, die von Horse and Pegasus implementiert wird, und IFlies mit einer "fly" -Methode, die von Bird und Pegasus implementiert wird.
MatsT
2
@Pablo nein, ein Pegasus hat Pferdefunktionen und hat Vogelfunktionen. +1 für die Antwort, da der Code im Gegensatz zu den klobigeren, klassenlaichenden und richtigen Java-Lösungen einfach gehalten wird.
JaneGoodall
25

Darf ich das Konzept der Ententypisierung vorschlagen ?

Höchstwahrscheinlich würden Sie dazu neigen, den Pegasus dazu zu bringen, eine Vogel- und eine Pferdeschnittstelle zu erweitern, aber die Eingabe von Enten legt tatsächlich nahe, dass Sie lieber Verhalten erben sollten . Wie bereits in den Kommentaren erwähnt, ist ein Pegasus kein Vogel, aber er kann fliegen. Ihr Pegasus sollte also lieber eine FlyableSchnittstelle erben und sagen wir eine GallopableSchnittstelle.

Diese Art von Konzept wird im Strategiemuster verwendet . Das gegebene Beispiel zeigt Ihnen , tatsächlich wie eine Ente erbt das FlyBehaviourund QuackBehaviourund dort noch Enten sein kann, zum Beispiel die RubberDuck, die nicht fliegen kann. Sie hätten die DuckErweiterung auch zu einer BirdKlasse machen können, aber dann hätten sie etwas Flexibilität aufgegeben, weil jeder Duckfliegen könnte, auch die Armen RubberDuck.

snrlx
quelle
19

Technisch gesehen können Sie jeweils nur eine Klasse erweitern und mehrere Schnittstellen implementieren. Wenn Sie jedoch die Softwareentwicklung in die Hand nehmen, würde ich eher eine problemspezifische Lösung vorschlagen, die im Allgemeinen nicht zu beantworten ist. Übrigens ist es eine gute OO-Praxis, konkrete Klassen nicht zu erweitern / nur abstrakte Klassen zu erweitern, um unerwünschtes Vererbungsverhalten zu verhindern - es gibt kein "Tier" und keine Verwendung eines Tierobjekts, sondern nur konkrete Tiere.

Smutje
quelle
13

In Java 8, das sich seit Februar 2014 noch in der Entwicklungsphase befindet, können Sie Standardmethoden verwenden , um eine Art C ++ - wie Mehrfachvererbung - zu erreichen. Sie können sich auch dieses Tutorial ansehen, das einige Beispiele zeigt, mit denen Sie leichter arbeiten können als mit der offiziellen Dokumentation.

GOTO 0
quelle
1
Beachten Sie jedoch, dass, wenn Ihr Vogel und Ihr Pferd beide eine Standardmethode haben, das Diamantproblem weiterhin auftritt und Sie es separat in Ihrer Pegasus-Klasse implementieren müssen (oder einen Compilerfehler erhalten).
Mikkel Løkke
@Mikkel Løkke: Die Pegasus-Klasse muss Überschreibungen für die mehrdeutigen Methoden definieren, kann sie jedoch implementieren, indem sie einfach an eine der Supermethoden (oder an beide in einer ausgewählten Reihenfolge) delegiert.
Holger
12

Es ist sicher, ein Pferd in einem Stall mit einer halben Tür zu halten, da ein Pferd nicht über eine halbe Tür gelangen kann. Deshalb habe ich einen Pferdehausdienst eingerichtet, der alle Gegenstände vom Typ Pferd akzeptiert und in einen Stall mit einer halben Tür stellt.

Ist ein Pferd wie ein Tier, das sogar ein Pferd fliegen kann?

Früher habe ich viel über Mehrfachvererbung nachgedacht, aber jetzt, da ich seit über 15 Jahren programmiere, ist es mir nicht mehr wichtig, Mehrfachvererbung zu implementieren.

Meistens, wenn ich versucht habe, mit einem Design umzugehen, das auf Mehrfachvererbung hinweist, habe ich später veröffentlicht, dass ich die Problemdomäne nicht verstanden habe.

ODER

Wenn es wie eine Ente aussieht und wie eine Ente quakt, aber Batterien benötigt, haben Sie wahrscheinlich die falsche Abstraktion .

Ian Ringrose
quelle
Wenn ich Ihre Analogie richtig lese, sagen Sie, dass Schnittstellen am Anfang großartig erscheinen, da Sie damit Designprobleme umgehen können. Sie können beispielsweise die API eines anderen verwenden, indem Sie Ihre Klassen über deren Schnittstellen zwingen. Aber nach einigen Jahren wurde Ihnen klar, dass das Problem zunächst schlechtes Design war.
CS
8

Java hat kein Mehrfachvererbungsproblem, da es keine Mehrfachvererbung hat. Dies ist beabsichtigt, um das eigentliche Problem der Mehrfachvererbung (das Diamantproblem) zu lösen.

Es gibt verschiedene Strategien zur Minderung des Problems. Das am schnellsten erreichbare ist das von Pavel vorgeschlagene zusammengesetzte Objekt (im Wesentlichen, wie C ++ damit umgeht). Ich weiß nicht, ob für die Zukunft von Java eine Mehrfachvererbung über C3-Linearisierung (oder ähnliches) geplant ist, aber ich bezweifle dies.

Wenn Ihre Frage akademisch ist, ist die richtige Lösung, dass Vogel und Pferd konkreter sind, und es ist falsch anzunehmen, dass ein Pegasus einfach ein Vogel und ein Pferd zusammen ist. Es wäre richtiger zu sagen, dass ein Pegasus bestimmte intrinsische Eigenschaften gemeinsam mit Vögeln und Pferden hat (das heißt, sie haben möglicherweise gemeinsame Vorfahren). Dies kann ausreichend modelliert werden, wie Moritz 'Antwort hervorhebt.

Mikkel Løkke
quelle
6

Ich denke, es hängt sehr stark von Ihren Bedürfnissen ab und davon, wie Ihre Tierklassen in Ihrem Code verwendet werden sollen.

Wenn Sie Methoden und Funktionen Ihrer Pferde- und Vogelimplementierungen in Ihrer Pegasus-Klasse nutzen möchten, können Sie Pegasus als Komposition aus einem Vogel und einem Pferd implementieren :

public class Animals {

    public interface Animal{
        public int getNumberOfLegs();
        public boolean canFly();
        public boolean canBeRidden();
    }

    public interface Bird extends Animal{
        public void doSomeBirdThing();
    }
    public interface Horse extends Animal{
        public void doSomeHorseThing();
    }
    public interface Pegasus extends Bird,Horse{

    }

    public abstract class AnimalImpl implements Animal{
        private final int numberOfLegs;

        public AnimalImpl(int numberOfLegs) {
            super();
            this.numberOfLegs = numberOfLegs;
        }

        @Override
        public int getNumberOfLegs() {
            return numberOfLegs;
        }
    }

    public class BirdImpl extends AnimalImpl implements Bird{

        public BirdImpl() {
            super(2);
        }

        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return false;
        }

        @Override
        public void doSomeBirdThing() {
            System.out.println("doing some bird thing...");
        }

    }

    public class HorseImpl extends AnimalImpl implements Horse{

        public HorseImpl() {
            super(4);
        }

        @Override
        public boolean canFly() {
            return false;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }

        @Override
        public void doSomeHorseThing() {
            System.out.println("doing some horse thing...");
        }

    }

    public class PegasusImpl implements Pegasus{

        private final Horse horse = new HorseImpl();
        private final Bird bird = new BirdImpl();


        @Override
        public void doSomeBirdThing() {
            bird.doSomeBirdThing();
        }

        @Override
        public int getNumberOfLegs() {
            return horse.getNumberOfLegs();
        }

        @Override
        public void doSomeHorseThing() {
            horse.doSomeHorseThing();
        }


        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }
    }
}

Eine andere Möglichkeit ist die Verwendung eines Entity-Component-System- Ansatzes anstelle der Vererbung zur Definition Ihrer Tiere. Dies bedeutet natürlich, dass Sie keine einzelnen Java-Klassen der Tiere haben, sondern diese nur durch ihre Komponenten definiert werden.

Ein Pseudocode für einen Entity-Component-System-Ansatz könnte folgendermaßen aussehen:

public void createHorse(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 4);
    entity.setComponent(CAN_FLY, false);
    entity.setComponent(CAN_BE_RIDDEN, true);
    entity.setComponent(SOME_HORSE_FUNCTIONALITY, new HorseFunction());
}

public void createBird(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 2);
    entity.setComponent(CAN_FLY, true);
    entity.setComponent(CAN_BE_RIDDEN, false);
    entity.setComponent(SOME_BIRD_FUNCTIONALITY, new BirdFunction());
}

public void createPegasus(Entity entity){
    createHorse(entity);
    createBird(entity);
    entity.setComponent(CAN_BE_RIDDEN, true);
}
Balder
quelle
4

Sie können eine Schnittstellenhierarchie haben und dann Ihre Klassen von ausgewählten Schnittstellen aus erweitern:

public interface IAnimal {
}

public interface IBird implements IAnimal {
}

public  interface IHorse implements IAnimal {
}

public interface IPegasus implements IBird,IHorse{
}

und definieren Sie dann Ihre Klassen nach Bedarf, indem Sie eine bestimmte Schnittstelle erweitern:

public class Bird implements IBird {
}

public class Horse implements IHorse{
}

public class Pegasus implements IPegasus {
}
richardtz
quelle
1
Oder er kann einfach: Öffentliche Klasse Pegasus erweitert Animal Implements Horse, Bird
Batman
OP ist sich dieser Lösung bereits bewusst und sucht nach einer alternativen Möglichkeit, dies zu tun
Yogesh,
@ Batman, natürlich kann er, aber wenn er die Hierarchie erweitern will, müsste er diesem Ansatz folgen
richardtz
IBirdund IHorsesollte IAnimalanstelle vonAnimal
oliholz
@ Yogesh, du hast recht. Ich habe den Ort übersehen, an dem er es angibt. Was soll ich als "Neuling" jetzt tun, die Antwort löschen oder dort lassen? Danke.
Richardtz
4

Ähm, Ihre Klasse kann die Unterklasse für nur eine andere sein, aber Sie können trotzdem so viele Schnittstellen implementieren, wie Sie möchten.

Ein Pegasus ist in der Tat ein Pferd (es ist ein Sonderfall eines Pferdes), das fliegen kann (was die "Fähigkeit" dieses besonderen Pferdes ist). Auf der anderen Seite kann man sagen, dass der Pegasus ein Vogel ist, der laufen kann und vierbeinig ist - alles hängt davon ab, wie einfach es für Sie ist, den Code zu schreiben.

Wie in Ihrem Fall können Sie sagen:

abstract class Animal {
   private Integer hp = 0; 
   public void eat() { 
      hp++; 
   }
}
interface AirCompatible { 
   public void fly(); 
}
class Bird extends Animal implements AirCompatible { 
   @Override
   public void fly() {  
       //Do something useful
   }
} 
class Horse extends Animal {
   @Override
   public void eat() { 
      hp+=2; 
   }

}
class Pegasus extends Horse implements AirCompatible {
   //now every time when your Pegasus eats, will receive +2 hp  
   @Override
   public void fly() {  
       //Do something useful
   }
}
András Iványi
quelle
3

Schnittstellen simulieren keine Mehrfachvererbung. Java-Ersteller hielten Mehrfachvererbung für 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.

Aus meiner Sicht kann man also nicht in das Diamantproblem geraten.

Karthik Surianarayanan
quelle
Es ist nicht falsch, genauso wie direkte Speicherzeiger, vorzeichenlose Typen und Operatorüberladung nicht falsch sind. Es ist einfach nicht notwendig, die Arbeit zu erledigen. Java wurde als schlanke Sprache entwickelt, die leicht zu erlernen ist. Machen Sie sich nichts aus und hoffen Sie auf das Beste, dies ist ein Wissensgebiet, keine Vermutungen.
Gimby
3
  1. Definieren Sie Schnittstellen zum Definieren der Funktionen. Sie können mehrere Schnittstellen für mehrere Funktionen definieren. Diese Funktionen können von bestimmten Tieren oder Vögeln implementiert werden .
  2. Verwenden Sie die Vererbung , um Beziehungen zwischen Klassen herzustellen, indem Sie nicht statische und nicht öffentliche Daten / Methoden gemeinsam nutzen.
  3. Verwenden Sie Decorator_pattern , um Funktionen dynamisch hinzuzufügen. Auf diese Weise können Sie die Anzahl der Vererbungsklassen und -kombinationen reduzieren.

Schauen Sie sich zum besseren Verständnis das folgende Beispiel an

Wann sollte das Dekorationsmuster verwendet werden?

Ravindra Babu
quelle
2

Um die Komplexität zu verringern und die Sprache zu vereinfachen, wird die Mehrfachvererbung in Java nicht unterstützt.

Stellen Sie sich ein Szenario vor, in dem A, B und C drei Klassen sind. Die C-Klasse erbt die Klassen A und B. Wenn A- und B-Klassen dieselbe Methode haben und Sie sie vom untergeordneten Klassenobjekt aufrufen, besteht Mehrdeutigkeit beim Aufrufen der Methode der A- oder B-Klasse.

Da Kompilierungsfehler besser sind als Laufzeitfehler, rendert Java Kompilierungsfehler, wenn Sie zwei Klassen erben. Unabhängig davon, ob Sie dieselbe oder eine andere Methode verwenden, tritt jetzt ein Fehler bei der Kompilierung auf.

class A {  
    void msg() {
        System.out.println("From A");
    }  
}

class B {  
    void msg() {
        System.out.println("From B");
    }  
}

class C extends A,B { // suppose if this was possible
    public static void main(String[] args) {  
        C obj = new C();  
        obj.msg(); // which msg() method would be invoked?  
    }
} 
Syeful Islam
quelle
2

Um das Problem der Mehrfachvererbung in Java zu lösen, wird die → Schnittstelle verwendet

J2EE (Core JAVA) Notizen von Herrn KVR Seite 51

Tag - 27

  1. Schnittstellen werden grundsätzlich zur Entwicklung benutzerdefinierter Datentypen verwendet.
  2. In Bezug auf Schnittstellen können wir das Konzept der Mehrfachvererbung erreichen.
  3. Mit Schnittstellen können wir das Konzept des Polymorphismus und der dynamischen Bindung erreichen und somit die Leistung eines JAVA-Programms in Bezug auf Speicherplatz und Ausführungszeit verbessern.

Eine Schnittstelle ist ein Konstrukt, das die Sammlung rein undefinierter Methoden enthält, oder eine Schnittstelle ist eine Sammlung rein abstrakter Methoden.

[...]

Tag - 28:

Syntax-1 zum Wiederverwenden der Funktionen von Schnittstellen zur Klasse:

[abstract] class <clsname> implements <intf 1>,<intf 2>.........<intf n>
{
    variable declaration;
    method definition or declaration;
};

In der obigen Syntax repräsentiert clsname den Namen der Klasse, die die Features von 'n' Anzahl der Schnittstellen erbt. 'Implements' ist ein Schlüsselwort, mit dem die Funktionen von Schnittstellen an eine abgeleitete Klasse geerbt werden.

[...]

Syntax-2, die 'n' Anzahl von Schnittstellen an eine andere Schnittstelle erbt:

interface <intf 0 name> extends <intf 1>,<intf 2>.........<intf n>
{     
    variable declaration cum initialization;
    method declaration;
};

[...]

Syntax-3:

[abstract] class <derived class name> extends <base class name> implements <intf 1>,<intf 2>.........<intf n>
{
  variable declaration;
  method definition or declaration;
};
Genial
quelle