インターフェイスと抽象メソッドのみを持つ抽象クラスの間に違いはありますか?


9

抽象クラスがあり、このクラスに抽象メソッドのみがあるとします。この抽象クラスは、同じメソッドのみを持つインターフェースとは異なりますか?

私が知りたいのは、抽象的メンバーのみを持つ抽象クラスと同等のインターフェイスの間に、哲学的、客観的、および基礎となるプログラミング言語の実装に違いがあるかどうかです。


どの言語?
kevin cline 2013

私の知る限り、あなたの質問が重複して答えている二回ここここ。そして、これらの2つの答えは言語に依存せず、C#に固有のものはありません
gnat

3
@空白質問に適用された重複ステータスに同意しなかったため、再開しました。さらに、私はあなたが質問していると私が信じていることをさらに明確にするためにあなたの質問を編集しました。
maple_shaft

回答:


22

技術的には、違いはそれほど重要ではありませんが、概念的には完全に異なるものであり、それが他の人が述べた技術的な違いにつながります。

抽象スーパークラスはまさにそれがどのように聞こえるかであり、それは猫や犬は動物であるなど、他の多くの型によって共有される一般的な型です。

インターフェースは、まさにそのように聞こえるものでもあります。それは、他のクラスがオブジェクトと通信できるインターフェースです。Catウォークを作成する場合は、問題ありません。CatがCanWalkインターフェイスを実装しているからです。トカゲも同じですが、歩く方法は大きく異なります。一方、スネークはCanWalkを実装していないため、ウォークするように指示することはできません。一方、LizardとSnake(またはおそらくもっと明示的なサブクラス-私はエキスパートではない)は両方ともスキンを取り除き、したがってCanShedを実装するかもしれませんが、Catはそれができませんでした。

しかし、それらはすべて動物であり、生きているか死んでいるかなど、いくつかの共通の特性があります。

これが、インターフェイス上のすべてのメソッドをパブリックとして(または明示的にC#で)実装する必要がある理由です。オブジェクトとのインターフェースをとるクラスから隠されているインターフェイスのポイントは何ですか?また、言語が複数の継承をサポートしていない場合でも、オブジェクトへの複数のインターフェイスを使用できるのはこのためです。

質問に戻ると、このように見ると、完全に抽象的なスーパークラスを持つ理由はほとんどありません。


4
+1、猫はヘビやトカゲよりもはるかに迷惑な方法で流したが。
マシューフリン

技術的に:抽象メソッドを保護することができます。インターフェイスメソッドはできません。
Jacques Koorts

19

ほとんどのOOP言語では、実装クラスは1つの抽象クラスからのみ派生できますが、複数のインターフェースを実装します。


3
最も?どれを数えていますか?私が知っているほとんどのOOP言語には、インターフェースや抽象クラスがありません。C ++には抽象クラスのみがあります。
kevin cline 2013

10
@kevincline:おそらくC#、Java、VB.NET。
tdammers 2013

1
@kevincline、私は「両方を持っている」だけの不足があると思います。IIDA、エイダでは、インターフェイスの動機は、デザイナーが一般的な多重継承機能を望んでいないことでしたが、インターフェイスの特別なケースはあまりにも重要であり、提供されないと判断されました。
AProgrammer 2013

@tdammers:爆笑。それはだった、右の冗談?
kevin cline 2013

3

多重継承を可能にし、インターフェースを持たないC ++のような言語では、すべてのメソッドが抽象である抽象クラスをインターフェースとして使用できます。私はC ++をあまり扱っていませんが、基本クラスに同じ名前のメソッドがある場合、多重継承が問題を引き起こす可能性があると思います。

PHPやC#などの言語では、インターフェイスは同様のポリモーフィズムを実現する手段を提供しますが、抽象クラスの継承とインターフェイスの実装との間には概念的な違いがあるため、「継承」とは呼ばれません。インターフェイス自体は実装を提供しないため、インターフェイスは競合の問題を取り除きます。

抽象クラスは実装を提供することができますが、インターフェイスを「偽造」するために使用された場合、それはほとんどの場合そうではありませんが、インターフェイスは外部の世界へのコントラクトとして機能します。

主な概念上の違いは、クラスが別のクラスを継承する場合(抽象かそうでないか)には「is」という関係があるため、a Carはa VehicleとでDogあるということAnimalです。インターフェースでは、それはオブジェクトが重要なことです。したがってCarDogcan とcan Move()と消費者の両方がそれを実装しているのでそれを知っていますMovableが、Carは間違いなくDog、またはではありませんAnimal。また、移動の実装は異なります(ホイールとレッグ)が、使用するコードは気にせず、気にする必要もありません。インターフェースは、実装というよりも、消費するコードに関するものです。

重要な点は、選択した言語のインターフェイスがある場合、それらを使用するためにそれらを使用することです。そうでない場合(C ++のように)、純粋な抽象クラスを使用してそれらを偽造できます。


あなたは両方のIAnimal持つことができるので、インターフェースは、同様のタイプであるDogCat しているが
エイミーブランケンシップ

できるかもしれませんが、私の意見では、インターフェイスは外界にさらされる動作に関するものであり、オブジェクトが何であるかについてはそれほどではありません。継承とは、何かが何か別のタイプであることを意味します(猫は動物です)。インターフェースは、そのオブジェクトが何ができるかを示しています。そのため、インターフェイスから「継承」するのではなく、「実装」と言いたいのです。これは、これまで扱ってきたほとんどの.Netの人々が言うことです(継承と実装の構文は同じであるためです)。
Ivan Pintar 2013

2

抽象クラスは、(私が使用している言語で)抽象保護されたメソッドを備えている場合があります。インターフェイスでは、メソッドは通常常にパブリックです。この違いが有用な悪用を許可するかどうかはわかりません。

編集私は最初、プライベートな抽象メソッドは役に立たないと思っていましたが、そのメソッドが呼び出されないようにするために使用できることを思い出しました。これにより、オブジェクトのコピーコンストラクターが呼び出されるのを防ぐことができます。


1
保護された仮想(オーバーライド可能)メソッドは、フレームワークなどの一部であるクラスに役立ちます。このようにして、抽象を継承するクラスのカスタムコードがその機能を提供することを保証します。これは、基本クラスのインターフェイスを継承することによっても実現できますが、実際にはそのメソッドを実装していません
Ivan Pintar

ええ、そういうことを考えていたのですが、経験がないので判断できませんでした。入力いただきありがとうございます。
トーマス

ただのメモ。一部の言語では、プライベート仮想メソッドは派生クラスでオーバーライドできます。
JohanBoulé2014年

2

はい、違います。そうでなければ、言語デザイナーは両方を提供しなかったでしょう。クラスとインターフェースを分離する2つの言語、JavaとC#、Javaのミュータントクローンを知っています。設計者は、複数のクラスの継承をサポートしないようにインターフェイスを作成しました。他のほとんどの言語は、複数のクラスの継承をサポートしているため、クラスとインターフェースを分離しません。


2

主な違いは次のとおりです。抽象クラスでは、すべてのメソッドがすべて抽象であっても、データメンバー(インスタンス変数)とそれを実装するクラス(プライベートメソッドまたはコンストラクターの形式)にコードを提供できます。静的ブロック; サブクラスの作業の一部を行い、実装を支援します。

1つの肯定的な副作用:コードが1か所にあるため、1か所で修正できます。サブクラスは、スーパークラスのメソッドを呼び出すだけで、スーパークラスのアクションで十分であれば、他のことを実行するか、何も実行できません。スーパークラスは、各サブクラスがこの決定を行うことを望んでいるため、すべての実装を抽象としてマークしました(一部は空にすることもできます)

質問には関係ありませんが、インターフェイスがあるということは、1つのクラスが2つの異なるコントラクトを実装できることを意味します。それが抽象スーパークラスに対するインターフェースの利点です


1
実装なしで定義された抽象メソッドではなく、実装を継承クラスに任せませんか?
Ivan Pintar 2013

はい、あなたの権利です。それらを数えれば、変数、コンストラクタ、静的メソッドとプライベートメソッドだけだと思います
tgkprog

@Pinetree。実際には、ほとんどの場合、抽象クラスに少なくとも「実際の」コードが必要です(少なくとも私が使用する言語では抽象クラス用の特別な構成はありません)。
エイミーブランケンシップ2013

@AmyBlankenshipはい、ほとんどの場合、抽象クラスには「実際の」コードがあります(そのためにあります)。しかし、インターフェースを持たないC ++のような言語でインターフェースとして機能する純粋に抽象的なクラスのコンテキスト内で、抽象的なメソッドを参照していました。
Ivan Pintar 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.