web-dev-qa-db-ja.com

抽象クラスまたはインターフェースをいつ使用するのですか?

抽象クラスまたはインターフェイスクラスが作成されるのはなぜですか、または抽象クラスまたはインターフェイスクラスをいつ使用する必要がありますか?

27
JavaResp

インターフェイスは、クラスが持つ必要のあるメソッドとメンバーのみを宣言する場合に使用されます。インターフェイスを実装する人は誰でも、インターフェイスによってリストされたメソッドを宣言して実装する必要があります。

デフォルトの実装も必要な場合は、抽象クラスを使用してください。抽象クラスを拡張するクラスは、その抽象メソッドとメンバーのみを実装する必要があり、オーバーライドするかどうかに関係なく、抽象クラスの他のメソッドのデフォルトの実装がいくつかあります。

-編集-言及するのを忘れた、Earwickerは私に思い出させた

最後に、必要な数のインターフェイスを実装できますが、拡張できるのは1つのクラスのみです(抽象的かどうかは関係ありません)。選択する前にそれを覚えておいてください。

40
Samuel Carrijo

主な違いは、クラス内で複数のインターフェイスをimplementできますが、単一の抽象クラスはextendしかできないことです。これは、抽象クラスはデータを格納するフィールドも定義できるのに対し、インターフェイスは定義できないためです。

16

抽象クラスは、少なくとも1つの抽象メソッドを持つクラスです。または、すべてのメソッドを抽象として作成することもできます。明らかに、インスタンス化することはできません。抽象クラスから継承し、継承クラス(つまり、抽象クラスを拡張するクラス)に抽象メソッドを実装する必要があります。

インターフェイスはクラスではありません(したがって、インターフェイスクラスとは呼ばないでください)。インターフェイスは、実装なしでメソッドのシグネチャを定義します。また、インターフェイスにはメンバーフィールドがありません。クラスにインターフェースを実装する場合は、インターフェースによって提供されるすべてのメソッドの実装を提供する必要があります。

完全に異なる実装を持つことができるいくつかのもののために一般化されたAPIを定義することは理にかなっています。抽象クラスは、主に同じことを行うクラスに役立ちますが、微妙な違いがいくつかあります。両方のアプローチを組み合わせることができます。

良い例は、Javaクラスライブラリの コレクションフレームワーク です。リストの動作を定義するインターフェイスListがあります。一部の実装はたとえばArrayListです。とLinkedList。これらは同様に動作するため、両方で同じように機能するものは抽象クラスAbstactListに実装され、どちらもこれを継承します。

11
Mnementh

インターフェースは基本的に「契約」を参照してください。インターフェイスを定義するときは、コントラクトを定義します。抽象クラスが拡張される場合、インターフェースが実装されます。

例を考えてみましょう。

_public interface Friend {
void hello();
}
_

これで、Friendを実装するクラスはメソッドhello()の定義を提供する必要があるというコントラクトを定義しました。

実装は次のとおりです。

_public class myFriend implements Friend {
public void hello()
println("Done");
}
_

これで、myFriendが契約を履行しました。ここで問題となるのは、インターフェースはどこで使用すべきかということです。

インターフェイスは、実装する必要のある動作を定義するのに役立ちます。いくつかの機能を定義するクラスAがあるとします。他のクラスが特定の動作(メソッド)を定義する場合にのみ、このクラス機能を使用するようにします。インターフェイスに関してこの制限を適用します。

3
Duleb

SamuelCarrijo この質問にうまく答えたようです。

Javaの場合、一部のフレームワークでは、操作するためのインターフェースが必要です。私は(たとえば) 動的プロキシ 、またはいくつかのクライアント/サーバープロキシフレームワークについて考えています。これは、オブジェクトのイントロスペクションを使用して、オブジェクトによって実装されたインターフェイスによって実装されたメソッドを判別するためです。そのため、通常は気にしないオブジェクトのインターフェイスを実装する必要がある場合があります。

thisインターフェースの理由はJavaに固有です。

2
Brian Agnew

抽象クラスは、継承階層を構築するときに使用されます。ただし、ほとんどの継承階層は「深く」なりすぎないようにする必要があります(つまり、継承のレベルが多すぎます)。多くのオブジェクト指向設計の本は、継承よりもインターフェースを好むでしょう(私が一度読んだある本は、「継承は、実装しない最もクールな[オブジェクト指向]機能です」と開発者を引用しました)。これにより、クラスに動作を割り当てることができます。契約による」、ここで契約はインターフェースです。

Samuelcarrijoの答えに注目する価値があります。メソッドのデフォルトの実装が必要な場合は、メソッドの具体的な実装を持つ抽象クラスを使用して、デフォルトの実装を提供する必要があります。このデフォルトの実装は、子クラスでオーバーライドできます。

お役に立てれば!

1
Scott Davies