1. Men det är inte allt.

Anta att Cowklassen har en printAll()metod som anropar två andra metoder. Då kommer koden att fungera så här:

Koda Beskrivning
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();
}
Skärmutgången blir:
I'm a white whale
I'm a whale

Observera att när printAll()metoden i Cowklassen anropas på ett Whaleobjekt,printNameWhale används klassens metodCow , inte metoden i metoden.

Huvudsaken är inte klassen metoden är skriven i, utan snarare typen (klassen) av objektet som metoden anropas på.

Endast icke-statiska metoder kan ärvas och åsidosättas. Statiska metoder ärvs inte och kan därför inte åsidosättas.

Så här Whaleser klassen ut efter att ha tillämpat arv och metodöverstyrning:

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");
   }
}
Så här Whaleser klassen ut efter att ha tillämpat arv och metodöverstyrning: Vi känner inte till någon gammal printNamemetod.

2. Typecasting

Det finns en ännu mer intressant punkt här. Eftersom en klass ärver alla metoder och data från sin överordnade klass, kan en referens till ett objekt i den underordnade klassen lagras i (tilldelade) variabler vars typ är densamma som förälderklassen (och förälderns överordnade, etc. — ända upp till Objectklassen). Exempel:

Koda Beskrivning
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printColor();
}
Skärmutgången blir:
I'm a white whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printColor();
}
Skärmutgången blir:
I'm a white whale
public static void main(String[] args)
{
   Object o = new Whale();
   System.out.println(o.toString());
}
Skärmutgången blir:
Whale@da435a.

Metoden toString()ärvs från Objectklassen

Detta är en mycket värdefull egenskap: lite senare kommer du att förstå hur du använder den i praktiken.


3. Anropa en metod på ett objekt

När en metod anropas på en variabel anropas metoden faktiskt på ett objekt. Denna mekanism kallas dynamisk metodsändning.

Så här ser det ut:

Koda Beskrivning
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
Skärmutgången blir:
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
Skärmutgången blir:
I'm a whale

Observera att den specifika implementeringen av printName()metoden som anropas — den i Coweller den i Whaleklassen — inte bestäms av variabelns typ, utan av typen av objekt som variabeln refererar till.

Variabeln Cowlagrar en referens till ett Whaleobjekt, och printName()metoden som definieras i Whaleklassen är vad som kallas.

Detta är inte särskilt uppenbart. Kom ihåg huvudregeln:

Uppsättningen av metoder som är tillgängliga för att anropas på en variabel bestäms av variabelns typ. Och den specifika metodimplementeringen som anropas bestäms av typen/klassen för objektet som variabeln refererar till.

Du kommer att stöta på detta hela tiden, så ju förr du kommer ihåg detta, desto bättre.