JavaRush /Java-Blog /Random-DE /Instanzen und Vererbungsgrundlagen

Instanzen und Vererbungsgrundlagen

Veröffentlicht in der Gruppe Random-DE
Hallo! In früheren Vorlesungen sind wir bereits mehrfach kurz auf den Begriff der Vererbung gestoßen. Heute werden wir dieses Thema ebenfalls ansprechen, aber auch nicht zu tief. Später wird es einen ausführlichen Vortrag dazu geben, aber heute schauen wir uns nur praktische Beispiele an und lernen einen interessanten Operator in Java kennen.

Java-Vererbung

Was genau ist also Vererbung? Instanzen und Vererbungsgrundlagen – 1Vererbung ist ein Mechanismus in der Programmierung, einschließlich Java, der es Ihnen ermöglicht, eine neue Klasse basierend auf einer vorhandenen Klasse zu beschreiben. Die Nachkommenklasse erhält dann Zugriff auf die Felder und Methoden der Elternklasse. Warum könnte das notwendig sein? Stellen Sie sich zum Beispiel vor, Sie müssten im Programm mehrere Fahrzeugklassen erstellen: LKW, Rennwagen, Limousine, Pickup usw. Auch ohne mit dem Schreiben von Code zu beginnen, wissen Sie mit Sicherheit, dass diese Klassen viele Gemeinsamkeiten haben: Alle Autos haben einen Modellnamen, ein Baujahr, eine Motorgröße, eine Höchstgeschwindigkeit usw. (ganz zu schweigen von der Tatsache, dass sie alle Räder und andere Teile haben). In einer solchen Situation können Sie:
  • Erstellen Sie diese Felder in jeder Klasse und fügen Sie sie bei der Erstellung neuen Fahrzeugklassen hinzu
  • Verschieben Sie die allen Maschinen gemeinsamen Felder in die übergeordnete Klasse Car, und alle Klassen bestimmter Maschinentypen erben von Carder Verwendung des Wortes „extends“ .
Die zweite Option ist natürlich viel bequemer:
public class Car {

   private String model;
   private int maxSpeed;
   private int yearOfManufacture;

   public Car(String model, int maxSpeed, int yearOfManufacture) {
       this.model = model;
       this.maxSpeed = maxSpeed;
       this.yearOfManufacture = yearOfManufacture;
   }
}

public class Truck extends Car {

   public Truck(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}

public class Sedan extends Car {
   public Sedan(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}
Zumindest haben wir unnötige Codeduplizierungen vermieden, und das sollten wir beim Schreiben von Programmen immer anstreben. Darüber hinaus haben wir eine einfache und verständliche Klassenstruktur: Felder, die allen Maschinen gemeinsam sind, werden in einer Klasse zusammengefasst. Wenn beispielsweise LKWs bestimmte Felder haben, die andere Autos nicht haben, können diese im angegeben werden Truck. Das Gleiche gilt für Methoden. Alle Autos haben ein gemeinsames Verhalten, das beschrieben werden kann: Auto starten, Gas geben/bremsen usw. Diese allgemeinen Methoden können in einer allgemeinen Klasse platziert werden Car, und das spezifische Verhalten jedes spezifischen Typs kann in abgeleiteten Klassen beschrieben werden.
public class Car {

   public void gas() {
       //...Gas
   }

   public void brake() {
       //...Bremse
   }
}


public class F1Car extends Car {

   public void pitStop() {

       //...nur Rennwagen machen Boxenstopps
   }

   public static void main(String[] args) {

       F1Car formula1Car = new F1Car();
       formula1Car.gas();
       formula1Car.pitStop();
       formula1Car.brake();
   }
}
Wir haben die gemeinsamen Methoden aller Autos in die Klasse verschoben Car. Doch in der Nachfolgeklasse F1Car, die Formel-1-Rennwagen beschreibt, gibt es Boxenstopps (Stopps zur dringenden Wartung des Wagens), die nur im Rennsport durchgeführt werden und sich durch spezifisches Verhalten auszeichnen.

Java-Instanz des Operators

Um zu überprüfen, ob ein Objekt basierend auf einer Klasse erstellt wird, gibt es in Java einen speziellen Operator – instanceof. Es gibt den Wert zurück true, wenn der Test wahr war oder falsewenn das Ergebnis falsch war. Sehen wir uns am Beispiel unserer Autoklassen an, wie es funktioniert:
public class Truck extends Car {

   public static void main(String[] args) {

       Truck truck = new Truck();
       System.out.println(truck instanceof Car);
   }
}
Ausgabe: true.instanceof Testen mit dem zurückgegebenen Operator true, da wir ein Objekt der Klasse haben Truckund alle Lastwagen Autos sind. Die Klasse Truckist ein Nachkomme der Klasse Car, daher werden alle LKWs auf der Grundlage eines gemeinsamen Elternteils erstellt – einem Auto. Achten Sie auf den Operator instanceof: Er wird ohne Punkt geschrieben, da es sich um einen Operator und nicht um eine Methode handelt („Objektinstanz der Klasse“). Versuchen wir es mal anders:
public static void main(String[] args) {

   Car car = new Car();
   System.out.println(car instanceof Truck);
}
Ausgabe: false Die Klasse Carund dementsprechend ihr Objekt sind nicht von der Klasse abgeleitet Truck. Alle Lastwagen sind Autos, aber nicht alle Autos sind Lastwagen. Objekte Carwerden nicht basierend auf der Klasse erstellt Truck. Noch ein Beispiel:
public static void main(String[] args) {

   Car car = new Car();
   Truck truck = new Truck();
   System.out.println(car instanceof Object && truck instanceof Object);
}
Ausgabe: True Die Logik hier ist ebenfalls einfach: Alle Klassen in Java, einschließlich der von Ihnen erstellten, stammen aus einer Klasse Object(obwohl Sie kein „extends Object“ in sie schreiben – dieser Mechanismus ist in ihnen implizit). Warum könnte dies nützlich sein und unter welchen Umständen? Der Operator wird am häufigsten instanceofals Methodenüberschreibung verwendet equals(). So wird die Methode beispielsweise equalsin der Klasse implementiert String:
public boolean equals(Object anObject) {
   if (this == anObject) {
       return true;
   }
   if (anObject instanceof String) {
       String anotherString = (String) anObject;
       int n = value.length;
       if (n == anotherString.value.length) {
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while (n-- != 0) {
               if (v1[i] != v2[i])
                       return false;
               i++;
           }
           return true;
       }
   }
   return false;
}
Vor dem Vergleich des Strings mit dem übergebenen Objekt prüft die Methode: Ist das übergebene Objekt tatsächlich ein String? Und erst dann beginnt er, die Eigenschaften zweier Objekte zu vergleichen. Ohne diese Prüfung könnten Sie jedes Objekt, das über Wert- und Längenfelder verfügt, an die Methode übergeben und es mit einer Zeichenfolge vergleichen, was natürlich falsch wäre.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION