Java-Vererbung


Konzept der Vererbung

Vererbung ist ein Eckpfeiler der objektorientierten Programmiertechnologie von Java, da sie die Erstellung hierarchischer Klassen ermöglicht.

Vererbung bedeutet, dass eine Unterklasse die Eigenschaften und Verhaltensweisen einer Elternklasse erbt, sodass Objekte (Instanzen) der Unterklasse über die Instanzfelder und Methoden der Elternklasse verfügen, oder dass die Unterklasse Methoden von der Elternklasse erbt, wodurch die Unterklasse dieselben Verhaltensweisen wie die Elternklasse erhält.

Vererbung im Alltag:

Kaninchen und Schafe gehören zur Klasse der Pflanzenfresser, während Löwen und Leoparden zur Klasse der Fleischfresser gehören.

Pflanzenfresser und Fleischfresser gehören ebenfalls zur Klasse der Tiere.

Daher ist die Beziehung, die durch Vererbung erfüllt werden muss: is-a. Die Elternklasse ist allgemeiner, und die Unterklasse ist spezifischer.

Obwohl Pflanzenfresser und Fleischfresser beide zu den Tieren gehören, gibt es Unterschiede in ihren Attributen und Verhaltensweisen. Daher hat eine Unterklasse sowohl die allgemeinen Merkmale der Elternklasse als auch ihre eigenen Merkmale.

Format der Klassenvererbung

In Java kann man das Schlüsselwort extends verwenden, um zu deklarieren, dass eine Klasse von einer anderen Klasse erbt. Die allgemeine Form ist wie folgt:

Format der Klassenvererbung

classElternklasse{ } classUnterklasseextendsElternklasse{ }

Warum brauchen wir Vererbung?

Als Nächstes veranschaulichen wir diese Notwendigkeit an einem Beispiel.

Entwickeln Sie eine Tierklasse, in der die Tiere ein Pinguin und eine Maus sind, mit den folgenden Anforderungen:

  • Pinguin: Attribute (name, id), Methoden (eat, sleep, self-introduction)
  • Maus: Attribute (name, id), Methoden (eat, sleep, self-introduction)

Klasse Penguin:

public class Penguin { private String name; private int id; public Penguin(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"frisst"); } public void sleep(){ System.out.println(name+"schläft"); } public void introduction() { System.out.println("Hallo zusammen! Ich bin" + id + "Number" + name + "."); } }

Mouse-Klasse:

public class Mouse { private String name; private int id; public Mouse(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"frisst"); } public void sleep(){ System.out.println(name+"schläft"); } public void introduction() { System.out.println("Hallo zusammen! Ich bin" + id + "Number" + name + "."); } }

An diesen beiden Codeabschnitten lässt sich erkennen, dass der Code dupliziert ist, wodurch der Code groß und aufgebläht wird und die Wartbarkeit gering ist (hauptsächlich weil bei späteren Änderungen viele Teile des Codes geändert werden müssen, was fehleranfällig ist). Um das Problem dieser beiden Codeabschnitte grundlegend zu lösen, ist Vererbung erforderlich. Extrahiere die gemeinsamen Teile der beiden Codeabschnitte, um eine Elternklasse zu bilden:

Gemeinsame Elternklasse:

public class Animal { private String name; private int id; public Animal(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"frisst"); } public void sleep(){ System.out.println(name+"schläft"); } public void introduction() { System.out.println("Hallo zusammen! Ich bin" + id + "Number" + name + "."); } }

Diese Animal-Klasse kann als Elternklasse dienen. Nachdem die Klassen Penguin und Mouse von dieser Klasse erben, besitzen sie die Attribute und Methoden der Elternklasse. Die Unterklassen haben keinen doppelten Code mehr, die Wartbarkeit ist verbessert, der Code ist prägnanter und die Wiederverwendbarkeit des Codes ist verbessert (Wiederverwendbarkeit bedeutet hauptsächlich, dass er mehrfach verwendet werden kann, ohne denselben Code erneut zu schreiben). Code nach der Vererbung:

Klasse Penguin:

public class Penguin extends Animal { public Penguin(String myName, int myid) { super(myName, myid); } }

Mouse-Klasse:

public class Mouse extends Animal { public Mouse(String myName, int myid) { super(myName, myid); } }

Arten der Vererbung

Beachten Sie, dass Java keine Mehrfachvererbung unterstützt, aber die mehrstufige Vererbung unterstützt.


Merkmale der Vererbung

  • Eine Unterklasse besitzt alle nicht-privaten Attribute und Methoden der Elternklasse.

  • Eine Unterklasse kann eigene Attribute und Methoden haben, was bedeutet, dass eine Unterklasse die Elternklasse erweitern kann.

  • Eine Unterklasse kann die Methoden der Elternklasse auf ihre eigene Weise implementieren.

  • Die Java-Vererbung ist eine Einfachvererbung, aber mehrstufige Vererbung ist möglich. Einfachvererbung bedeutet, dass eine Unterklasse nur von einer Elternklasse erben kann. Mehrstufige Vererbung bedeutet zum Beispiel, dass Klasse B von Klasse A erbt und Klasse C von Klasse B erbt. Bezogen auf die Beziehungen ist Klasse B die Elternklasse von Klasse C und Klasse A die Elternklasse von Klasse B. Dies ist ein Merkmal, das die Java-Vererbung von der C++-Vererbung unterscheidet.

  • Sie erhöht die Kopplung zwischen Klassen (ein Nachteil der Vererbung; hohe Kopplung macht die Verbindungen zwischen Code enger und die Code-Unabhängigkeit schwächer).


Vererbungsschlüsselwörter

Vererbung kann mit den beiden Schlüsselwörtern extends und implements implementiert werden. Außerdem erben alle Klassen von java.lang.Object. Wenn eine Klasse diese beiden Vererbungsschlüsselwörter nicht verwendet, erbt sie standardmäßig von Object (diese Klasse ist imjava.lang-Paket, daher ist es nicht nötig,importzu verwenden) Vorfahrenklasse.

extends-Schlüsselwort

In Java ist die Klassenvererbung Einfachvererbung; das heißt, eine Unterklasse kann nur eine Elternklasse haben, daher kann extends nur eine Klasse erben.

extends-Schlüsselwort

public class Animal { private String name; private int id; public Animal(String myName, int myid) { //Eigenschaftswerte initialisieren } public void eat() { //Spezifische Implementierung der eat-Methode } public void sleep() { //Spezifische Implementierung der sleep-Methode } } public class Penguin extends Animal{ }

implements-Schlüsselwort

Die Verwendung des implements-Schlüsselworts kann Java indirekt die Merkmale der Mehrfachvererbung verleihen. Es wird verwendet, wenn eine Klasse Schnittstellen erbt, und sie kann gleichzeitig mehrere Schnittstellen erben (Schnittstellen werden durch Kommas getrennt).

implements-Schlüsselwort

public interface A { public void eat(); public void sleep(); } public interface B { public void show(); } public class C implements A,B { }

super- und this-Schlüsselwörter

super-Schlüsselwort:Wir können das super-Schlüsselwort verwenden, um auf Mitglieder der Elternklasse zuzugreifen; es wird verwendet, um auf die Elternklasse des aktuellen Objekts zu verweisen.

this-Schlüsselwort:Eine Referenz auf sich selbst, die auf das aktuelle Objekt verweist, d. h. auf die Objektinstanz, zu der die aktuelle Methode oder der aktuelle Konstruktor gehört.

Beispiel

class Animal { void eat() { System.out.println("animal : eat"); } } class Dog extends Animal { void eat() { System.out.println("dog : eat"); } void eatTest() { this.eat(); //this ruft seine eigene Methode auf super.eat(); //super ruft die Methode der Elternklasse auf } } public class Test { public static void main(String[] args) { Animal a = new Animal(); a.eat(); Dog d = new Dog(); d.eatTest(); } }

Das Ausgabeergebnis ist:

animal : eat
dog : eat
animal : eat

final-Schlüsselwort

final kann verwendet werden, um Variablen (einschließlich Klassenattribute, Objektattribute, lokale Variablen und formale Parameter), Methoden (einschließlich Klassenmethoden und Objektmethoden) und Klassen zu modifizieren.

final bedeutet "final".

Die Verwendung des Schlüsselworts final zum Deklarieren einer Klasse definiert die Klasse als eine finale Klasse, die nicht vererbt werden kann; oder es wird verwendet, um Methoden zu modifizieren, und solche Methoden können nicht von Unterklassen überschrieben werden:

  • Eine Klasse deklarieren:

    final class 类名 {//类体}
  • Eine Methode deklarieren:

    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

Hinweis:In einer mit final definierten Klasse sind ihre Attribute und Methoden nicht final.


Konstruktor

Eine Unterklasse erbt nicht den Konstruktor der Elternklasse (Konstruktionsmethode oder Konstruktorfunktion); sie ruft ihn lediglich auf (implizit oder explizit). Wenn der Konstruktor der Elternklasse Parameter hat, dann müssen Sie im Konstruktor der Unterklasse explizit dassuperSchlüsselwort verwenden, um den Konstruktor der Elternklasse mit einer geeigneten Parameterliste aufzurufen.

Wenn der Konstruktor der Elternklasse keine Parameter hat, dann ist es im Konstruktor der Unterklasse nicht nötig, dassuperSchlüsselwort zu verwenden, um den Konstruktor der Elternklasse aufzurufen; das System ruft automatisch den parameterlosen Konstruktor der Elternklasse auf.

Beispiel

class SuperClass { private int n; //Parameterloser Konstruktor public SuperClass() { System.out.println("SuperClass()"); } //Konstruktor mit Parametern public SuperClass(int n) { System.out.println("SuperClass(int n)"); this.n = n; } } //SubClass-Klassenvererbung class SubClass extends SuperClass { private int n; //Konstruktor ohne Argumente: ruft automatisch den Konstruktor ohne Argumente der Elternklasse auf public SubClass() { System.out.println("SubClass()"); } //Konstruktor mit Parametern: ruft den Konstruktor der Elternklasse mit Parametern auf public SubClass(int n) { super(300); System.out.println("SubClass(int n): " + n); this.n = n; } } //SubClass2-Klassenvererbung class SubClass2 extends SuperClass { private int n; //Konstruktor ohne Argumente: ruft den Konstruktor der Elternklasse mit Parametern auf public SubClass2() { super(300); System.out.println("SubClass2()"); } //Konstruktor mit Parametern: ruft automatisch den parameterlosen Konstruktor der Elternklasse auf public SubClass2(int n) { System.out.println("SubClass2(int n): " + n); this.n = n; } } public class TestSuperSub { public static void main(String[] args) { System.out.println("------Vererbung der Klasse SubClass------"); SubClass sc1 = new SubClass(); SubClass sc2 = new SubClass(100); System.out.println("------Vererbung der Klasse SubClass2------"); SubClass2 sc3 = new SubClass2(); SubClass2 sc4 = new SubClass2(200); } }

Das Ausgabeergebnis ist:

------SubClass 类继承------
SuperClass()
SubClass()
SuperClass(int n)
SubClass(int n): 100
------SubClass2 类继承------
SuperClass(int n)
SubClass2()
SuperClass()
SubClass2(int n): 200
Andere Erweiterungen