[JAVA] Lassen Sie uns mit Vererbung faulenzen und überschreiben

Vererbung ist nicht gut ~ ...

In der Schule hatte ich eine großartige Nachfolge, also sprach ich über die Nachfolge mit Schwung. Da es fast ad libitum ist, ist auch abstrakt verfügbar.

Was ist Vererbung?

Die Vererbung besteht darin, eine andere Klasse aufzunehmen und eine Instanz einer in einer anderen Klasse geschriebenen Methode oder Variablen zu erstellen. Sie können sie so behandeln, als wäre sie eine in Ihrer eigenen Klasse oder einer Variablen geschriebene Methode. ..

Verwenden Sie das Schlüsselwort extens für die Vererbung. Die geerbte Klasse wird als übergeordnete Klasse (Superklasse) und die geerbte und erweiterte Klasse als untergeordnete Klasse (Unterklasse) bezeichnet.

Übergeordnete Klasse


class SuperClass{
  public int num = 10;

  public void superClassMethod(){
    System.out.println("Es ist eine Elternklasse ~");
  }
}

Kinderklasse


class SubClass extends SuperClass{
  //Ich schreibe vorerst nichts
}

Klasse mit Hauptmethode


class Test{
  public static void main(String[] args){
    SubClass instance = new SubClass();
    instance.superClassMethod();
  }
}

// >>>"Es ist eine Elternklasse" wird angezeigt.

Wenn man die Beziehung in der Abbildung betrachtet, sieht es so aus. 名称未設定1.png Es fühlt sich an, als ob die untergeordnete Klasse die übergeordnete Klasse umfasst. Wenn Sie auf Japanisch denken, sind Sie ein Elternteil unter Ihren Kindern? Sie mögen denken, aber geben Sie Ihr Bestes und gewöhnen Sie sich daran ...

Untergeordnete Klassen können nicht private Variablen und Methoden der übergeordneten Klasse verwenden. Wenn Sie private Variablen der übergeordneten Klasse verwenden möchten, bereiten Sie die Getter / Setter-Methoden vor.

Kinderklasse


class SubClass extends SuperClass{
  void test(){
    //Beziehen Sie sich auf die Variable der übergeordneten Klasse
    System.out.println(num);  //10

    //Versuchen Sie, eine Methode der übergeordneten Klasse aufzurufen
    superClassMethod();
  }
}

Durch dieses Erben konnte ich das Gefühl vermitteln, eine andere Klasse in meine Klasse aufgenommen zu haben. Wenn Sie jedoch dieselbe Methode an verschiedenen Stellen verwenden können, können Sie eine Klassenmethode verwenden.

Das stimmt nicht. </ b>

Durch das Erben kann </ b> überschrieben werden. Lass es uns versuchen.

Lassen Sie uns überschreiben

Mit Überschreiben können Sie Methoden der Oberklasse hinzufügen und definieren. Warum brauchst du das? Ich werde später darüber sprechen, also warte eine Minute.

Übergeordnete Klasse


class SuperClass{
  public void printMethod(){
    System.out.println("Es ist eine Elternklasse ~");
  }
}

Kinderklasse


class SubClass extends SuperClass{
  @Override
  public void printMethod(){
    System.out.println("Ich habe es überschrieben!");
  }
}

Auf diese Weise kann die Methode überschrieben werden, indem eine Methode mit demselben Namen und demselben Argument wie die Methode der übergeordneten Klasse in der untergeordneten Klasse definiert wird.

Die Annotation "@ Override" wird vor der Methode geschrieben. Dies soll dem Java-Compiler anzeigen, dass "diese Methode überschreibt" und nichts mit dem Verhalten des Programms zu tun hat. Ich weiß nicht, ob es ohne dies überschrieben wird, und wenn der Name nicht mit der Methode der übergeordneten Klasse übereinstimmt, wird ein Fehler ausgegeben, daher ist es ein Standard, ihn hinzuzufügen.

Wenn Sie weitere Details erfahren möchten, lesen Sie Folgendes. Die Leute müssen es nicht separat lesen.

Was ist, wenn ich kein "@ Override" habe?

Warum brauchen Sie etwas, das nichts mit Betrieb zu tun hat? In diesem Beispiel wird beispielsweise eine Methode namens "printMethod ()" hinzugefügt und definiert, es wird jedoch ein geringfügiger Tippfehler gemacht und der Methodenname lautet "priiiiiiiiiintMethod ()".

Kinderklasse


class SubClass extends SuperClass{
  public void priiiiiiiiiintMethod(){
    System.out.println("Ich habe es überschrieben!");
  }
}

Wenn es kein "@ Override" hat, kann es normal als eine Methode kompiliert werden, die Sie nicht überschreiben möchten. Wenn der Aufrufer dieser Methode erneut einen korrekten Tippfehler macht (?), Kann er normal verwendet werden, sodass es einige Zeit dauert, bis festgestellt wird, dass die gewünschte Operation nicht ausgeführt wird.

Es ist besser, eine "@ Override" -Anmerkung zu schreiben, um einen solchen menschlichen Fehler zu vermeiden. Wenn Sie in der IDE arbeiten, funktioniert auch die Funktion zur Vervollständigung der Eingabe gut.

Warum machst du so eine lästige Sache?

Ich dachte: "Wenn Sie es separat erben möchten, sollten Sie einfach eine andere Klasse erstellen, indem Sie es kopieren." Aber die Vererbung ist viel intelligenter als wir denken.

Weil Sie den Kopiercode reduzieren können

Erstens müssen Sie beim Vorbereiten ähnlicher Klassen nicht kopieren und einfügen, was zu einer Verringerung der Codemenge führt. "Es ist egal, ob es lang ist"? Seien wir faul, weil es ärgerlich ist, einen Charakter mehr zu treffen! !! </ b>

Fahren wir mit einem Beispiel für das programmgesteuerte Erstellen von Kreaturen fort.

Versuchen Sie zu schreiben, ohne zu erben

Hund


class Wanko{
  public void eat(String foodName){
    //Ich dachte, es wurde darüber geschrieben, wie man einen Hund isst

    //Auf dem Essensteller...
    //Direct...
    //Attack!!(Hundefutter)

    System.out.println(foodName+"aß");

    //Verdauen
    syouka(foodName);
  }

  public void syouka(String foodName){
    System.out.println(foodName+"Verdaut");
  }
}

Affe


class Monkey{
  public void eat(String foodName){
    //Ich dachte, dass der Prozess des Essens von Affen geschrieben wurde

    //Von Hand abholen...
    //Zu deinem Mund...
    //Ich möchte, dass du es trägst und isst.

    System.out.println(foodName+"aß");

    //Verdauen
    syouka(foodName);
  }

  public void syouka(String foodName){
    System.out.println(foodName+"Verdaut");
  }
}

Nun gibt es einige Ähnlichkeiten zu diesen beiden Methoden. Reduzieren wir die Codemenge, indem wir dies erben.

Erben und schreiben

Erstelle zuerst eine Basis Kreaturenklasse </ b>. Ich bin kein Biologe, also weiß ich es nicht, aber das Verfahren zur Verdauung von Affen und Hunden ist das gleiche.

Kreaturen


class Animal{
  public void eat(String foodName){
    System.out.println(foodName+"aß");

    //Verdauungsprozess
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Verdaut");
  }
}

Lassen Sie uns dies erben und eine Hundeklasse und eine Affenklasse schreiben.

Hund


class Wanko extends Animal{
  @Override
  public void eat(String foodName){
    //Ich dachte, es wurde darüber geschrieben, wie man einen Hund isst
    //Auf dem Essensteller...
    //Direct...
    //Attack!!(Hundefutter)

    //super()Kann verwendet werden, um die eat-Methode der übergeordneten Klasse aufzurufen.
    super(foodName);
  }
}

Affe


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //Ich dachte, dass der Prozess des Essens von Affen geschrieben wurde

    //Von Hand abholen...
    //Zu deinem Mund...
    //Ich möchte, dass du es trägst und isst.

    //super()Kann verwendet werden, um die eat-Methode der übergeordneten Klasse aufzurufen.
    super(foodName);
  }
}

Plötzlich schrieb ich super ();, aber es ist nie passiert. Es wird nur die Methode der übergeordneten Klasse aufgerufen. Die eat () -Methode </ b> der Elternklasse wird verwendet, um anzuzeigen, was gegessen und verdaut wurde, was bei Hunden und Affen üblich ist.

Übrigens ... (Über super ())

super () ist ein Schlüsselwort, das im Konstruktor der untergeordneten Klasse unter den überschriebenen Methoden verwendet werden kann, und die Methode und der Konstruktor der übergeordneten Klasse können aufgerufen werden. super () kann wie normale Methoden auch Argumente übergeben und überladen.

abstraktes Schlüsselwort

Die oben erwähnte "Tier" -Klasse war eine Klasse, die Vererbung annahm </ b>. In diesem Fall kann die Klasse "Animal" verwendet werden, indem eine Instanz ohne Vererbung erstellt wird. Es handelt sich jedoch nicht um eine zu diesem Zweck erstellte Klasse.

Verwenden Sie in diesem Fall das Schlüsselwort "abstract". abstract ist auch Klassen und Methoden zugeordnet.

abstract bedeutet abstract </ b>, immateriell </ b>. Wie der Name schon sagt, handelt es sich um eine abstrakte Klasse und Methode </ b>. Machen Sie sie daher bitte konkret, bevor Sie sie verwenden.

Wenn einer Klasse abstract hinzugefügt wird, ist die Instanziierung durch das Schlüsselwort new verboten und kann nur verwendet werden, wenn eine Vererbung durchgeführt wird. </ b> Klassen mit "abstract" werden abstrakte Klassen </ b> genannt.

Wenn der Methode abstract hinzugefügt wird, kann der Prozess nicht beschrieben werden und die untergeordnete Klasse muss überschrieben werden. </ b> Wenn Sie es nicht aus der untergeordneten Klasse überschreiben, wird es nicht kompiliert. Selbstverständlich kann super () auch nicht verwendet werden.

Kreaturen


class abstract Animal{
  public void eat(String foodName){
    System.out.println(foodName+"aß");

    //Verdauungsprozess
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Verdaut");
  }

  public abstract void printName();
}

Affe


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //Ich dachte, dass der Prozess des Essens von Affen geschrieben wurde

    //Von Hand abholen...
    //Zu deinem Mund...
    //Ich möchte, dass du es trägst und isst.

    //super()Kann verwendet werden, um die eat-Methode der übergeordneten Klasse aufzurufen.
    super(foodName);
  }

  //printName()Sie müssen die Methode immer überschreiben.
  @Override
  public void printName(){
    System.out.println("Wai ist ein Affe");
  }
}

final Schlüsselwort

Sie können "final" hinzufügen, um weitere Änderungen zu verhindern. ..

Wenn eine Klasse angehängt ist, ist die Vererbung verboten. Beim Anhängen an eine Methode ist das Überschreiben verboten. Beim Anhängen an eine Variable ist die Neuzuweisung eines anderen Werts als beim Deklarieren der Variablen verboten.

Weil es als übergeordneter Klassentyp behandelt werden kann

Es ist sehr praktisch, auf den übergeordneten Klassentyp </ b> hochzuspielen.

Bringen Sie die oben genannten Tiere wieder.

Kreaturen


class Animal{
  public void eat(String foodName){
    System.out.println(foodName+"aß");

    //Verdauungsprozess
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Verdaut");
  }
}

Hund


class Wanko extends Animal{
  @Override
  public void eat(String foodName){
    //Ich dachte, es wurde darüber geschrieben, wie man einen Hund isst
    //Auf dem Essensteller...
    //Direct...
    //Attack!!(Hundefutter)

    //super()Kann verwendet werden, um die eat-Methode der übergeordneten Klasse aufzurufen.
    super(foodName);
  }
}

Affe


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //Ich dachte, dass der Prozess des Essens von Affen geschrieben wurde

    //Von Hand abholen...
    //Zu deinem Mund...
    //Ich möchte, dass du es trägst und isst.

    //super()Kann verwendet werden, um die eat-Methode der übergeordneten Klasse aufzurufen.
    super(foodName);
  }
}

Tier, Hund und Affe haben eine Eltern-Kind-Beziehung. Wenn Sie eine Eltern-Kind-Beziehung haben, können Sie eine Typkonvertierung durchführen ...! </ b>

Möchten Sie es zunächst ohne Typkonvertierung schreiben?

class MeshiKue{
  public static void main(String[] args){
    Wanko dog = new Wanko();
    Monkey monkey = new Monkey();

    Gohan(dog);
    Gohan(monkey);
  }

  void Gohan(Wanko wanko){
    wanko.eat("Apfel");
  }

  void Gohan(Monkey monkey){
    monkey.eat("Apfel");
  }
}   

Nun, es wird so sein. Es ist in Ordnung, weil es zwei Typen gibt, aber wenn die Anzahl der Freunde und die Anzahl der Servalkatzen Arai-san und Fennec zunimmt, muss für jeden Typ die Methode Gohan () geschrieben werden. </ B> b> Richtig.

Wenn es sich um denselben Vorgang handelt, können Sie ihn nicht sehen. Verwenden Sie daher die Konvertierung vom Typ , um nur einen Vorgang auszuführen. </ b>

class MeshiKue{
  public static void main(String[] args){
    Wanko dog = new Wanko();
    Monkey monkey = new Monkey();

    //Upcast Hunde und Affen zu Tierart
    Gohan((Animal)dog);
    Gohan((Animal)monkey);
  }

  //Nur einer!
  void Gohan(Animal animal){
    animal.eat("Apfel");
  }
}   

Das Umwandeln eines untergeordneten Klassentyps in einen übergeordneten Klassentyp wird als upcast </ b> und das Umwandeln eines übergeordneten Klassentyps in einen untergeordneten Klassentyp als downcast </ b> bezeichnet. Downcasting kann nur für Variablen durchgeführt werden, die einmal hochgespielt wurden.

Wenn eine Eltern-Kind-Beziehung besteht, enthält die untergeordnete Klasse immer die Methoden und Variablen, die in der übergeordneten Klasse enthalten sind, sodass sie in die übergeordnete Klasse umgewandelt werden kann.

Selbst wenn es eine Methode mit demselben Namen und demselben formalen Argument zwischen zwei Klassen gibt, die keine Eltern-Kind-Beziehung haben, existiert zufällig eine Methode mit dem Namen und dem formalen Argument </ b>, sodass sie statisch ist. Die Typkonvertierung kann nicht in einer typisierten Sprache durchgeführt werden.

Apropos

Mit einer dynamisch typisierten Sprache wie Python können Sie dies mit duck typing </ b> tun, auch wenn Sie zufällig eine Methode mit demselben Namen haben und keine Eltern-Kind-Beziehung besteht. Die dynamisch typisierte Sprache wird Zeile für Zeile zufällig ausgeführt, sodass sie nur zu diesem Zeitpunkt vorhanden sein muss.

schließlich

Mendokuseee vom Programmschreiben! Wenn Sie </ b> denken, wenn Sie nach einer Sprachfunktion suchen, die es lösen kann, oder wenn es eine kürzere Syntax gibt, werden Sie meiner Meinung nach dem Rennen näher kommen, das als guter Programmierer bezeichnet wird. Lassen Sie uns also unser Bestes tun, um es zu finden. !! !!