1. しかしそれだけではありません。

クラスに、他の 2 つのメソッドを呼び出すメソッドCowがあるとしますprintAll()。すると、コードは次のように動作します。

コード 説明
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();
}
画面出力は次のようになります。
I'm a white whale
I'm a whale

printAll()クラス内のメソッドがオブジェクトに対してCow呼び出される場合、メソッド内のメソッドではなく、クラスのメソッドが使用されることに注意してください。WhaleprintNameWhaleCow

重要なのは、メソッドが記述されているクラスではなく、メソッドが呼び出されるオブジェクトの型 (クラス) です。

継承およびオーバーライドできるのは、非静的メソッドのみです。静的メソッドは継承されないため、オーバーライドできません。

Whale継承とメソッドのオーバーライドを適用した後のクラスは次のようになります。

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");
   }
}
継承とメソッドのオーバーライドを適用した後のクラスは次のようになります。 古いメソッドWhaleについてはわかりません。printName

2. タイプキャスト

ここにはさらに興味深い点があります。クラスは親クラスのすべてのメソッドとデータを継承するため、子クラスのオブジェクトへの参照は、親クラス(および親の親など)と同じ型の変数に格納 (割り当て) できます。クラスまでずっとObject)。例:

コード 説明
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printColor();
}
画面出力は次のようになります。
I'm a white whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printColor();
}
画面出力は次のようになります。
I'm a white whale
public static void main(String[] args)
{
   Object o = new Whale();
   System.out.println(o.toString());
}
画面出力は次のようになります。
Whale@da435a.

メソッドはクラス toString()から継承されますObject

これは非常に貴重なプロパティです。実際にそれを使用する方法は、少し後で理解できるようになります。


3. オブジェクトのメソッドを呼び出す

メソッドが変数に対して呼び出される場合、そのメソッドは実際にはオブジェクトに対して呼び出されます。このメカニズムは、動的メソッド ディスパッチと呼ばれます。

その様子は次のとおりです。

コード 説明
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printName();
}
画面出力は次のようになります。
I'm a whale
public static void main(String[] args)
{
   Cow cow = new Whale();
   cow.printName();
}
画面出力は次のようになります。
I'm a whale

呼び出されるメソッドの特定の実装printName()( 内のメソッドCowまたはクラス内のメソッドWhale)は、変数の型によってではなく、変数が参照するオブジェクトの型によって決定されることに注意してください。

変数Cowにはオブジェクトへの参照が格納されWhale、クラスprintName()で定義されたメソッドWhaleが呼び出されます。

これはあまり明らかではありません。主なルールを覚えておいてください。

変数に対して呼び出すことができるメソッドのセットは、変数の型によって決まります。 そして、呼び出される特定のメソッド実装は、変数によって参照されるオブジェクトの型/クラスによって決まります。

これは常に遭遇することになるため、これを覚えるのは早ければ早いほど良いでしょう。