241

インターフェイスを使用すると、それを実装するクラスのメソッドを定義するコードを作成できます。ただし、これらのメソッドにコードを追加することはできません。

抽象クラスを使用すると、メソッドにコードを追加するだけでなく、同じことを行うことができます。

抽象クラスで同じ目標を達成できるのなら、なぜインターフェイスの概念が必要なのでしょうか?

C++ から Java までの OO 理論に関係していると言われています。これは、PHP の OO が基づいているものです。この概念はJavaでは役に立ちますが、PHPでは役に立ちませんか? 抽象クラスにプレースホルダーが散らばらないようにするための単なる方法ですか? 何か不足していますか?

4

15 に答える 15

148

インターフェースの全体的なポイントは、クラスに複数のインターフェースを強制的に実装する柔軟性を与えることですが、それでも多重継承は許可しません。複数のクラスからの継承に関する問題は多種多様であり、ウィキペディアのページはそれらをかなりうまくまとめています。

インターフェイスは妥協です。多重継承に関する問題のほとんどは抽象基底クラスには当てはまらないため、最近のほとんどの最新言語は多重継承を無効にしますが、抽象基底クラスのインターフェイスを呼び出し、クラスがそれらを必要な数だけ「実装」できるようにします。

于 2008-08-21T16:45:54.390 に答える
128

この概念は、オブジェクト指向プログラミングのあらゆる場面で役立ちます。私はインターフェースをコントラクトと考えています。私のクラスとあなたのクラスがこのメソッド シグネチャ コントラクトに同意している限り、「インターフェース」を行うことができます。抽象クラスに関しては、いくつかのメソッドをスタブ化する基本クラスのほうが多く、詳細を記入する必要があります。

于 2008-08-21T16:39:23.143 に答える
25

インターフェイスと抽象クラスの使用の違いは、言語自体による強制というよりも、コードの編成に関係しています。他の開発者が使用するコードを準備して、意図した設計パターン内にとどまるようにするときに、これらをよく使用します。インターフェイスは一種の「契約による設計」であり、アクセスできないコードから発生する可能性のある所定の API 呼び出しのセットにコードが応答することに同意します。

抽象クラスからの継承は「is a」関係ですが、それが常に必要なわけではなく、インターフェイスの実装は「as like a」関係に近いものです。この違いは、特定のコンテキストでは非常に重要です。

たとえば、抽象クラス Account があり、そこから他の多くのクラス (アカウントの種類など) が拡張されているとします。そのタイプ グループにのみ適用できる特定のメソッド セットがあります。ただし、これらのアカウント サブクラスの一部は、Versionable、Listable、または Editable を実装しているため、これらの API を使用することを期待するコントローラーにスローできます。コントローラはオブジェクトのタイプを気にしません

対照的に、User 抽象クラスなど、Account から拡張されないオブジェクトを作成し、Listable および Editable を実装することもできますが、Versionable は実装できません。これはここでは意味がありません。

このように、FooUser サブクラスはアカウントではなく、編集可能オブジェクトのように機能すると言っています。同様に、BarAccount は Account から拡張されますが、User サブクラスではありませんが、Editable、Listable、および Versionable を実装します。

Editable、Listable、Versionable のこれらすべての API を抽象クラス自体に追加すると、雑然として醜いだけでなく、Account と User の共通インターフェイスが複製されるか、User オブジェクトに Versionable を強制的に実装させて、おそらく単に例外。

于 2008-08-27T16:36:48.217 に答える
23

インターフェイスは基本的に、作成できるものの青写真です。これらは、クラスに必要なメソッドを定義しますが、これらの制限の外側に追加のメソッドを作成できます。

メソッドにコードを追加できないということで、あなたが何を意味するのかわかりません-できるからです。インターフェイスを抽象クラスまたはそれを拡張するクラスに適用していますか?

抽象クラスに適用されるインターフェースのメソッドは、その抽象クラスに実装する必要があります。ただし、そのインターフェイスを拡張クラスに適用すると、メソッドは拡張クラスに実装するだけで済みます。ここで間違っている可能性があります-私はできる限り/すべきであるほど頻繁にインターフェイスを使用していません。

私は常に、インターフェースを外部開発者向けのパターン、または物事が正しいことを確認するための追加のルールセットと考えてきました。

于 2008-08-21T16:44:38.467 に答える
15

PHP でインターフェイスを使用します。

  1. 実装を非表示にするには - オブジェクトのクラスへのアクセス プロトコルを確立し、そのオブジェクトを使用したすべての場所でリファクタリングせずに基になる実装を変更します
  2. 型をチェックするには - パラメータに特定の型があることを確認する場合と同様に$object instanceof MyInterface
  3. 実行時にパラメータ チェックを実施するには
  4. 複数の動作を 1 つのクラスに実装するには (複雑な型を構築する)

    class Car は、EngineInterface、BodyInterface、SteeringInterface {

Carオブジェクト がstart(), stop()(EngineInterface) またはgoRight(), goLeft()(Steering インターフェース)になりました

その他、今は考えられないこと

4 番目は、おそらく、抽象クラスでは対処できない最も明白な使用例です。

Java で考える から:

インターフェースは、「これは、この特定のインターフェースを実装するすべてのクラスがどのように見えるかです」と言います。したがって、特定のインターフェイスを使用するすべてのコードは、そのインターフェイスに対してどのメソッドを呼び出すことができるかを認識しています。そのため、インターフェイスはクラス間の「プロトコル」を確立するために使用されます。

于 2013-02-08T18:20:37.053 に答える
9

インターフェイスは、開発者が特定のメソッドを確実に実装できるようにするためだけのものではありません。これらのクラスには特定のメソッドがあることが保証されているため、クラスの実際の型がわからなくてもこれらのメソッドを使用できるという考え方です。例:

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

多くの場合、実装は大きく異なり、いくつかのメソッド以外に共通点がないため、抽象クラスであるかどうかにかかわらず、基本クラスを提供することは意味がありません。

動的に型付けされた言語には、インターフェースを必要としない「ダックタイピング」の概念があります。オブジェクトには、呼び出しているメソッドがあると自由に想定できます。これは、オブジェクトに何らかのメソッド (私の例では read()) があるがインターフェイスを実装していない、静的に型付けされた言語の問題を回避します。

于 2008-08-21T16:52:24.203 に答える
7

私の意見では、インターフェースは機能しない抽象クラスよりも優先されるべきです。インスタンス化されたオブジェクトは 1 つだけで、2 つを解析してそれらを結合するのではなく、パフォーマンス ヒットがあったとしても驚かないでしょう (ただし、内部の仕組みに精通していないため、確信が持てません)。 OOP PHP の)。

インターフェースが Java などと比べて有用性や意味がないのは事実です。一方、PHP6 では、戻り値の型ヒントなど、さらに多くの型ヒントが導入されます。これにより、PHP インターフェイスに何らかの価値が追加されます。

tl;dr: インターフェイスは、従う必要があるメソッドのリストを定義します (API を考えてください)。一方、抽象クラスは、サブクラスが特定のニーズに合わせて改良するいくつかの基本的/共通機能を提供します。

于 2008-08-21T16:47:11.253 に答える
6

PHPはこの点が違うのか思い出せないのですが、Javaでは複数のInterfaceを実装できますが、複数の抽象クラスを継承することはできません。PHPも同じように動作すると思います。

PHP では、コンマで区切ることで複数のインターフェースを適用できます (私は、それが明確な解決策であるとは思いません)。

複数の抽象クラスについては、相互に拡張する複数の抽象クラスを持つことができます (繰り返しますが、それについては完全にはわかりませんが、以前にどこかで見たことがあると思います)。拡張できないのは最終クラスだけです。

于 2008-08-21T16:53:24.810 に答える
5

インターフェイスは、コードのパフォーマンスを向上させたり、そのようなものを提供したりしませんが、コードを保守可能にするために大いに役立ちます。抽象クラス (または非抽象クラス) を使用してコードへのインターフェイスを確立できることは事実ですが、適切なインターフェイス (キーワードで定義し、メソッド シグネチャのみを含むもの) を使用する方が簡単です。並べて読む。

そうは言っても、クラスよりもインターフェースを使用するかどうかを決定する際には、私は裁量を使用する傾向があります。デフォルトのメソッド実装や、すべてのサブクラスに共通の変数が必要になることがあります。

もちろん、複数インターフェイスの実装に関するポイントも健全なものです。複数のインターフェイスを実装するクラスがある場合、そのクラスのオブジェクトを同じアプリケーション内の異なる型として使用できます。

ただし、あなたの質問が PHP に関するものであるという事実は、物事をもう少し興味深いものにします。インターフェイスへの型付けは、PHP では依然として非常に必要ではありません。PHP では、型に関係なく、あらゆるメソッドにほとんど何でもフィードできます。メソッドのパラメーターを静的に入力することはできますが、その中には壊れているものもあります (文字列は問題を引き起こすと思います)。これを、他のほとんどの参照を入力できないという事実と組み合わせると、PHP で静的型付けを強制しようとしてもあまり価値がありません (この時点では)。そのため、この時点で PHPの interfaces の値はより厳密に型付けされた言語よりもはるかに少ないです。読みやすさという利点がありますが、他にはほとんどありません。メソッドを宣言し、実装者内でそれらに本体を与える必要があるため、複数の実装は有益ではありません。

于 2008-08-21T17:06:42.093 に答える
2

以下はPHPインターフェースのポイントです

  1. クラスで必要なメソッドを定義するために使用されます [html をロードする場合は、id と名前が必要なので、この場合、インターフェイスには setID と setName が含まれます]。
  2. インターフェイスは、定義されているすべてのメソッドをクラスに含めるように厳密に強制します。
  3. public アクセシビリティを備えたインターフェイスでのみメソッドを定義できます。
  4. クラスのようにインターフェースを拡張することもできます。extends キーワードを使用して、php のインターフェイスを拡張できます。
  5. 複数のインターフェイスを拡張します。
  6. 両方が同じ名前の機能を共有している場合、2 つのインターフェースを実装することはできません。エラーがスローされます。

コード例:

interface test{
    public function A($i);
    public function B($j = 20);
}

class xyz implements test{
    public function A($a){
        echo "CLASS A Value is ".$a;
    }
    public function B($b){
        echo "CLASS B Value is ".$b;
    }
}
$x = new xyz();
echo $x->A(11);
echo "<br/>";
echo $x->B(10);
于 2017-01-12T06:39:51.317 に答える
2

抽象クラスとインターフェースは、子クラスに実装する必要がある抽象メソッドを提供するという点で似ていることがわかりました。ただし、これらにはまだ次の違いがあります。

1.インターフェイスには、抽象メソッドと定数を含めることができますが、具体的なメソッドと変数を含めることはできません。

2. インターフェイス内のすべてのメソッドは、パブリック可視性スコープ内にある必要があります。

3. クラスは複数のインターフェースを実装できますが、継承できる抽象クラスは 1 つだけです。

                                  interface                      abstract class
the code                     - abstract methods               - abstract methods
                             - constants                      - constants                  
                                                              - concrete methods
                                                              - concrete variables

access modifiers             
                             - public                         - public
                                                              - protected
                                                              - private
                                                                etc.
number of parents          The same class can implement
                           more than 1 interface              The child class can 
                                                              inherit only from 1 abstract class

これが誰にとっても理解するのに役立つことを願っています!

于 2018-02-16T11:17:08.727 に答える