抽象クラスがあり、このクラスに抽象メソッドのみがあるとします。この抽象クラスは、同じメソッドのみを持つインターフェースとは異なりますか?
私が知りたいのは、抽象的メンバーのみを持つ抽象クラスと同等のインターフェイスの間に、哲学的、客観的、および基礎となるプログラミング言語の実装に違いがあるかどうかです。
抽象クラスがあり、このクラスに抽象メソッドのみがあるとします。この抽象クラスは、同じメソッドのみを持つインターフェースとは異なりますか?
私が知りたいのは、抽象的メンバーのみを持つ抽象クラスと同等のインターフェイスの間に、哲学的、客観的、および基礎となるプログラミング言語の実装に違いがあるかどうかです。
回答:
技術的には、違いはそれほど重要ではありませんが、概念的には完全に異なるものであり、それが他の人が述べた技術的な違いにつながります。
抽象スーパークラスはまさにそれがどのように聞こえるかであり、それは猫や犬は動物であるなど、他の多くの型によって共有される一般的な型です。
インターフェースは、まさにそのように聞こえるものでもあります。それは、他のクラスがオブジェクトと通信できるインターフェースです。Catウォークを作成する場合は、問題ありません。CatがCanWalkインターフェイスを実装しているからです。トカゲも同じですが、歩く方法は大きく異なります。一方、スネークはCanWalkを実装していないため、ウォークするように指示することはできません。一方、LizardとSnake(またはおそらくもっと明示的なサブクラス-私はエキスパートではない)は両方ともスキンを取り除き、したがってCanShedを実装するかもしれませんが、Catはそれができませんでした。
しかし、それらはすべて動物であり、生きているか死んでいるかなど、いくつかの共通の特性があります。
これが、インターフェイス上のすべてのメソッドをパブリックとして(または明示的にC#で)実装する必要がある理由です。オブジェクトとのインターフェースをとるクラスから隠されているインターフェイスのポイントは何ですか?また、言語が複数の継承をサポートしていない場合でも、オブジェクトへの複数のインターフェイスを使用できるのはこのためです。
質問に戻ると、このように見ると、完全に抽象的なスーパークラスを持つ理由はほとんどありません。
ほとんどのOOP言語では、実装クラスは1つの抽象クラスからのみ派生できますが、複数のインターフェースを実装します。
多重継承を可能にし、インターフェースを持たないC ++のような言語では、すべてのメソッドが抽象である抽象クラスをインターフェースとして使用できます。私はC ++をあまり扱っていませんが、基本クラスに同じ名前のメソッドがある場合、多重継承が問題を引き起こす可能性があると思います。
PHPやC#などの言語では、インターフェイスは同様のポリモーフィズムを実現する手段を提供しますが、抽象クラスの継承とインターフェイスの実装との間には概念的な違いがあるため、「継承」とは呼ばれません。インターフェイス自体は実装を提供しないため、インターフェイスは競合の問題を取り除きます。
抽象クラスは実装を提供することができますが、インターフェイスを「偽造」するために使用された場合、それはほとんどの場合そうではありませんが、インターフェイスは外部の世界へのコントラクトとして機能します。
主な概念上の違いは、クラスが別のクラスを継承する場合(抽象かそうでないか)には「is」という関係があるため、a Car
はa Vehicle
とでDog
あるということAnimal
です。インターフェースでは、それはオブジェクトが重要なことです。したがってCar
、Dog
can とcan Move()
と消費者の両方がそれを実装しているのでそれを知っていますMovable
が、Carは間違いなくDog
、またはではありませんAnimal
。また、移動の実装は異なります(ホイールとレッグ)が、使用するコードは気にせず、気にする必要もありません。インターフェースは、実装というよりも、消費するコードに関するものです。
重要な点は、選択した言語のインターフェイスがある場合、それらを使用するためにそれらを使用することです。そうでない場合(C ++のように)、純粋な抽象クラスを使用してそれらを偽造できます。
Dog
とCat
しているが。
抽象クラスは、(私が使用している言語で)抽象保護されたメソッドを備えている場合があります。インターフェイスでは、メソッドは通常常にパブリックです。この違いが有用な悪用を許可するかどうかはわかりません。
編集私は最初、プライベートな抽象メソッドは役に立たないと思っていましたが、そのメソッドが呼び出されないようにするために使用できることを思い出しました。これにより、オブジェクトのコピーコンストラクターが呼び出されるのを防ぐことができます。
主な違いは次のとおりです。抽象クラスでは、すべてのメソッドがすべて抽象であっても、データメンバー(インスタンス変数)とそれを実装するクラス(プライベートメソッドまたはコンストラクターの形式)にコードを提供できます。静的ブロック; サブクラスの作業の一部を行い、実装を支援します。
1つの肯定的な副作用:コードが1か所にあるため、1か所で修正できます。サブクラスは、スーパークラスのメソッドを呼び出すだけで、スーパークラスのアクションで十分であれば、他のことを実行するか、何も実行できません。スーパークラスは、各サブクラスがこの決定を行うことを望んでいるため、すべての実装を抽象としてマークしました(一部は空にすることもできます)
質問には関係ありませんが、インターフェイスがあるということは、1つのクラスが2つの異なるコントラクトを実装できることを意味します。それが抽象スーパークラスに対するインターフェースの利点です