web-dev-qa-db-ja.com

いつ抽象クラスの代わりにインターフェイスを使用する必要がありますか?

いつインターフェースを使用すべきか疑問に思っていました。

以下について考えてみましょう。

public abstract class Vehicle {
   abstract float getSpeed();
}

および:

public interface IVehicle {
  float getSpeed();
}

両方を簡単に実装できますが、機能は同じです。しかし、車両クラスに変数を追加することもできます。これは、おそらく車両で使用する必要があります(maxSpeed、carType ...)

インターフェイスを使用する理由は何ですか?

ありがとう!

EDIT:別のスレッドでそれに関する素敵なリンクを見つけました: http://www.thecoldsun.com/en/content/01 -2009/abstract-classes-and-interfaces

83
augmentie123

Java How to Program 抽象クラスについて:

これらは継承階層のスーパークラスとしてのみ使用されるため、抽象スーパークラスと呼びます。 これらのクラスは、抽象クラスが不完全であるため、オブジェクトのインスタンス化には使用できません。サブクラスは、「欠落したピース」を宣言して「コンクリート」クラスになる必要があります。オブジェクトをインスタンス化できます。そうでない場合、これらのサブクラスも抽象になります。

「インターフェイスを使用する理由は何ですか?」という質問に答えるには:

抽象クラスの目的は、他のクラスが継承して、共通の設計を共有できる適切なスーパークラスを提供することです.

インターフェイスとは対照的に:

インターフェースは、オブジェクトで呼び出すことができるメソッドのセットを記述しますが、はすべてに具体的な実装を提供しませんメソッド...クラスがインターフェイスを実装すると、そのクラスのすべてのオブジェクトはインターフェイスタイプとis-aの関係を持ち、のすべてのオブジェクトクラスは、インターフェイスで記述された機能を提供することが保証されています。これは、そのクラスのすべてのサブクラスにも当てはまります。

したがって、「インターフェイスをいつ使用すべきか疑問に思っていました」という質問に答えるために、完全な実装が必要な場合はインターフェイスを使用し、設計に部分的な部分が必要な場合は抽象クラスを使用する必要があると思います(再利用性のため)

97
kgdesouz

Oracleチュートリアル から:

インターフェイスとは異なり、抽象クラスには、staticおよびfinalではないフィールドを含めることができ、実装されたメソッドを含めることができます。このような抽象クラスは、部分的な実装を提供し、実装を完了するためにサブクラスに残すことを除いて、インターフェイスに似ています。抽象クラスに抽象メソッド宣言のみが含まれる場合、代わりにインターフェイスとして宣言する必要があります。

複数のインターフェースは、何らかの方法で相互に関連しているかどうかにかかわらず、クラス階層のどこにでもクラスで実装できます。たとえば、ComparableまたはCloneableを考えてください。

比較すると、抽象クラスは、実装の一部を共有するために最も一般的にサブクラス化されます。単一の抽象クラスは、多くの共通点を持つ抽象クラス(抽象クラ​​スの実装部分)によってサブクラス化されますが、いくつかの違いもあります(抽象メソッド)。

15

多くの場合、両方のクラスタイプで実装できます。

インターフェースは、少なくとも基本的な機能を持たなければならないクラスを定義する場合に役立ちます。 USBなどの実際のインターフェイスのように。

interface USB {
    public function sendPower(); //charge iphone for example
    public function sendData(); //iTunes
    public function recieveData();
}

オブジェクトを実装する方法がいくつかある場合は、抽象クラスを使用します。

abstract class MobilePhone {
    public function isIphone();

    public function charge() {
        //get some power, all phones need that
    }
}

class iPhone extends MobilePhone {
    public function isIphone() { return true; }
}
9
Daniel W.

抽象的な実装を介してインターフェースを使用することを検討する場合があります

  • 使用可能な抽象実装が希望どおりに機能せず、独自に作成したい場合
  • 既存のクラス(他のクラスから拡張される)があり、インターフェースの機能を実装する場合

一般的に、インターフェイスは、特に多重継承の欠如を克服するために導入されました

7
MadProgrammer

Java 8のリリース以来、インターフェースのデフォルトメソッドのサポートにより、interfaceabstractクラス間のギャップは減少しましたが、それでも大きな違いがあります。

  1. インターフェイスの変数はpublic static finalです。しかし、抽象クラスはprivate、protectedなどのような他のタイプの変数を持つことができます

  2. インターフェイスのメソッドはpublicまたはpublic staticですが、抽象クラスのメソッドはprivateおよびprotectedでも可能です

  3. abstract classを使用して、相互に関連するオブジェクト間の関係を確立します。 interfaceを使用して、無関係なクラス間の関係を確立します。

これをご覧ください 記事interfacein Javaの特別なプロパティについて8.インターフェイスのデフォルトメソッドの静的修飾子により、派生でコンパイルエラーが発生します@overrideを使用する場合はエラー。

この記事では、デフォルトメソッドがJava 8で導入された理由について説明します。コレクションAPIをJava 8で拡張して、ラムダ式をサポートします。

Oracle ドキュメントも参照して、違いをよりよく理解してください。

より良い方法で物事を理解するために、コード例でこの関連するSEの質問を見てください:

インターフェイスクラスと抽象クラスの違いをどのように説明したらよいですか?

3
Ravindra babu

から Java™チュートリアル-インターフェイスと比較した抽象クラス

抽象クラスとインターフェースのどちらを使用すべきですか?

  • これらのステートメントのいずれかがあなたの状況に当てはまる場合は、抽象クラスの使用を検討してください:
    • いくつかの密接に関連するクラス間でコードを共有したい。
    • 抽象クラスを拡張するクラスには、多くの一般的なメソッドまたはフィールドがあるか、またはpublic以外のアクセス修飾子(protectedやprivateなど)が必要であることが予想されます。
    • 非静的または非最終フィールドを宣言します。これにより、それらが属するオブジェクトの状態にアクセスして変更できるメソッドを定義できます。
  • これらのステートメントのいずれかがあなたの状況に当てはまる場合は、インターフェースの使用を検討してください:
    • 無関係なクラスがインターフェイスを実装することを期待します。たとえば、インターフェイスComparableおよびCloneableは、多くの無関係なクラスによって実装されます。
    • 特定のデータ型の動作を指定したいが、その動作を誰が実装するかは気にしません。
    • 型の多重継承を利用したい場合。

JDKの抽象クラスの例は、AbstractMapです。これは、Collections Frameworkの一部です。そのサブクラス(HashMapTreeMap、およびConcurrentHashMapを含む)は、getが定義する多くのメソッド(putisEmptycontainsKeycontainsValue、およびAbstractMapを含む)を共有します。

3
Akash5288

サブクラスのグループに対して template を定義する場合は abstract クラスを使用し、少なくともサブクラスが使用できる実装コードがいくつかあります

他のクラスが再生できる role を定義する場合、 interface を使用します。どこに関係なくこれらのクラスは継承ツリーにあります

あなた extend 抽象クラス

あなた implement インターフェイス:)

interface では、すべてのフィールドは自動的にpublicstaticfinalになり、すべての methods publicになりますが、 abstract classは、ここで少し柔軟性を高めます。

2
user2768308

Javaの検討:

インターフェース:

  • 基本的なOOP抽象化です。
  • 多くの場合(常にではありませんが)、抽象クラスよりも明確なコードを生成します。
  • さまざまな状況に合わせて、複数の具象クラスで実装できます。
  • 多重継承を要求するシナリオを直接実装できます。
  • テスト目的でより簡単にモックアウトできます。
  • JDKプロキシに役立ちます(Java.lang.reflect.Proxyを参照)。

これらは、インターフェースと抽象クラスの賛否両論の非常に長いリストのほんの始まりにすぎません。

1
Arthur Dent

この質問の答えは非常に簡単です、インターフェイスでできることは抽象クラスAgreeでできます...インターフェイスを使用するときの答えは、多重継承のC#制限にあります。宣言するコントラクト(抽象)のみがあり、サブクラスにインターフェイスを実装させる場合、この場合に抽象クラスを使用すると、もう1つのクラスから継承できず、1つから継承したい場合にスタックするためより多くのクラスが、あなたは多くのインターフェイスを実装することができます。

1
Dinesh

これは、ブルース・エッケルの優れた本「 Thinking in Java 」からの抜粋です。

[..]interfaceまたはabstract classを使用する必要がありますか?

インターフェースは抽象クラスの利点とインターフェースの利点を提供するため、メソッド定義やメンバー変数なしで基本クラスを作成できる場合は、常に抽象クラスよりもインターフェースを優先する必要があります。

実際、何かが基本クラスになることがわかっている場合、最初の選択肢はそれをインターフェイスにすることであり、メソッド定義またはメンバー変数を強制する場合にのみ抽象クラスに変更する必要があります。

1
fortytwo

JDK 8を使用している場合、抽象クラスを使用する理由は何もありません。抽象クラスで行うことは何でも、デフォルトメソッドのためにインターフェースで実行できるようになったためです。抽象クラスを使用する場合は拡張する必要があり、一度しか拡張できないという制限があります。ただし、インターフェイスを使用する場合は、必要な数だけ実装できます。

インターフェースはデフォルトでは抽象クラスであり、すべてのメソッドとコンストラクターはパブリックです。

1
HM Nayem

Abstract Class:スーパークラスとサブクラスの間に強いis-a関係があり、すべてのサブクラスがいくつかの共通の動作を共有している場合に使用します。

インターフェース:すべてのサブクラスが従う必要があるプロトコルのみを定義します。

0
Ravi Soni

抽象クラスでは多重継承を実現できません。そのため、Sun Microsystemsはインターフェイスを提供しています。

2つのクラスを拡張することはできませんが、複数のインターフェイスを実装できます。

0
kavi temre

抽象クラスには抽象ではないメソッドを含めることができますが、インターフェイスではすべてのメソッドは抽象であり、実装する必要があります。

これらの特定のメソッドを常に実装することがわかっている場合は、代わりにインターフェイスを使用する必要があります。また、複数のインターフェイスから継承することもできます。これは、複数の継承を処理するJavaの方法です

0
Will Jamieson

実際には、インターフェイスと抽象クラスは、サブクラスがどのようになるかを示すだけのコントラクト/ルールを指定するために使用されます。

ほとんどの場合、インターフェイスは純粋な抽象であることを知っています。つまり、bodyで単一のメソッドを指定することはできません。この特定のポイントは、abstractクラスの利点です。

だから、もしあなたがサブクラスについて何かを指定したいなら、インターフェースに行くかもしれません。しかし、もしuがurサブクラスに何かを指定したいなら、また、あなたはurクラスにも独自のメソッドを持たせる必要があります。その場合、uは抽象クラスになります。

0
sridhar

インターフェースは基本的に、2つのパーティが連携して動作し、一方のパーティが他のパーティから何かを隠したい(またはクラスの一部のみを表示したい)場合に使用されます。 jdbcでは、jdbcベンダーは、すべてを非表示にするインターフェイスをいくつか提供しています。

抽象クラスは、複数のクラスで共通の動作をサポートする場合、または実装されていないメソッドを実装済みの実装に提供する場合にのみ使用されます(メソッドは抽象である必要があります)。例えば。サーブレットインターフェイスのhttpサーブレットは、このクラスがサービスメソッドを除いてサーブレットインターフェイスを実装する抽象クラスbcozです。したがって、このクラスは、インターフェイスメソッドの事前実装を支援します。

0
praveen tyagi

InterfaceAbstract Classは、OOP言語で抽象化を実現する2つの異なる方法です。

インターフェイスは100%抽象化を提供します。つまり、すべてのメソッドは抽象です。

抽象クラスは0 to 100%抽象化を提供します。つまり、抽象メソッドを持つ場合と持たない場合があります。

型のすべての機能をクライアントで実装する場合は、Interfaceを使用できます。

Abstract Class実装者がいくつかの共通機能を提供でき、クライアントが実際に必要なものを実装する機会を与えられる場合、Abstract Classを使用できます。

0
Raghu