今回は「多重継承」のお話。
お久しぶりのinterfaceです。
以前質問だけ受けて解説しなかった「多重継承」のお話をしていきましょう!


そういやありましたね!「多重継承」
ていうか、もう忘れてましたよ!
なぜにいま?
( ̄∇ ̄;)ハッハッハ
それは私の気まぐれです。
しゃべりたいときにしゃべる、気まぐれ進行です。

interfaceのイメージとメリットについては以前お話しましたので、そちらを参照ください。
多重継承のメリット・デメリット
Java言語の仕様の一つに「クラス」があります。
Java登場以前にC++は既に存在しており、C言語にオブジェクト指向機能、主に「クラス」を付け加えた言語がC++です。
C++では多重継承を許可しています。

ん?
そうすると、Javaは多重継承を否定しているから、C++よりも劣る?
そうではありません。
実は多重継承は諸刃の剣。たくさんの機能を引き継げるのはメリットなのですが、しばしば不具合の原因にもなっていました。
不具合のもととなる例の一つが「菱形継承」です。
UMLのクラス図でのイメージはこう:

クラス「A」を「B」「C」で継承して、クラス「D」は「B」「C」を継承しています。
これ、やりようによるのですが、C++のデフォルトの動作ですと、メモリ上のイメージはこうなります:


あれ、「A」は一個じゃないんですか?
そうなんです。「A」は一つに見えてメモリ上は2つに分かれてしまうのです。回避の方法はありますが、何も考えずに実装してしまうとこういうことが起こります。
そうした場合、
- 「B」経由の「A」が持つメンバ変数a
- 「C」経由の「A」が持つメンバ変数a
のそれぞれに個別に値を設定する必要が出てくるので面倒なのです。
片一方には設定したけど、もう片一方には設定していない、のような場合に意図しない動作が起きてしまい、これが不具合となるのです。

へ~、多重継承って危険じゃないですか…
そこでJavaは多重継承をやめました。
シンプルに単一継承。
これでめでたしめでたし!
ではなかった。
interfaceの導入
やっぱり多重継承をしたい状況というのはある。しかしそれを許すと複雑さを増加させてしまう。
そこで導入されたのがinterfaceなのです

interfaceは多重継承を許可する代わり、中身が空っぽ。
変化するデータや実装を持たない、というルールにしたのです。
(※Java8からinterfaceにもデフォルトメソッドが導入されたため、実装は持てるようになりました。ただし依然としてデータは持ちません。)
そもそもデータを持たないため、菱形継承が起きても2個や3個のデータが出来上がることがない。
ちなみにC#も同様ですね。と言いますか、当初C#はJavaの影響をモロに受けていたため当然です。

いやー、Javaは奥が深い…
プログラムが書けるようになったーと思っても、わからないことばかりですね
確かにそうですねー。
興味を持って進めていれば、そのうち全体が見えてきます。
焦らずにプログラミングを楽しんでくださいね~

まとめ
- 多重継承を行った場合、データの重複など、プログラムが複雑になる傾向がある
- Java(やC#)はクラスの多重継承を禁止した
- 代わりにinterfaceでの多重継承を許可した
- interfaceはデータを持つことを禁止したためデータの重複は回避されている