• 検索結果がありません。

WeightedPoint.java ( 重み付きの点クラス )

ドキュメント内 i I Java Java Java (ページ 175-178)

第 2 章 Java 言語の基本的な文法 I 5

3.32 WeightedPoint.java ( 重み付きの点クラス )

継承は連鎖的に行うことができます。つまり、クラスAがクラスBを継承し、そのクラスBが新たなクラスCを 継承するような状況です(図3.5参照)。このとき、クラスAのインスタンスを作成すると、そこには、クラスAで宣 言されたフィールドa(やメソッド)はもちろんのこと、クラス Bのフィールドb、クラスCで宣言されたフィール

ドcを持つことになります。

右の図は、クラスA のインスタンス instAを作成したときの概念的な図です。instA は、クラスA のインスタ ンスですから、フィールド aをもちろん持ちますが、クラス Bを継承しているので、フィールドb も持ち、同様に フィールドcも持つわけです。

A + a : int

B + b : int

C + c : int

int a

int b

int c

クラスBから 継承した部分

クラスCから 継承した部分 instA

クラスAのインスタンス型

図3.5 単一継承

クラス Cをスーパークラスとするクラスは、クラスBだけとは限りません。先に「人」クラスを「学生」クラスと

「教授」クラスが継承しましたよね。しかし、複数のスーパークラスを持つこと「多重継承(multiple inheritance)」は Javaでは許されていません。と言うか、ほとんどのオブジェクト指向言語は、多重継承を許していません (C++は許し ている)。Java のように多重継承を許さない継承方式を「単一継承(single inheritance)」方式と言います。

何か不便な気がする? そうですね。例えば、「水陸両用車」クラスと考えるとき、「自動車」と「船」の2つのクラス を定義して継承するのが順当な気がする。「電子ピアノ」は「ピアノ」と「電化製品」。「狼人間」は「狼」と「人間」。

これらができないJavaはC++に負けてる?

なぜJavaは単一継承を選択しているのでしょう。それを示す例が次のプログラムです。

ソースコード3.33 単一継承の理由 // 水陸両用車クラスが2つのクラスを継承できるとする

class AmphibiousCycle extends Car, Boat {

// どちらの speed drive() を継承したら良いのでしょう?

}

class Car { // 自動車クラス double speed; // 単位 km/h

void drive() { ・・・} // 陸上をタイヤで運転 }

class Boat { // 船クラス

double speed; // 単位 knot : 1knot = 1852m/h void drive() { ・・・} // 水上をスクリューで運航 }

多重継承を許すと、継承する2 つのスーパークラスに同じフィールドや同じメソッドが存在したら、サブクラスはその いずれを選択すべきか?の問題が生じます。また、同じクラスを重複して継承する問題も生じます (自動車のスーパー

クラスとしての乗り物クラスと船のスーパークラスとしての乗り物)。これらの問題を「菱形継承問題もしくはダイア モンド継承問題」と呼びます。

自動車

乗り物

drive()

drive() drive()

水陸両用車 drive()

図3.6 菱形継承問題

C++はそうした選択をプログラマに任せている(明にプログラム中で選ぶ)のですが、Java などはその危険性(プロ グラマを信じていない?)を重要視し、こうした多重継承を許していません。その代わりに、後で出てきます「インタ フェース」という「クラスもどき?」を用いて単一継承の不便さを解消しています。

なお、「スーパークラス・サブクラス」という言葉は、直接継承関係にある2つのクラス間の呼び方なので、クラスA からクラスCを見るとき、本来「スーパークラスのさらにスーパークラス」と言わないといけません。これはちょっ と不便なので、直接の継承関係になくとも、何段階かの継続関係にあるクラスの間で誤解が生まれない限り、このテキ ストでは「スーパークラス・サブクラス」の言葉を流用するか、ここだけの言葉として、「お爺さんのクラス・孫のクラ ス」などとよぶことにします。つまり、クラスCはクラスAのお爺さんクラスで、クラスA はクラスCの孫クラス である!と(孫のほうが一般に機能が多い!?)。

問題 3.4.2. 次の(a),(b),(c)のうち単一継承はどれですか。

A + a : int

B + b : int C

+ c : int

A + a : int

B + b : int C

+ c : int

A + a : int

B + b : int C

+ c : int

D + d : int

(a) (b) (c)

問題 3.4.3. 左のような継承関係のとき、そのいずれかのクラスのインスタンスを書いたのが右の図である。下線部に 適当なクラス名を入れ、3つのクラス内のフィールド名とメソッド名を右の図の妥当な場所に書き込みなさい。

A + x : double + y : double + length() : double

B + w : double

+ getWeight() : double

C + c : java.Color + getColor() : java.Color

クラス   のインスタンス クラス   の情報

クラス   の情報

ドキュメント内 i I Java Java Java (ページ 175-178)