Java
abstract
interface

インタフェースと抽象クラスどっち使ったらいいんだ?

More than 3 years have passed since last update.

どういうケースでどちらを使うかとか知りたかった。

まず結論からいうと多様な議論があるようだった。

だからこれを読んだかたは鵜呑みにせずにいっしょに考えてもらいたい。


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


結論、インタフェースって?

クラスの型(仕様)を定義するもの。

カプセル化多態性を要求する意味あいが強い。


結論、抽象クラスって?

継承関係をもつ実装の再利用をできる。

継承多態性を要求する意味あいが強い。


インタフェースとは


  • インタフェースのメンバ変数は必ず定数。自動でfinal public staticとなる。

  • 抽象メソッドのみ記述可能。自動でpublic abstractとなる。

  • 実装クラスは、全ての抽象メソッドを実装する必要ある

  • 多重継承できる。ミックスインというらしい。

  • 多重継承できるけど、メンバ変数は一意でなければならん

  • メソッドの場合は実装をもたないのでダブってても競合せず問題なし

  • 実装クラスはアップキャストしてインタフェース型変数に代入可能


抽象クラスとは


  • 抽象メソッドは必ず子クラスで実装されねばならない

  • 実装を持つメソッドも記述できる

  • クラスなので単一継承のみ。多重継承は不可

  • 共通機能を実装し、個別機能は抽象定義しておく

  • 抽象クラス使わないで継承するとアップキャストしたときにメソッドが使えなくなるとか起こりうる


結局どっちを使えばいいのか?

クラス仕様としての型定義したいならインタフェース。

継承関係にあって処理の再利用したいなら抽象クラス。

ってかんじか。

抽象クラスと派生クラスは「継承」の関係はIS A関係と呼ばれている対して、

インターフェイスと実装クラスの「実装」の関係はCAN DO関係と呼ばれているそうです。

(たぶん)たとえば、

public abstract class Animal {}

public class Rabbit extends Animal {}

はよい。Rabbit is an Animalであるから。=な関係。

public interface Jumpable {}

public class Rabbit implements Jumpable {}

はよい。Rabbit can jumpであるから。≠の関係。

超個人的感覚的な説明になるが、

実装クラスからみて、

抽象クラスは垂直に上な関係。

インタフェースは斜め上な関係、

はて。


参考URL