next up previous
: 継承の問題点(1) : オブジェクト指向言語 Java : 多重定義

オーバーライド

継承の応用として,親クラスと同じメソッド名 (以下 A としよう) を定 義することを考えることができる.このメソッドは,親の同じ名前のメソッド を オーバーライド(override) した,という. オーバーライドとは,継承と同じように定義するが,意味的に逆に,親のメ ソッドの機能を否定している点に注意しよう. 例えば以下のプログラムを考える.
public class A {
  public void A1() {
    System.out.println("calling A1 of A.");
  }
  public void A2() {
    System.out.println("calling A2 of A.");
  }
  public static void main(String args[]) {
    A a = new A(); B b = new B();
    a.A1(); b.A1(); b.A2();
  }
}
class B extends A {
  public void A1() {
    System.out.println("calling A1 of B.");
  }
}
このプログラムを実行すると,以下のようになる.
calling A1 of A.
calling A1 of B.
calling A2 of A.
一行目は, a.A1() に相当する処理で,クラス A より生成したオ ブジェクト a のメソッドを呼出し, 二行目は, b.A1() に相当する処理で,クラス B より生成したオ ブジェクト b でオーバーライドしたメソッドを呼出している. 最後の行では, b.A2() に相当する処理で,クラス B が 親クラス A で定義されたメソッド A2 を継承したことを示して いる.

「継承」さらに,ここで定義した「オーバーライド」を多用すればより複雑な関係な どを記述することができるが,慣れないとどのような処理をするかわからな くなるので注意が必要である.例えば,上の例で main メソッドでの オブジェクト生成で,

A a = new B();
と宣言することも可能である.
クラス A のサブクラス B より生 成されたインスタンスは,クラス A の性質も持つためクラス A のイン スタンス(Java では 型 A) としても認識することが可能である. この性質は,以下の命題が成立する.
命題1
クラス $A$ のインスタンス $a$$a:A$ と書き,クラス $A$$B$ に対し て,クラス $B$ はクラス $A$ のサブクラスである時,$B\ll A$ と書くこと にする.この時 $b:B$ かつ $B\ll A$ であるならば $b:A$ である.

この性質を サブシューム(subsume) という.また,クラス $B$ から生 成されたインスタンス $b$ は,クラス $A$ に「サブシュームされた」という. この性質は,Java のような 「クラス=型」 とするオブジェ クト指向言語で成立する性質である5

さて,この性質を使って,

A a = new B();
このように書き換えた場合,
a.A1();
は,クラス A で定義された
メソッド A1 を呼出すのであろうか. それとも,クラス B で定義されたメソッド A1 を呼出すで あろうか.前者は,メソッドが 静的に束縛された(statically binded) オブジェクト指向言語で採用される性質であり,後者は,メソッドが 動的に束縛された(dynamically binded) オブジェクト指向言語で採用 される性質である.一般には,どちらともいえないが Java はどちらの性質も もつであろうか.読者の課題にしたい6
平成12年8月9日