Java-Vererbung

Über diesen Beitrag

Ich verweise auf die 2. Ausgabe der Java-Einführung, die Sie klar verstehen können.

1. Grundlagen der Vererbung

1.1 Vererbung

Bei der Entwicklung eines Programms wird häufig eine Klasse erstellt, die der zuvor erstellten Klasse ähnelt. Derzeit ist es ineffizient, die zuvor erstellte Klasse zu kopieren und einzufügen, sodass Sie effizienten Code schreiben können, indem Sie die zuvor erstellte Klasse erben.

Hero.java


public class Hero{
  private String name = "hoge";
  private int Hp = 100;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 5;
  }
}

SuperHero.java


public class SuperHero{
  private String name = "hoge";
  private int Hp = 100;
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("Flugstatus");
  }
  public void land(){
    this.flying = false;
    System.out.println("Landezustand");
  }
}

Wenn ich in diesem Code der Hero-Klasse eine neue Methode hinzufüge, muss ich diese Änderung auch in die SuperHero-Klasse ändern. Da der größte Teil des Codes zwischen der SuperHero-Klasse und der Hero-Klasse ähnlich ist, ist die Gesamtansicht schwierig und die Wartung mühsam. Verwenden Sie daher ** Vererbung **, um Codeduplizierungen zu vermeiden.

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("Flugstatus");
  }
  public void land(){
    this.flying = false;
    System.out.println("Landezustand");
  }
}

Durch Umschreiben wie oben beschrieben ist es möglich, eine SuperHero-Klasse zu definieren, die die Feldmethoden der Hero-Klasse erbt. In diesem Fall wird die Hero-Klasse als übergeordnete Klasse (Superklasse) und die SuperHero-Klasse als untergeordnete Klasse (Unterklasse) bezeichnet.

1.2 Vererbungsschwankungen

Java erlaubt keine Mehrfachvererbung. Insbesondere wenn es eine Hero-Klasse und eine Moster-Klasse gibt, ist es nicht möglich, eine HeroMonster-Klasse zu definieren, indem diese beiden Klassen geerbt werden. Das heißt, eine Kinderklasse kann nicht mit mehreren Elternklassen als Eltern definiert werden. Es ist möglich, die in der übergeordneten Klasse definierte Methode mit der untergeordneten Klasse zu überschreiben (als Methodenüberschreibung bezeichnet). Einige Java-Klassen dürfen nicht erben. Ein Beispiel ist die String-Klasse. Es ist auch möglich, eine Klasse zu deklarieren, die es nicht zulässt, dass sie selbst vererbt wird. Fügen Sie den letzten Operator hinzu, wenn Sie eine Klasse deklarieren.

Main.java


public final class Main{
  public static void main(Strign args[]){
    //Inhalt der Hauptfunktion
  }
}

Um Methodenüberschreibungen zu vermeiden, fügen Sie beim Deklarieren der Methode den endgültigen Operator hinzu.

1.3 Instanzverhalten

Überlegen Sie, was mit dem Verhalten der erstellten Instanz aufgrund der Vererbung passiert. Es wird anhand der oben gezeigten Hero-Klasse und der SuperHero-Klasse beschrieben. Die SuperHero-Instanz enthält eine Hero-Instanz und hat eine doppelte Struktur. Wenn ein Methodenausführungsbefehl von außerhalb der Instanz aufgerufen wird, ruft die multistrukturierte Instanz * so weit wie möglich die Methode * der untergeordneten Instanz von außen auf. Insbesondere wenn die Wiederherstellungsmethode von der SuperHero-Instanz aufgerufen wird, wird die überschriebene Methode aufgerufen und die Wiederherstellungsmethode der Hero-Instanz wird nicht aufgerufen. Beschreibt den Zugriff auf die übergeordnete Instanz. Wenn Sie sich im Flug erholen, erhalten Sie als zusätzliche Spezifikation HP um 25 Punkte. Beim Aufruf des Methodenfeldes der übergeordneten Instanz

super. Methodenname (Argument) super. Feldname

Und.

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
    if(this.flying){
      super.recover();
    }
  }
  public void fly(){
    this.flying = true;
    System.out.println("Flugstatus");
  }
  public void land(){
    this.flying = false;
    System.out.println("Landezustand");
  }
}

Wenn Sie zu diesem Zeitpunkt super.recover () mit recovery () aufrufen, wird es als this.recover () aufgerufen und Sie geraten in eine Endlosschleife. Seien Sie also vorsichtig.

1.4 Vererbung und Konstruktoren

Wir haben bereits erklärt, dass geerbte Instanzen eine mehrschichtige Struktur haben. Überlegen Sie als Nächstes, wie die Instanz erstellt wird. Führen Sie das folgende Programm mit Bezug auf das obige Programm aus.

Hero.java


public class Hero{
  private String name = "hoge";
  private int Hp = 100;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 5;
  }

  Hero(){
    System.out.println("Heldenkonstrukteur");
  }
}

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("Flugstatus");
  }
  public void land(){
    this.flying = false;
    System.out.println("Landezustand");
  }

  SuperHero(){
    System.out.println("SuperHero Konstruktor");
  }
}

Main.java


public class Main{
  public static void main(Strign args[]){
    SuperHero sh = new SuperHero();
  }
}

Zuerst wird der übergeordnete Instanzteil erstellt, und dann wird der untergeordnete Instanzteil außen erstellt. Schließlich ruft die JVM automatisch den SuperHero-Klassenkonstruktor auf. Das Ausführungsergebnis ist wie folgt.

Ausführungsergebnis


Heldenkonstrukteur
SuperHero Konstruktor

Beachten Sie, dass der Konstruktor der Hero-Instanz, die die innere Instanz ist, ebenfalls aufgerufen wird. Dies liegt daran, dass die Java-Regel lautet: "Alle Konstruktoren müssen zu Beginn den Konstruktor der internen Instanz aufrufen."

SuperHero.java


public class SuperHero extends Hero{
  .
  .
  .

  SuperHero(){
    super();
    System.out.println("SuperHero Konstruktor");
  }
}

Der Compiler fügt automatisch super () ein.

1.5 Situationen, in denen keine übergeordnete Instanz erstellt werden kann

Ein Konstruktor, der nicht im übergeordneten Instanzteil definiert ist, kann vom Konstruktor im untergeordneten Instanzteil aufgerufen werden, was zu einem Fehler führt. Insbesondere wird es unter Verwendung der Klasse Mensch und der Klasse Soldat beschrieben.

Human.java


public class Human{
  private String name;
  private int Hp;
  private int Mp;

  Human(String name){
    this.name = name;
    this.Hp = 100;
    this.Mp = 100;
  }
  Human(String name, int hp, int mp){
    this.name = name;
    this.Hp = hp;
    this.Mp = mp;
  }
}

Human.java


public class Soldier{
  .
  .
  .
}

Main.java


public class Main{
  public static void main(Strign args[]){
    Soldier soldier = new Soldier();
  }
}

In diesem Code hat die Soldier-Klasse keinen Konstruktor, daher wird der Konstruktor der übergeordneten Klasse Human-Klasse aufgerufen. Die Human-Klasse verfügt jedoch nicht über einen Konstruktor ohne Argumente, sodass dieser Code zu einem Fehler führt. Um dies zu verhindern, rufen Sie den Konstruktor mit Argumenten im Konstruktor der Soldier-Klasse zwangsweise auf, um das Problem zu lösen.

Human.java


public class Soldier{
  .
  .
  .
  Soldier(){
    super("hoge");
  }
}

1.6 Richtige Vererbung und falsche Vererbung

Richtige Vererbung ist Vererbung nach dem "is-a-Prinzip".

Untergeordnete Klasse ist eine übergeordnete Klasse (untergeordnete Klasse ist Teil der übergeordneten Klasse)

Wie im oben gezeigten Code erläutert, ist die SuperHero-Klasse Teil der Hero-Klasse. Es ist ein Fehler, dass die Hero-Klasse Teil der SuperHero-Klasse ist. Vererbung ist eine nützliche Funktion, aber eine falsche Vererbung kann zu programmatischen Inkonsistenzen und der Unfähigkeit führen, die Vielfalt zu nutzen.

2. Vererbung mit abstrakten Klassen

2.1 Bedeutung der Existenz der abstrakten Klasse

Eine abstrakte Klasse ist eine Klasse mit einem abstrakten Methodenfeld. Eine konkrete Klasse, die von einer abstrakten Klasse erbt, muss die in der abstrakten Klasse definierten Methoden überschreiben. Wenn Sie mehrere abstrakte Klassen erben, können Sie dies auch realisieren, indem Sie die abstrakten Klassen als Schnittstellen definieren (Details sind 2.3). Die Bedeutung der Existenz abstrakter Klassen und Methoden ist ein Material für die effiziente Erstellung sicherer Programme, wenn die Anzahl der Entwickler in Zukunft zunimmt. Um ein konkretes Beispiel zu nennen: Wenn Sie mit der Entwicklung ohne abstrakte Klasse fortfahren, wird der Inhalt einer bestimmten Methode zu diesem Zeitpunkt möglicherweise nicht festgelegt, und der Inhalt der Methode wird möglicherweise leer gelassen. Wenn ein anderer Entwickler diese Methode sieht, weiß ich nicht, ob der Inhalt neu geschrieben werden muss. Wenn es jedoch als abstrakte Methode definiert ist, muss es überschrieben werden, sodass ersichtlich ist, dass der Inhalt neu geschrieben werden muss. Daraus können Sie sich mit der abstrakten Methode sicher entwickeln.

2.2 Abstrakte Klassenmethode

Character.java


public class Character{
  .
  .
  public abstract void atttack(Monster m);

}

Die Angriffsmethode ist in einer Klasse enthalten, die die Zeichenklasse erbt.

Character.java


public abstract class Character{
  .
  .
  public abstract void atttack(Monster m);

}

Definieren Sie eine Klasse als abstrakte Klasse, um die Erstellung unvollständiger Klasseninstanzen zu verhindern.

2.3 Schnittstelle

In Java können abstrakte Klassen mit einem besonders hohen Abstraktionsgrad speziell als Schnittstellen behandelt werden. Als Bedingung, um als Schnittstelle zu behandeln

Es gibt.

Creature.java



public interface Creature{
  public abstract void run();  //öffentliche Zusammenfassung kann weggelassen werden
}

Wenn Sie eine Variable in der Schnittstelle definieren, wird public static final ergänzt und als Konstante behandelt. Gehen Sie beim Implementieren der Creature-Klasse wie folgt vor.

Pig.java



public class Pig implements Creature{
  public void run(){
    System.out.println("Schwein rannte weg");
  }
}

Durch die Definition der Schnittstelle

Es gibt einen Verdienst.

Recommended Posts

[Java] Vererbung
Java-Vererbung
Java-Vererbung
Java (Vererbung)
[Java] Klassenvererbung
Über Java-Vererbung
[Java] Überladen / Überschreiben / Vererbung
Erbe
Fassen Sie die Java-Vererbung zusammen (Java Silver 8)
Informationen zur Vererbung (Java Silver)
Java
Java
[Java] Implizites Vererbungsprotokoll
Java-Lernnotiz (Vererbung)
Zusammenfassung der erweiterten Vererbung, Schnittstelle -java
Vererbung der JAVA-Lernverlaufsschnittstelle
Java ab Anfänger, Vererbung
[Java] Was ist Klassenvererbung?
Java (Vererbung von is-ein Prinzip)
Java lernen (0)
Java studieren ―― 3
[Java] -Array
Java geschützt
[Java] Anmerkung
[Java] Modul
Java studieren ―― 9
Java Scratch Scratch
Java-Tipps, Tipps
Java-Methoden
Java-Methode
Java (Konstruktor)
Über die Vererbung
Java-Array
[Java] ArrayDeque
Java (überschreiben)
Java (Methode)
Java Day 2018
Java-Zeichenfolge
Java (Array)
Java statisch
Java-Serialisierung
Java Anfänger 4
JAVA hat bezahlt
Java studieren ―― 4
Java (gesetzt)
Java-Shell-Sortierung
[Java] compareTo
Java studieren -5
Java reflektierend 获 获 举
Java (Schnittstelle)
Java-Memorandum
Java-Array
Java studieren ―― 1
[Java] Array
[Java] Polymorphismus
Java # 0 studieren
Java-Überprüfung
Java-Framework
Java-Funktionen
FastScanner Java
Java-Funktionen