Javaのインターフェイス(interface)、抽象クラス(abstract)については、
2つセットで語られる事が多いように思います。
それは両者の違いが分かりづらく、
どのように使い分けたら良いのかピンと来ない事が多いからだと思います。
そこで、この2つの概念の違いを挙げて、
両者の使い分け方を明確にしてみたいと思います。
【違い1】定義するもの
- インターフェイス → 「型」
- 抽象クラス → 「クラス」
そもそも、両者が定義しているものの次元に違いがあるようです。
インターフェイスはクラスの「型」を定義するものであり、
抽象クラスはそれを実装した「クラス」を定義するものという違いです。
【違い2】多重継承の可否
- インターフェイス → 「可」
- 抽象クラス → 「不可」
「型」を定義するインターフェイスを多重継承することはできても、
「クラス」を定義する抽象クラスは多重継承ができない。
これを現実に言い換えれば、
「電話」型、「カメラ」型を実装した「携帯電話」クラスは存在できても、
「Android」クラスであり、「iPhone」クラスでもある「携帯電話」クラスは存在できない、
といった所だと思います。
【違い3】実装の可否
- インターフェイス → 「不可」
- 抽象クラス → 「可」
インターフェイスはあくまで型という「設計図」なのに対し、
抽象クラスは「モノ」そのものです。
さらに例えれば、
ラジコンの設計図の前に電池は意味をなしませんが、
ラジコン本体のエネルギー源としては意味があり、
そこにニッカド電池を使うことも、ニッケル水素電池を使うことも可能、
といったイメージです。
今までの概念の違いを踏まえると、
次のような使い分け方が考えられます。
下記に当てはまる場合は、インターフェースを使用する。
【使い分け1】インターフェースを使用する場合
- 既存クラスで使用する
- 型体系を意識させる必要がない
- 実装に大差が生じる可能性がある
逆に、インターフェースでは当てはまらない、
下記のような場合は、抽象クラスを使用する。
【使い分け2】抽象クラスを使用する場合
- 既存クラスで使用しない
- 型体系を意識させる必要がある
- 実装に大差が生じる可能性がない
こうして見ると、
インターフェースの方が概念的にシンプルである分、自由度が高いです。
しかし、あえて抽象クラスを使うことによって、コードの可読性が向上する事もあると思います。
正確な理解と適切な判断によって、
コードの品質を高めていきたいものですね。