1. Aber das ist noch nicht alles.

Angenommen, die CowKlasse verfügt über eine printAll()Methode, die zwei andere Methoden aufruft. Dann funktioniert der Code so:

Code Beschreibung
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor ()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.println("I'm a whale");
   }
}
public static void main(String[] args)
{
   Whale whale = new Whale ();
   whale.printAll();
}
Die Bildschirmausgabe wird sein:
I'm a white whale
I'm a whale

Beachten Sie, dass beim Aufruf der printAll()Methode in der Klasse für ein Objekt die Methode der Klasse verwendet wird, nicht die in der Methode.CowWhaleprintNameWhaleCow

Die Hauptsache ist nicht die Klasse, in der die Methode geschrieben ist, sondern der Typ (die Klasse) des Objekts, für das die Methode aufgerufen wird.

Nur nicht statische Methoden können vererbt und überschrieben werden. Statische Methoden werden nicht vererbt und können daher nicht überschrieben werden.

So Whalesieht die Klasse nach der Anwendung von Vererbung und Methodenüberschreibung aus:

class Whale
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a whale");
   }
}
So Whalesieht die Klasse nach der Anwendung von Vererbung und Methodenüberschreibung aus: Wir kennen keine alte printNameMethode.

2. Typisierung

Hier gibt es einen noch interessanteren Punkt. Da eine Klasse alle Methoden und Daten ihrer übergeordneten Klasse erbt, kann ein Verweis auf ein Objekt der untergeordneten Klasse in Variablen gespeichert (zugeordnet) werden, deren Typ mit dem der übergeordneten Klasse (und dem übergeordneten Element der übergeordneten Klasse usw.) identisch ist. — bis zur ObjectKlasse). Beispiel:

Code Beschreibung
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printColor();
}
Die Bildschirmausgabe wird sein:
I'm a white whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printColor();
}
Die Bildschirmausgabe wird sein:
I'm a white whale
public static void main(String[] args)
{
   Object o = new Whale();
   System.out.println(o.toString());
}
Die Bildschirmausgabe wird sein:
Whale@da435a.

Die Methode wird von der Klasse toString()geerbtObject

Dies ist eine sehr wertvolle Eigenschaft: Wenig später werden Sie verstehen, wie Sie sie in der Praxis nutzen können.


3. Aufrufen einer Methode für ein Objekt

Wenn eine Methode für eine Variable aufgerufen wird, wird die Methode tatsächlich für ein Objekt aufgerufen. Dieser Mechanismus wird als dynamischer Methodenversand bezeichnet.

So sieht es aus:

Code Beschreibung
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
Die Bildschirmausgabe wird sein:
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
Die Bildschirmausgabe wird sein:
I'm a whale

Beachten Sie, dass die spezifische Implementierung der printName()aufgerufenen Methode – die in der Cowoder die in der WhaleKlasse – nicht durch den Typ der Variablen bestimmt wird, sondern durch den Typ des Objekts, auf das die Variable verweist.

Die CowVariable speichert einen Verweis auf ein WhaleObjekt und die printName()in der Klasse definierte Methode Whalewird aufgerufen.

Das ist nicht sehr offensichtlich. Denken Sie an die Hauptregel:

Der Satz an Methoden, die für den Aufruf einer Variablen verfügbar sind, wird durch den Typ der Variablen bestimmt. Und die spezifische Methodenimplementierung, die aufgerufen wird, wird durch den Typ/die Klasse des Objekts bestimmt, auf das sich die Variable bezieht.

Das wird Ihnen immer wieder passieren. Je früher Sie sich also daran erinnern, desto besser.