10

私の経験から、次のことが正しいと思います。重要な点が欠けている場合はお知らせください。

インターフェース:

インターフェイスで宣言されたすべてのメソッドは、サブクラスで実装する必要があります。インターフェイスに存在できるのは、イベント、デリゲート、プロパティ (C#)、およびメソッドのみです。クラスは複数のインターフェイスを実装できます。

抽象クラス:

サブクラスで実装する必要があるのは抽象メソッドのみです。Abstract クラスは、実装を伴う通常のメソッドを持つことができます。抽象クラスは、イベント、デリゲート、プロパティ、およびメソッドの横にクラス変数を持つこともできます。C# には複数継承が存在しないため、クラスは 1 つの抽象クラスのみを実装できます。

その違いでさえ質問を説明しません

1) 抽象メソッドだけを持つ抽象クラスがあるとしたら? それはインターフェースとどのように違うでしょうか?

2) インターフェイス内にパブリック変数があるとしたら、それは抽象クラスとどのように異なるでしょうか?

したがって、説明はさまざまです。

4

12 に答える 12

4

技術的な違いに加えて、主に設計の意図によって、どちらを使用するかを決定する必要があります。

インターフェイスは、それらを実装するクラスのパブリック APIを定義します。インターフェイスを使用する目的は、それを実装するクラスの使用法を示すことです。副作用ではありませんが、クラスがさまざまなインターフェイスを実装して、クラスが実行できるさまざまな役割を示すことができるようにすることは、中心的な設計目標です。

抽象クラスは、いくつかの基本的なアルゴリズムまたは一般的な動作を実装する必要があります。主に、サブクラスの共通機能を 1 か所に結合することです。その目的は、パブリック インターフェイスではなく、内部の使用方法またはフローを定義することです。抽象クラスの使用法を公開したい場合は、別のインターフェースを実装する必要があります。

そう:

1) 上記のガイドラインを使用する場合、パブリック抽象メソッドのみを持つ抽象クラスは意味がありません。抽象クラスは、保護された抽象メソッドを定義して、フローまたはアルゴリズムを定義できます。しかし、それはインターフェースでは不可能です。

2) パブリック プロパティに加えて、抽象クラスは保護されたインスタンス変数を定義できるため、さらに多くの使用シナリオがあります (上記の説明を参照)。

編集:「java」タグは作成者によって削除されました。これを可能な限り一般的にしようとしましたが、Java と C# の両方に当てはまるはずです。

于 2013-07-23T12:57:39.487 に答える
3

Java の場合:

abstract classできimplementますinterface。_

interface できませextendabstract class

ところで:奇妙なabstract classことに、実際にはそうimplementしなくてもできます。interface

interface I {
  public String hello ();
}

interface J {
  public String goodbye ();
}

abstract class A implements I, J {
  @Override
  abstract public String hello ();
}

class B extends A {

  @Override
  public String hello() {
    return "Hello";
  }

  @Override
  public String goodbye() {
    return "goodbye";
  }

}
于 2013-07-23T12:54:42.290 に答える
3

Interface のすべての変数は、デフォルトでは public および static です。インターフェイスに唯一の public 変数を持つことはできませんが、Abstract クラスでは public 変数を宣言できます。

クラスが抽象クラスを拡張する場合、それらの間に契約はありません。それを拡張するクラスは抽象メソッドをオーバーライドする場合とオーバーライドしない場合がありますが、インターフェースの場合、インターフェースとそれを実装するクラスの間に厳密な契約があります。つまり、クラスはそのインターフェースのすべてのメソッドをオーバーライドする必要があります。したがって、抽象メソッドの観点からは、それらは同じように見えますが、まったく異なる特性と利点を持っています。

于 2013-07-23T12:55:51.430 に答える
2

あなたの質問は「一般的なオブジェクト指向」を示していますが、.NET でのこれらの用語の使用に焦点を当てているようです。

  • インターフェイスは状態または実装を持たないことができます
  • インターフェイスを実装するクラスは、そのインターフェイスのすべてのメソッドの実装を提供する必要があります
  • 抽象クラスには、状態 (データ メンバー) および/または実装 (メソッド) を含めることができます。
  • 抽象クラスは、抽象メソッドを実装せずに継承できます (ただし、そのような派生クラスは抽象自体です)。
  • インターフェースは多重継承することができますが、抽象クラスはそうではありません (これはおそらく、抽象クラスとは別にインターフェースが存在する主な具体的な理由です。それらは、一般的な MI の問題の多くを取り除く多重継承の実装を可能にします)。

一般的な OO 用語として、違いは必ずしも明確に定義されているわけではありません。たとえば、同様の厳密な定義を保持している C++ プログラマがいる (インターフェイスは、実装を含めることができない抽象クラスの厳密なサブセットです) 一方で、一部のデフォルト実装を持つ抽象クラスは依然としてインターフェイスである、または非抽象クラスであると言う人もいます。クラスは引き続きインターフェイスを定義できます。

実際、非仮想インターフェイス (NVI) と呼ばれる C++ のイディオムがあり、パブリック メソッドはプライベート仮想メソッドに「サンク」する非仮想メソッドです。

http://www.gotw.ca/publications/mill18.htm http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface

于 2013-07-23T12:47:56.017 に答える
2

抽象メソッドだけを持つ抽象クラスがあるとしたら? それはインターフェースとどのように違うでしょうか?

  • 複数のインターフェイスを実装できますが、拡張できるクラスは 1 つだけです
  • 抽象クラスは、インターフェイスを変更すると、それを実装するクラスが壊れるため、インターフェイスより変更の影響を受けません。
  • インターフェイスはフィールドのみを持つstatic finalことができます。抽象クラスは任意のタイプのフィールドを持つことができます。
  • インターフェイスにはコンストラクターがありませんが、抽象クラスにはコンストラクターを含めることができます

しかし、Javaドキュメントはこれを言います

抽象クラスに抽象メソッド宣言のみが含まれている場合は、代わりにインターフェイスとして宣言する必要があります。

于 2013-07-23T12:50:14.920 に答える
2

抽象クラスの現在のバージョンのすべてのメソッドが抽象であっても、クラスの将来のバージョンでは、実装の変更やコンシューマの再コンパイルを強制することなく、仮想メソッドまたは非仮想メソッドを追加できます。対照的に、インターフェイスにメンバーを追加するには、通常、インターフェイスを実装するすべてのクラスを変更してそのメンバーを実装する必要があり、変更によってまだ実装されていないものが追加されたかどうかに関係なく、実装とコンシューマーの両方を通常再コンパイルする必要があります。

実装や消費者を壊すことなく抽象変更を変更できるという事実は、抽象クラスを支持する大きな利点です。一方、抽象クラスは、実装クラスがそれから派生することを強制し、他のクラスは派生させません。対照的に、インターフェースは、その実装者が継承または派生できるものにほとんど制限を課します。これは、インターフェースを支持する大きな利点です。

抽象クラスとインターフェースにはそれぞれ明確な利点があるため、どちらか一方が優れている場合があります。概念的には、インターフェイスの動作方法にいくつかの機能を追加して、現在抽象クラスのみが享受している利点をインターフェイスに追加することは可能ですが、そうする具体的な計画はありません。

于 2013-12-09T17:44:14.980 に答える
1
*1) What if you had an Abstract class with only abstract methods? How would that be different from an interface?*

デフォルトでは、インターフェースのメソッドは「パブリック抽象」であり、抽象クラスも「パブリック抽象」として抽象メソッドを持ちます。抽象クラスに抽象メソッドのみが含まれている場合は、それをインターフェイスにすることをお勧めします。

*2) What if you had a Public variable inside the interface, how would that be different than in Abstract Class?*

インターフェイスに変数を含めることはできません。プロパティ、イベント、デリゲートなどを意味する場合...それらはデフォルトで「パブリック」になります。抽象クラスで何も指定されていない場合は、「プライベート」になります (インターフェイス/抽象クラスのメンバーに関してのみ)。

于 2013-11-27T01:35:23.227 に答える
1

クラスは 1 つの抽象クラスのみを拡張し、多くのインターフェイスを実装できます。

于 2013-07-23T12:45:08.847 に答える
1

まあ、抽象クラスではフィールドを持つこともでき、自動プロパティを再実装する必要はありません。ではないアクセス指定子を指定することもできますpublic。また、スケーラビリティも優れています (たとえば、 を使用[Obsolete]して古い実装をマークし、新しい実装がデフォルトで古い実装を呼び出すようにすることができます)。また、クラスの継承ができなくなります。もう 1 つのことは、抽象クラスで静的フィールドを設定できることです。

また、インターフェイスは通常、アクションを実行するものですが、クラスはそれに関するものです。

于 2013-07-23T12:46:12.460 に答える
0

クラスで何かを実行できるようにする場合は、インターフェイスを使用します。

'is a'関係がある場合、クラスは抽象クラスを拡張します。

セマンティックの違いがあります。

于 2013-07-23T12:48:41.447 に答える