In „Think in Java“ gibt es ein Sprichwort: Die Wiederverwendung von Code ist eine der vielen auffälligen Funktionen von Java. Aber damit eine Sprache höchst revolutionär ist, reicht es nicht aus, Code kopieren und ändern zu können; sie muss auch mehr können. Das Auffälligste an diesem Satz ist „Code so weit wie möglich wiederverwenden“. Jetzt werde ich eine Möglichkeit vorstellen, Code wiederzuverwenden, was auch eines der drei Hauptmerkmale von Java ist . Eins---Vererbung.
Vererbung
Bevor wir es erklären, werfen wir einen Blick auf ein Beispiel. Dieses Beispiel stammt aus dem vorherigen Blogbeitrag (Java-Verbesserung – Verständnis der Kapselung der drei Hauptfunktionen von Java).
Von hier aus können wir sehen, dass die Klassen „Ehefrau“ und „Ehemann“ bis auf ihre jeweiligen Ehemänner und Ehefrauen alle gleich sind. Als Programmierer, der die Wiederverwendung von Code maximieren möchte, können wir das tun. Wenn es eine andere Herrin, Herrin, Herrin oder Herrin gibt ... (ich gehe zu weit), müssen wir es so schreiben? Wie erreichen wir also die Wiederverwendbarkeit dieser Klassen? Nutzen Sie die Erbschaft! !
Verlassen wir zunächst die Welt der Softwareprogrammierung. Aus gesundem Menschenverstand wissen wir, dass Ehemänner, Ehefrauen, Geliebte, Geliebte ... sie alle Menschen sind und einige Dinge gemeinsam haben, wie z B. Name, Alter, Geschlecht, Kopf usw., und sie sind alle in der Lage zu essen, zu gehen, zu sprechen und andere übliche Verhaltensweisen zu zeigen. Von hier aus können wir also feststellen, dass sie alle menschliche Eigenschaften und Verhaltensweisen besitzen und diese Eigenschaften und Verhaltensweisen auch erben Verhaltensweisen von Menschen.
Aus dem oben Gesagten können wir grundsätzlich verstehen, dass Vererbung eine Technologie ist, die die Definition einer vorhandenen Klasse als Grundlage für die Erstellung einer neuen Klasse verwendet Neue Funktionen Sie können auch die Funktionen der übergeordneten Klasse verwenden, die übergeordnete Klasse jedoch nicht selektiv erben. Durch die Verwendung der Vererbung können wir vorherigen Code sehr bequem wiederverwenden, was die Entwicklungseffizienz erheblich verbessern kann.
Nachdem wir die Vererbung für Ehefrau und Ehemann verwendet haben, können wir nicht nur die Codemenge reduzieren, sondern auch ihre Beziehung klar erkennen.
Vererbung beschreibt die „ist-a“-Beziehung. Wenn es zwei Objekte A und B gibt und dies als „A ist B“ beschrieben werden kann, kann dies bedeuten, dass A B erbt, während B The vererbt Der Nachfolger wird als übergeordnete Klasse oder Superklasse bezeichnet, und der Nachfolger wird als Unterklasse oder abgeleitete Klasse bezeichnet.
Tatsächlich ist der Nachfolger eine Spezialisierung des Geerbten. Zusätzlich zu den Eigenschaften des Geerbten weist er auch seine eigenen einzigartigen Eigenschaften auf. Katzen haben beispielsweise Eigenschaften, die andere Tiere nicht haben, wie zum Beispiel das Fangen von Mäusen und das Klettern auf Bäume. Gleichzeitig kann der Erbe in der Erbschaftsbeziehung das Geerbte vollständig ersetzen, aber nicht umgekehrt. Wir können beispielsweise sagen, dass eine Katze ein Tier ist, aber wir können nicht sagen, dass das Tier tatsächlich eine Katze ist Der Grund, warum wir dies „Aufwärtstransformation“ nennen, wird im Folgenden vorgestellt.
Es stimmt, dass Vererbung definiert, wie Klassen zueinander in Beziehung stehen und Merkmale teilen. Für mehrere identische oder bekannte Klassen können wir ihre gemeinsamen Verhaltensweisen oder Attribute abstrahieren und sie als übergeordnete Klasse oder Superklasse definieren und diese Klassen dann verwenden, um die übergeordnete Klasse zu erben. Sie können nicht nur die Eigenschaften und Methoden der übergeordneten Klasse haben Sie können auch Ihre eigenen einzigartigen Eigenschaften oder Methoden definieren.
Gleichzeitig müssen Sie sich bei der Verwendung der Vererbung drei Sätze merken:
1. Die Unterklasse verfügt über die nicht privaten Attribute und Methoden der übergeordneten Klasse.
2. Unterklassen können ihre eigenen Attribute und Methoden haben, dh Unterklassen können übergeordnete Klassen erweitern.
3. Unterklassen können die Methoden der übergeordneten Klasse auf ihre eigene Weise implementieren. (Später eingeführt).
Zusammenfassend lässt sich sagen, dass die Verwendung der Vererbung nicht nur die gemeinsamen Attribute aller Unterklassen in die übergeordnete Klasse einfügt, um eine Codefreigabe zu erreichen und Duplikate zu vermeiden, sondern auch die geerbte Implementierung relativ einfach ändern und erweitern kann .
Es stimmt, dass diese drei Dinge bei der Vererbung unverzichtbar sind: Konstruktor, geschütztes Schlüsselwort und Aufwärtstransformation.
Konstrukteur
Aus dem oben Gesagten wissen wir, dass Unterklassen die Attribute und Methoden von übergeordneten Klassen erben können. Zusätzlich zu diesen privaten Klassen gibt es noch eine weitere Sache, die Unterklassen nicht erben können: Konstruktoren. Der Konstruktor kann nur aufgerufen und nicht vererbt werden. Um den Konstruktor der übergeordneten Klasse aufzurufen, können wir super() verwenden.
Für Unterklassen ist die korrekte Initialisierung ihres Konstruktors sehr wichtig, und zwar nur dann, wenn es nur eine Methode gibt, die dies sicherstellen kann: den Aufruf des Konstruktors der übergeordneten Klasse im Konstruktor, um die Initialisierung abzuschließen, und die übergeordnete Der Klassenkonstruktor verfügt über alle erforderlichen Kenntnisse und Fähigkeiten, um die Initialisierung der übergeordneten Klasse durchzuführen.
public class Person { protected String name; protected int age; protected String sex; Person(){ System.out.println("Person Constrctor..."); } } public class Husband extends Person{ private Wife wife; Husband(){ System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor... Husband Constructor...
Aus diesem Beispiel ist ersichtlich, dass sich der Konstruktionsprozess von der übergeordneten Klasse „nach außen“ ausbreitet, dh ausgehend von der übergeordneten Klasse und Abschluss der Konstruktion Schritt für Schritt bis zur Unterklasse. Und wir haben nicht explizit auf den Konstruktor der übergeordneten Klasse verwiesen. Das ist die Cleverness von Java: Der Compiler ruft standardmäßig den Konstruktor der übergeordneten Klasse auf.
Dieser Standardaufruf an den Konstruktor der übergeordneten Klasse ist jedoch Voraussetzung: Die übergeordnete Klasse verfügt über einen Standardkonstruktor. Wenn die übergeordnete Klasse keinen Standardkonstruktor hat, müssen wir explizit super () verwenden, um den Konstruktor der übergeordneten Klasse aufzurufen. Andernfalls meldet der Compiler einen Fehler: Es wurde kein Konstruktor gefunden, der der Form der übergeordneten Klasse entspricht.
public class Person { protected String name; protected int age; protected String sex; Person(String name){ System.out.println("Person Constrctor-----" + name); } } public class Husband extends Person{ private Wife wife; Husband(){ super("chenssy"); System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor-----chenssy Husband Constructor...
Um es zusammenzufassen: Bei der Vererbung ruft die Unterklasse standardmäßig den Konstruktor der übergeordneten Klasse auf. Wenn jedoch kein Standardkonstruktor für die übergeordnete Klasse vorhanden ist, muss die Unterklasse den Konstruktor der übergeordneten Klasse explizit angeben. und muss das erste sein, was im Unterklassenkonstruktor (der ersten Codezeile) erledigt wird.
geschütztes Schlüsselwort
Der private Zugriffsmodifikator ist die beste Wahl für die Kapselung, aber dies basiert nur auf einer idealen Welt. Manchmal brauchen wir dieses Bedürfnis: Wir müssen Bestimmte Dinge so weit wie möglich vor der Welt verbergen, den Mitgliedern von Unterklassen aber dennoch den Zugriff darauf ermöglichen. Zu diesem Zeitpunkt müssen Sie protected verwenden.
„Geschützt“ bedeutet, dass es für den Klassenbenutzer privat ist, aber für jede Unterklasse, die diese Klasse oder eine andere Klasse im selben Paket erbt, zugänglich ist.
public class Person { private String name; private int age; private String sex; protected String getName() { return name; } protected void setName(String name) { this.name = name; } public String toString(){ return "this name is " + name; } /** 省略其他setter、getter方法 **/ } public class Husband extends Person{ private Wife wife; public String toString(){ setName("chenssy"); //调用父类的setName(); return super.toString(); //调用父类的toString()方法 } public static void main(String[] args) { Husband husband = new Husband(); System.out.println(husband.toString()); } } Output: this name is chenssy
Aus dem obigen Beispiel können Sie ersehen, dass die Unterklasse Husband offensichtlich setName() der übergeordneten Klasse Person aufrufen kann.
Es ist wahr, dass Sie zwar den geschützten Zugriffsmodifikator verwenden können, um den Zugriff auf Eigenschaften und Methoden der übergeordneten Klasse einzuschränken, der beste Weg jedoch darin besteht, die Eigenschaften privat zu halten (wir sollten die zugrunde liegende Implementierung immer ändern) und zu verwenden Die geschützte Methode steuert die Zugriffsberechtigungen für Erben einer Klasse.
Aufwärtstransformation
In der obigen Vererbung haben wir über Vererbung als eine gegenseitige Beziehung von is-a, Katzenerbe und Tier gesprochen, also können wir Katze sagen Es ist ein Tier, oder eine Katze ist eine Tierart. Katzen auf diese Weise als Tiere zu betrachten, bedeutet eine Transformation nach oben. Wie folgt:
public class Person { public void display(){ System.out.println("Play Person..."); } static void display(Person person){ person.display(); } } public class Husband extends Person{ public static void main(String[] args) { Husband husband = new Husband(); Person.display(husband); //向上转型 } }
Hier übergeben wir Person.display(husband). Aus diesem Satz ist ersichtlich, dass der Ehemann ein Personentyp ist.
Die Konvertierung einer Unterklasse in eine übergeordnete Klasse bewegt sich in der Vererbungsbeziehung nach oben und wird daher allgemein als Aufwärtstransformation bezeichnet. Da es sich beim Upcasting um eine Konvertierung von einem spezialisierten Typ in einen allgemeineren Typ handelt, ist es immer sicher. Die einzige Änderung, die auftreten kann, ist der Verlust von Eigenschaften und Methoden. Aus diesem Grund erlaubt der Compiler Aufwärtsumwandlungen, auch wenn die Umwandlung nicht explizit angegeben oder kein spezielles Flag angegeben ist.
Seien Sie vorsichtig mit der Vererbung
Oben wurde über die vielen Vorteile der Vererbung gesprochen. Können wir die Vererbung also großzügig nutzen? Ein Tipp für Sie: Gehen Sie beim Thema Vererbung mit Vorsicht vor.
Zunächst müssen wir klarstellen, dass die Vererbung die folgenden Mängel aufweist:
1. Wenn sich die übergeordnete Klasse ändert, muss sich auch die Unterklasse ändern.
2. Vererbung zerstört die Kapselung. Für die übergeordnete Klasse sind ihre Implementierungsdetails für die Unterklasse transparent.
3. Vererbung ist eine starke Kopplungsbeziehung.
Wenn wir also die Vererbung verwenden, müssen wir sicherstellen, dass die Verwendung der Vererbung tatsächlich eine effektive und praktikable Methode ist. Sollten wir also Vererbung nutzen? „Think in Java“ bietet eine Lösung: Fragen Sie sich, ob Sie eine Aufwärtstransformation von der Unterklasse zur übergeordneten Klasse durchführen müssen. Wenn eine Aufwärtstransformation erforderlich ist, ist eine Vererbung erforderlich. Wenn nicht, sollten Sie sorgfältig überlegen, ob Sie eine Vererbung benötigen.
Vererbung mit Vorsicht nutzen! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
Das Obige ist das Java-Verbesserungskapitel (2) ----- Verständnis der Vererbung der drei Hauptmerkmale von Java Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php. cn)!