Java ist eine objektorientierte Sprache. Das bedeutet, dass in Java alles aus Klassen und ihren Objekten besteht und den Paradigmen von OOP (objektorientierte Programmierung) folgt. Ein solches Paradigma ist die Vererbung, ein Mechanismus in Java, der es einer Klasse ermöglicht, die Features (Felder und Methoden) einer anderen Klasse zu erben. Vereinfacht ausgedrückt bedeutet Vererbung in Java das Erstellen neuer Klassen auf der Grundlage vorhandener Klassen. Vererbung in Java - 1

Hauptakteure der Vererbung in Java

  • Unter Vererbung versteht man das Konzept, dass eine Klasse die Eigenschaften und Methoden ihrer übergeordneten Klasse (der Klasse, von der sie erbt) teilweise oder vollständig wiederholen kann.
  • Eine untergeordnete Klasse, Unterklasse, erweiterte Klasse oder abgeleitete Klasse ist eine Klasse, die von einer anderen Klasse erbt.
  • Eine übergeordnete Klasse, Superklasse oder Basisklasse ist eine Klasse, die über eine Reihe von Funktionen verfügt, und diese Funktionen können von einer anderen Klasse (untergeordneten Klasse) übergeben (geerbt) werden.
  • Durch das Überschreiben einer Methode wird das Verhalten einer abgeleiteten Klassenmethode geändert. Dabei handelt es sich in der Regel um ein spezifischeres, verfeinertes Verhalten. Wenn Sie eine Methode im Erben überschreiben, die sich bereits in der übergeordneten Klasse befindet, ersetzt sie gewissermaßen die übergeordnete Methode.
  • Eine Klasse kann nur eine Vorfahrenklasse haben, aber jede Klasse kann viele „Kinder“ haben.

Wie es funktioniert

Die Vererbungskette verläuft von der abstraktesten zur konkreteren Klasse. Das heißt, die Superklasse ist die abstrakteste in der Klassenkette. Oft wird sie als abstrakt bezeichnet (Basisklasse, die keine Implementierung erfordert). Alle weiteren Klassen sind spezifischer. Es gibt zum Beispiel eine Klasse namens „Gadget“. Es kann ein Feld (oder Zustand) „Gewicht“, Feldbatteriekapazität, Feldladezustand und Methoden (oder Verhalten) „Arbeit“ und Laden haben. In diesem Fall können Methoden abstrakt sein, das heißt, sie haben keine spezifische Implementierung. Wir können zwar nicht sagen, um welche Art von Gerät es sich handelt, aber es handelt sich absolut um jedes wiederaufladbare Gerät. Erstellen wir eine Phone-Unterklasse der Gadget-Klasse. Es muss das Gewicht und die Batterie nicht mehr neu definieren, sondern übernimmt diese einfach vom abstrakten Gerät. Das Verhalten der Arbeit muss jedoch geklärt werden. Sie können auch weitere Felder „Bildschirmdiagonale“, Anschlüsse usw. hinzufügen. Sie können eine neue Methode „Betriebssystem aktualisieren“ hinzufügen. Als nächstes können wir zwei weitere Klassen erstellen und beide werden von Phone, Android und iPhone geerbt. Beide Klassen erben alle Felder und Methoden des Gadgets und des Smartphones, und die Methoden können überschrieben werden. Die erste Klasse benötigt ein Feld „Markenname“, während das iPhone dieses Feld nicht benötigt, da nur ein Unternehmen solche Smartphones herstellt.
class Gadget {}
}
//subclass of Gadget class
class Phone extends Gadget {}
//subclass of Phone class
class IPhone extends Phone {}
//subclass of Phone class
class AndroidPhone extends Phone {}
Eine untergeordnete Klasse erbt alle öffentlichen und geschützten Mitglieder der übergeordneten Klasse. Es spielt keine Rolle, in welchem ​​Paket sich die Unterklasse befindet. Wenn sich die untergeordnete Klasse im selben Paket wie die übergeordnete Klasse befindet, erbt sie auch die paketprivaten Mitglieder der übergeordneten Klasse. Sie können geerbte Mitglieder unverändert verwenden, sie ersetzen, ausblenden oder neue Mitglieder hinzufügen:
  • Sie können geerbte Felder wie alle anderen Felder direkt verwenden.
  • Sie können in der untergeordneten Klasse ein Feld deklarieren, das denselben Namen wie in der übergeordneten Klasse hat. Es verheimlicht es (es ist also besser, es nicht zu tun).
  • Sie können neue Felder in der untergeordneten Klasse deklarieren (solche, die die übergeordnete Klasse nicht hat).
  • Geerbte Methoden können direkt ohne Überschreibung in der abgeleiteten Klasse verwendet werden.
  • Sie können auch eine neue Instanzmethode in einer Unterklasse schreiben, die dieselbe Signatur wie eine Methode in der übergeordneten Klasse hat. Dieses Verfahren überschreibt es.
  • Sie können in der untergeordneten Klasse neue Methoden deklarieren, die in der übergeordneten Klasse nicht deklariert wurden.
  • Sie können einen Unterklassenkonstruktor schreiben, der den Oberklassenkonstruktor entweder implizit oder mit dem Schlüsselwort super aufruft.

Beispiel

Erstellen wir eine Basisklasse „MusicalInstrument“ mit den Feldern „weight“ und „trade“ sowie einer work()- Methode. Wir definieren auch einen Konstruktor.
public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
Es ist völlig unklar, um welche Art von Musikinstrument es sich handelt und wie man es spielt. Lassen Sie uns ein spezifischeres Instrument erstellen, die Geige. Es verfügt über dieselben Felder wie im Musikinstrument (sie werden im Konstruktor mit dem Schlüsselwort super aufgerufen). Wir können auch die Arbeitsmethode überschreiben und eine Methode zum Setzen der Geigensaite für Saite erstellen.
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
Erstellen wir eine Demo- Klasse, um die Violin- Klasse zu testen und genau zu sehen, wie die Vererbung funktioniert.
public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
In diesem Fall sieht die Ausgabe des Programms wie folgt aus:
Ich stimme die 1. Saite... Ich stimme die 2. Saite... Ich stimme die 3. Saite... Ich stimme die 4. Saite... Die Geige spielt
Das heißt, wenn in der untergeordneten Klasse eine überschriebene Methode vorhanden ist, wird die Vorfahrenmethode nicht mehr aufgerufen. Was ist, wenn es nicht da ist? Das heißt, die Violinklasse sieht so aus:
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override


 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
Die Ausgabe ist:
Ich stimme die 1. Saite... Ich stimme die 2. Saite... Ich stimme die 3. Saite... Ich stimme die 4. Saite... Das Instrument spielt...
Das heißt, die Vorfahrenmethode wird automatisch aufgerufen. Übrigens kann die untergeordnete Klasse über den Vorfahren definiert werden, um ein Upcasting durchzuführen:
Parent parent = new Child()
Diese Initialisierung wird verwendet, um nur auf die in der übergeordneten Klasse vorhandenen Mitglieder und die überschriebenen Methoden zuzugreifen. In unserem Beispiel wäre es:
public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
In einem solchen Fall können wir die Geigenmethode nicht konfigurieren. Gleichzeitig wird jedoch die work()- Methode der Nachfolgeklasse aufgerufen, sofern diese vorhanden ist.

Die Klassenhierarchie der Java-Plattform

In Java besteht alles aus Klassen und diese sind einer Hierarchie untergeordnet. Es stellt sich die Frage: Gibt es eine Klasse, von der alle anderen geerbt werden? Die Antwort lautet: Ja, tatsächlich existiert eine solche Klasse. Und es heißt einfach Object . Die Object- Klasse aus dem java.lang-Paket definiert und implementiert das gemeinsame Verhalten aller Klassen, einschließlich der von Ihnen erstellten. In der Java-Plattform leiten sich viele Klassen direkt von Object ab , andere Klassen leiten sich von einigen dieser Klassen ab und so weiter und bilden so eine Klassenhierarchie.

Arten der Vererbung in Java

Lassen Sie uns einige Arten der Vererbung in Java hervorheben. 1. Einzelvererbung Dieser Typ ist genau wie in unserem Beispiel oben: Unterklassen erben die Funktionen einer Superklasse. In der Abbildung unten dient Klasse A als Basisklasse für die abgeleitete Klasse B. 2. Mehrstufige Vererbung Dies ist nur eine Vererbungskette, das heißt, es gibt eine Basisklasse A, von dieser wird Klasse B geerbt und Klasse C wird von Klasse B geerbt. In Java kann eine Klasse nicht direkt auf die Mitglieder der Großelternklasse zugreifen. 3. Hierarchische Vererbung Bei der hierarchischen Vererbung dient eine Klasse als Superklasse (Basisklasse) für mehr als eine Unterklasse. Oben haben wir ein Beispiel für die Phone-Klasse gegeben, die zwei „Kinder“ haben kann – AndroidPhone und IPhone.
class A {
    public void printA() {
System.out.println("A");
 }
}

class B extends A {
    public void printB() {
 System.out.println(" B"); }
}

class C extends A {
    public void printC() {
System.out.println("C");
}
}

class D extends A {
    public void printD() {
System.out.println("D");
 }
}

public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();

        C objC = new C();
        objC.printA();
        objC.printC();

        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
Die Ausgabe ist:
A B A C A D
4. Mehrfachvererbung, also das Vorhandensein mehrerer Vorfahren ... aber halt, die klassische Mehrfachvererbung wird in Java nicht unterstützt. Bis zu einem gewissen Grad kann es nicht mithilfe von Klassen, sondern mithilfe von Schnittstellen implementiert werden.
interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }

   @Override
   public void printA() {
   }

   @Override
   public void printB() {
   }
}