1. Maar dat is niet alles.

Stel dat de Cowklasse een methode heeft printAll()die twee andere methoden aanroept. Dan werkt de code als volgt:

Code Beschrijving
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();
}
De schermuitvoer is:
I'm a white whale
I'm a whale

Merk op dat wanneer de printAll()methode in de Cowklasse wordt aangeroepen op een Whaleobject, de printNamemethode van deWhale klasse wordt gebruikt, niet die in de Cowmethode.

Het belangrijkste is niet de klasse waarin de methode is geschreven, maar eerder het type (klasse) van het object waarop de methode wordt aangeroepen.

Alleen niet-statische methoden kunnen worden overgenomen en overschreven. Statische methoden worden niet overgeërfd en kunnen daarom niet worden overschreven.

Zo Whaleziet de klasse eruit na het toepassen van overerving en methode-overheersing:

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");
   }
}
Zo Whaleziet de klasse eruit na het toepassen van overerving en methode-overheersing: We kennen geen enkele oude printNamemethode.

2. Typecasten

Er is hier een nog interessanter punt. Omdat een klasse alle methoden en gegevens van zijn bovenliggende klasse overerft, kan een verwijzing naar een object van de onderliggende klasse worden opgeslagen in (toegewezen aan) variabelen waarvan het type hetzelfde is als de bovenliggende klasse (en de bovenliggende klasse, enz. ) tot in de Objectklas). Voorbeeld:

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

De toString()methode wordt geërfd van de Objectklasse

Dit is een zeer waardevolle eigenschap: even later zul je begrijpen hoe je het in de praktijk kunt gebruiken.


3. Een methode aanroepen op een object

Wanneer een methode wordt aangeroepen op een variabele, wordt de methode eigenlijk aangeroepen op een object. Dit mechanisme wordt dynamische methodeverzending genoemd.

Zo ziet het eruit:

Code Beschrijving
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
De schermuitvoer is:
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
De schermuitvoer is:
I'm a whale

Merk op dat de specifieke implementatie van de printName()methode die wordt aangeroepen - die in de Cowof die in de Whaleklasse - niet wordt bepaald door het type van de variabele, maar door het type object waarnaar de variabele verwijst.

De Cowvariabele slaat een verwijzing naar een Whaleobject op en de printName()methode die in de Whaleklasse is gedefinieerd, wordt genoemd.

Dit is niet erg duidelijk. Onthoud de hoofdregel:

De set methoden die beschikbaar zijn om op een variabele te worden aangeroepen, wordt bepaald door het type van de variabele. En de specifieke methode-implementatie die wordt aangeroepen, wordt bepaald door het type/de klasse van het object waarnaar de variabele verwijst.

Je zult dit de hele tijd tegenkomen, dus hoe eerder je dit onthoudt, hoe beter.