比較表
比較基準 | インタフェース | 抽象クラス |
---|---|---|
基本 | 実装についてではなく要件についての知識しかない場合は、 "Interface"を使用します。 | 実装についてある程度知っているときは、「抽象クラス」を使います。 |
方法 | インタフェースは抽象メソッドのみを含みます。 | 抽象クラスは抽象メソッドと具象メソッドを含みます。 |
メソッドのアクセス修飾子 | 宣言していなくても、インタフェースメソッドは常に "Public"と "Abstract"です。 したがって、それは100%、純粋な抽象クラスと言えます。 | 抽象クラスのメソッドがパブリックで抽象的であることは必須ではありません。 具体的な方法もあります。 |
メソッドの制限付き修飾子 | インタフェースメソッドは、次の修飾子を付けて宣言することはできません。 公開:非公開および保護 要約:ファイナル、スタティック、シンクロナイズ、ネイティブ、strictfp | 抽象クラス変数の修飾子に制限はありません。 |
変数のアクセス修飾子 | 宣言しているかどうかにかかわらず、インターフェース変数に使用できるAcess Modifierはpublic、static、finalです。 | 抽象クラスの変数はpublic、static、finalである必要はありません。 |
変数の制限付き修飾子 | インターフェイス変数は、private、protected、transient、volatileとして宣言できません。 | 抽象クラス変数の修飾子に制限はありません。 |
変数の初期化 | インターフェイス変数は宣言時に初期化する必要があります。 | 宣言時に抽象クラス変数を初期化する必要があることは必須ではありません。 |
インスタンスと静的ブロック | インターフェース内では、インスタンスや静的ブロックを宣言することはできません。 | 抽象クラスは、その中にインスタンスまたは静的ブロックを許可します。 |
コンストラクタ | インターフェース内でコンストラクタを宣言することはできません。 | 抽象クラス内でコンストラクタを宣言できます。 |
インタフェースの定義
Javaは多重継承を許可しません。 つまり、単一のクラスが一度に複数のクラスを継承することはできません。 この理由は、例で説明できます。 2つの親クラス、AとB、および派生クラスCがあるとします。派生クラスCはクラスAとBの両方を継承します。では、両方ともクラスAとBにメソッドset()があります。クラスCでは、どのクラスのset()メソッドを継承するべきか。 この問題の解決策は「インターフェース」です。
access_specifier インタフェース interface_name {戻り値の型メソッド名1(パラメータリスト); 戻りタイプmethod-name2(parameter-list); type final-varname1 = value; type final-varname2 = value; // ... return-typeメソッド名N(パラメータリスト); type final-varnameN = value; }
クラスはインタフェースを実装する必要があるため、アクセス指定子はpublicと宣言されています。
C ++には「インタフェース」という概念はありません。 しかし、JavaとC#はインターフェースを非常によく定義しています。
Javaのインターフェース:
- インターフェースの変数はデフォルトでは常にパブリック、スタティック、ファイナルです。
- 変数は宣言時に初期化する必要があります。
- 変数は、プライベート、保護、一時的、揮発性として宣言することはできません。
- インターフェースのメソッドは常にパブリックおよび抽象的ですが、プライベート、プロテクト、ファイナル、スタティック、同期、ネイティブ、およびstrictfpとして宣言することはできません。
- コンストラクタの主な目的はクラス変数の初期化であるため、インタフェース内でコンストラクタを宣言することはできませんが、インタフェース変数では宣言時に変数が初期化されます。
- インタフェースは他のインタフェースを継承できますが、そのようなインタフェースを実装するクラスはすべての継承されたインタフェースのメソッドを実装する必要があります。
- クラスは一度に複数のインタフェースを継承でき、継承したすべてのインタフェースのすべてのメソッドを実装する必要があります。
Javaでインターフェースを実装する一般的な形式は、次のとおりです。
class class_nameはInterface_name {// class-body}を実装しています
インタフェースを継承するために、クラスはキーワード「implements」を使用し、クラスは継承されたインタフェースによって宣言されたすべてのメソッドを実装します。
C#のインタフェース:
C#のインタフェースは、Javaのインタフェースとほとんど同じです。
- C#のインタフェースは変数を宣言しません。
- インターフェースの名前には大文字のIが頭に付けられ、コロン(:)記号で継承されます。
C#でインターフェースを実装する一般的な形式は次のとおりです。
クラスclass_name:interface_name {// class-body}
抽象クラスの定義
1つ以上の抽象メソッドを含むクラスは抽象クラスと呼ばれ、クラス宣言の先頭に「class」キーワードが付いたキーワード「abstract」を使用して抽象として宣言されます。 抽象クラスには抽象メソッドが含まれているため、不完全な型になります。 したがって、抽象クラスのオブジェクトを作成することはできません。 クラスが抽象クラスを継承するときはいつでも、抽象クラスのすべての抽象メソッドを実装する必要があります。そうしない場合は、抽象クラスとして宣言する必要があります。
抽象クラスには、派生クラスがそのまま利用できる具体的なメソッドを含めることもできます。 しかし、抽象クラス内で抽象コンストラクタや抽象静的メソッドを宣言することはできません。 Javaの抽象クラスの一般的な形式は次のとおりです。
抽象クラスclass_name {abstract method_name1(); abstract method_name2(); return_type method_name3(parameter_list){//具象メソッド} return_type method_name4(parameter_list){//具象メソッド}};
抽象クラスの概念は、JavaとC#の両方で似ています。 抽象クラスはC ++では少し異なります。
C ++では、クラスに少なくとも1つの仮想関数がある場合、そのクラスは抽象クラスになります。 キーワード「abstract」の代わりに、キーワード「virtual」を使用して抽象メソッドを宣言します。
JavaとC#のインタフェースと抽象クラスの主な違い
- 「必要なもの」についての知識があり、「それがどのように実装されるか」についての知識がない場合は、インターフェースを使用する必要があります。 一方、何が必要かを知っていて、それがどのように実装されるかを部分的に知っている場合は、抽象クラスを使用します。
- インタフェースはそのすべてのメソッドを抽象的にしますが、抽象クラスはいくつかの抽象メソッドといくつかの具象メソッドを持ちます。
- インターフェース内のメソッドはパブリックで抽象的であるため、純粋な抽象クラスとも呼ばれます。 一方、抄録内のメソッドは、パブリックおよび抄録のみに制限されていません。
- インターフェイスメソッドは、プライベート、保護、最終、静的、同期、ネイティブ、またはstrictfpになることはできません。 一方、抽象クラスのメソッドには制限がありません。
- インターフェイス内の変数は、宣言しているかどうかにかかわらず、公開されていて最終的なものです。一方、抽象クラスの変数が公開されて最終的なものであるという制限はありません。
- インターフェイス内の変数は、プライベート保護された一時的または揮発性にすることはできませんが、抽象クラスの変数には制限がありません。
- インターフェイスの変数は宣言中に初期化する必要があります。 一方、抽象クラスの変数はいつでも初期化できます。
- インターフェイスの中では、インスタンスまたは静的ブロックは宣言できませんが、抽象クラスの中でインスタンスまたは静的ブロックを宣言することはできます。
- コンストラクタをインタフェースの内部で定義することはできませんが、コンストラクタを抽象クラスの内部で定義することはできます。
結論:
必要に応じて派生クラスによって実装できる一般化された形式のメソッドを含む基本クラスを作成する必要がある場合は、インターフェイスと抽象クラスの概念が役立ちます。