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

継承の問題点(2)

最近のオブジェクト指向の研究では,
クラス≠型

が常識である.それは「クラス=型」にすると以下のような問 題が知られているからである.Java で示そう.
public class Food {
  private String name;
  Food(String f) { name = f; }
  public static void main(String args[]) {
    Person p = new Person();
    Vegetarian v = new Vegetarian();
    Vegetable v1 = new Vegetable("Cabbage");
    Food f1 = new Food("Meat");
    System.out.println(
      "Can a person eat cabbages? "+p.Eat(v1));
    System.out.println(
      "Can a person eat meats? "+p.Eat(f1));
    System.out.println(
      "Can a vegetarian eat cabbages? "+
      v.Eat(v1));
    System.out.println(
      "Can a vegetarian eat meats? "+v.Eat(f1));
  }
}
class Vegetable extends Food {
  String name;
  Vegetable(String s) { super(s); name = s; }
}
class Person {
  public boolean Eat(Food f) { return true; }
}
class Vegetarian extends Person {
  public boolean Eat(Vegetable v){return true;}
}
このプログラムでは,
人間( Person) と菜食主義者( Vegetarian) $\hbox{\tt Vegetarian}\ll\hbox{\tt Person}$, 食べ物( Food) と野菜( Vegetable) $\hbox{\tt Vegetable}\ll\hbox{\tt Food}$ を定義した. 各々「食べ物」は,野菜,肉すべての食べ物を含んでいるので,肉(meats) を 定義し,「野菜」は,キャベツ(cabbages) を定義した. その結果,人間,菜食主義者が各々「肉」を食べることができるか, 「野菜」を食べることができるか.を問い合わせてみた。 このプログラムを実行すると,以下のようになる.
Can a person eat cabbages? true
Can a person eat meats? true
Can a vegetarian eat cabbages? true
Can a vegetarian eat meats? true
このように「菜食主義者」(vegetarian) が,「肉を食べることが出来てしま う」(最後の行) が問題である.この原因として,「菜食主義者」は,「人間」の サブクラスであるので, Eat(Vegetable v) に当てはまらない場合は, 人間の Eat(Food f) を継承してしまうためである. そもそも,「菜食主義者」は,「人間」のほとんどの性質を継承するが, 「野菜以外の食べ物は食べない」ことを表現するために,オーバーライドを利 用するが,うまく表現できない.

では,例えば,

class Vegetarian {
  public boolean Eat(Vegetable v){return true;}
}
とすれば,
そさそうであるが,菜食主義者といえども人間であるので その性質を受け継ぐ関係は必要である.

一般に,このような時は(Java では書けないが), TypeOperator を使う ことが知られている.結果として,人間と菜食主義者のサブタイプ関係は成り 立つ.

TypeOperator Person[F<:Food] {
  public boolean Eat(F f) { return false; }
}
TypeOperator Vegetarian[V<:Vegetable] {
  public boolean Eat(V v) { return ture; }
}
として,
ある Vegetable のインスタンス v に対 して $\hbox{\tt Vegetarian[v]}<:\hbox{\tt Person[v]}$ が成立するようにすることができる. v の代わりに,すべての Food のインスタンス f では 成立しない.

結果として $\hbox{TypeOf}(b)<:\hbox{TypeOf}(a)\Rightarrow B\ll A$ であるが,逆は成立しない関係である.ここで,クラス $A$$B$ のインスタン スを $a$$b$ とし,更に,その型を $\hbox{TypeOf}(a)$$\hbox{TypeOf}(b)$ と書く.$b$ の型が $a$ の型のサブタイプである時 $\hbox{TypeOf}(a)<:\hbox{TypeOf}(b)$ とする.


平成12年8月9日