1. Men det er ikke alt.

Anta at Cowklassen har en printAll()metode som kaller to andre metoder. Da vil koden fungere slik:

Kode Beskrivelse
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();
}
Skjermutgangen vil være:
I'm a white whale
I'm a whale

Merk at når printAll()metoden i Cowklassen kalles på et Whaleobjekt,printNameWhale brukes metoden til klassenCow , ikke den i metoden.

Det viktigste er ikke klassen metoden er skrevet i, men snarere typen (klassen) til objektet som metoden kalles på.

Bare ikke-statiske metoder kan arves og overstyres. Statiske metoder er ikke arvet og kan derfor ikke overstyres.

Slik Whaleser klassen ut etter å ha brukt arv og metodeoverstyring:

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");
   }
}
Slik Whaleser klassen ut etter å ha brukt arv og metodeoverstyring: Vi vet ikke om noen gammel printNamemetode.

2. Typecasting

Det er et enda mer interessant poeng her. Fordi en klasse arver alle metodene og dataene til den overordnede klassen, kan en referanse til et objekt i den underordnede klassen lagres i (tilordnet til) variabler hvis type er den samme som den overordnede klassen (og den overordnede klassen, etc. — helt opp til Objectklassen). Eksempel:

Kode Beskrivelse
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printColor();
}
Skjermutgangen vil være:
I'm a white whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printColor();
}
Skjermutgangen vil være:
I'm a white whale
public static void main(String[] args)
{
   Object o = new Whale();
   System.out.println(o.toString());
}
Skjermutgangen vil være:
Whale@da435a.

Metoden toString()er arvet fra Objectklassen

Dette er en veldig verdifull eiendom: litt senere vil du forstå hvordan du bruker den i praksis.


3. Kalle en metode på et objekt

Når en metode kalles på en variabel, kalles metoden faktisk på et objekt. Denne mekanismen kalles dynamisk metodeutsendelse.

Slik ser det ut:

Kode Beskrivelse
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
Skjermutgangen vil være:
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
Skjermutgangen vil være:
I'm a whale

Merk at den spesifikke implementeringen av printName()metoden som blir kalt — den i Coweller den i Whaleklassen — ikke bestemmes av variabelens type, men av typen objekt som variabelen refererer til.

Variabelen Cowlagrer en referanse til et Whaleobjekt, og printName()metoden som er definert i Whaleklassen er det som kalles.

Dette er ikke veldig åpenbart. Husk hovedregelen:

Settet med metoder som er tilgjengelige for å bli kalt på en variabel, bestemmes av variabelens type. Og den spesifikke metodeimplementeringen som blir kalt, bestemmes av typen/klassen til objektet som variabelen refererer til.

Du vil støte på dette hele tiden, så jo før du husker dette, jo bedre.