26
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
26
Help us understand the problem. What are the problem?