LoginSignup
26
27

More than 5 years have passed since last update.

Effective Java 18章 抽象クラスよりインタフェースを選ぶ

Last updated at Posted at 2013-01-17

Effective Javaの18章「抽象クラスよりインタフェースを選ぶ」を読んだので軽くまとめます。

インターフェースと抽象クラスの違い

インターフェースと抽象クラスは、複数の実装を許す為の仕組みの1つである。
両者の違いは、抽象クラスはメソッドの実装を持てるのに対してインターフェースは持てないことである。
インターフェースはクラス階層のどこに属していても実装できる。抽象クラスもどの階層においても実装できるが、Javaでは単一継承しか許されていない為、型定義をする為に抽象クラスを使用するのは非常に不便になる。
例えば、2つの異なるクラスA, Bに対して、抽象クラスCを実装させたいとする。その場合、AとBの祖先がCになるように実装しなければならない。ここで問題になるのは、AとBに関係ないクラスまでCを実装する必要が出て来てしまうことである。

ミックスイン

複数のインターフェースを混ぜ合わせて振る舞わせることをミックスインと呼ぶ。たとえば、以下のようなSingerインターフェースとSongwriterインターフェースがあるとする。

Singer.java
public interface Singer {
    AudioClip sing(Song s);
}
Songwriter.java
public interface Songwriter {
    Song compose(boolean hit);
}

これらをミックスインし、以下のようなSingerSongwriterインターフェースを定義できる。

SingerSongwriter.java
public interface SingerSongwriter extends Singer, Songwriter {
    AudioClip strum();
    void actSensitive();
}

これは抽象クラスでは実現出来ない。なぜなら、Javaではクラスは2つ以上の親を持つこと(多重継承)ができないから。無理に継承を使って実装しようとすると、組み合わせ爆発(combinational explosion)が起こり、クラス階層が膨れ上がる。

骨格実装

Javaではインターフェースに実装を含むことは許されていないが、それ単体で提供しても実装者の負担になるだけである。そこで、インターフェースと一緒に骨格実装クラスを提供することでその問題を解決する。
骨格実装クラスはAbstractInterfaceと呼ばれ、Javaの主要なCollection Frameworkではそれが提供されている。例えば、 List インターフェースに対しては AbstractList が提供されている。
ほとんどの場合、骨格実装を拡張してインターフェースを実装することを選択すべきである。

骨格実装を作る場合、それが継承して使われることを想定して実装すべきである。ドキュメントと設計の指針に正しく従って設計を行う。

インターフェースの変更は困難

一度リリースされたpublicなインターフェースに対し、後から変更を加えることは非常に難しい。
このような問題を回避する為、正式リリース前にできるだけ多くのプログラマにこのインターフェースを使って実装してもらい、欠陥を早期に発見できるようにすると良い。インターフェースは最初から正しい設計をする必要がある。

26
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
27