検索

ホームページ  >  に質問  >  本文

PHP インターフェースが実際にクラスの動作をどのように変更するか

<p>PHP ドキュメントによると、</p> <ブロック引用> <p>オブジェクト インターフェイスを使用すると、クラスがどのメソッドを実装するかを定義せずに、どのメソッドを実装する必要があるかを指定するコードを作成できます。 </p> </blockquote> <p>したがって、インターフェイスは、<code>-></code> 表記</p> を使用してアクセスする必要がある事前定義されたメソッドを持つクラスのようなものです。 <p>ただし、ArrayAccess インターフェイスは、オブジェクトへのアクセスを配列として提供します。オブジェクトには、<code>$object->property</code> および <code>$object["property"]</code></p> を使用してアクセスできます。 <p>ArrayAccess でオブジェクトの構文をどのように変更できるのか理解できません。 <code>ArrayAccess</code> メソッドの効果を 1 つだけ </em> だけ再現しようとコードを作成しましたが、エラー</p> がスローされます。 <pre class="brush:php;toolbar:false;">// PHP ArrayAccess インターフェイスの使用 名前空間 A { クラス myclass は \ArrayAccess {を実装します。 パブリック関数 offsetExists($offset) { return true; } パブリック関数 offsetGet($offset) { // 動作が変更されました $this->{$offset} ?? null を返します。 } パブリック関数 offsetSet($offset, $value) {} パブリック関数 offsetUnset($offset) {} } $myclass = 新しい myclass(); $myclass->access = 'インターフェース'; echo $myclass['access']; // "インターフェース"; }; //独自の ArrayAccess インターフェイスを実装してみます 名前空間 B { インターフェース MyArrayAccess { パブリック関数 offsetGet($offset); } クラス myclass は MyArrayAccess を実装します { パブリック関数 offsetGet($offset) { // 動作を変更する $this->{$offset} ?? null を返します。 } } $myclass = 新しい myclass(); $myclass->access = 'インターフェース'; echo $myclass['access']; // 致命的エラー: キャッチされないエラー: B\myclass 型のオブジェクトを配列として使用できません } </pre> <p>正しく説明できるよう助けてください。ありがとうございます</p>
P粉289775043P粉289775043466日前619

全員に返信(1)返信します

  • P粉702946921

    P粉7029469212023-09-03 20:17:24

    インターフェイスによって「クラスの動作が変わる」と言っているのではなく、インターフェイスによって クラスの機能の拡張が簡単になるということです。

    インターフェイスをオブジェクト指向プログラミングの概念として理解するには、まずインターフェイスが解決したい問題を理解する必要があります。

    「インターフェイス」はどのような問題を解決するために設計されていますか?

    インターフェイスは

    コントラクトです。これは、duck-typing が PHP で実装される方法です。機能を他の人に公開したいライブラリ作成者の観点から考える必要があります。例えば、### リーリー

    $person

    には getName() メソッドが必要であることをライブラリ ユーザーに確実に知らせるために、 # を持つクラス person > を作成できます。 ##getName() メソッド。 型宣言は、コードが解決されるときに潜在的なエラーを検出するために使用されます。 リーリー 食べ物を物に与える別のライブラリがあるとします。 リーリー ###このことを考慮...###

    ここで、ユーザーが食事と挨拶の両方ができる

    Pet

    クラスを作成したいとします。ユーザーは、単に

    Pet

    するためだけにこれらの機能を再度作成することを望んでいません。

    Greeter ライブラリと

    Feeder

    ライブラリの両方を使用する Pet を作成するにはどうすればよいですか? おそらくこれは事実ですか? リーリー 残念ながら、PHP は多重継承

    をサポートしていません。クラスは

    1 つのクラスのみを拡張できます。上記のコードは無効です。したがって、現在の状況では、ユーザーはいずれかのライブラリしか使用できません。

    さらに、「名前」は、さまざまなものによって非常に異なる概念になる可能性があります (たとえば、getName() を使用して $first_name$last_name# を返す場合があります

    # #)。ライブラリ クラスに

    getName() メソッドの適切なデフォルト実装が存在しない可能性があります。 したがって、ライブラリ作成者は、自分のライブラリがユーザーにとって可能な限り柔軟であることを望んでいます。何ができるの? PHP の「インターフェイス」を使用してこの問題を解決するにはどうすればよいですか? インターフェイスはメソッドのシグネチャの宣言です。これは、具体的なクラス/継承要件を使用せずにライブラリ要件を宣言する簡単な方法です。

    インターフェイスを使用すると、次のように両方のライブラリをオーバーライドできます。

    グリーター

    ライブラリ

    リーリー

    フィーダー

    ライブラリ

    リーリー 特定のクラス (または親クラスの継承) は必要なく、クラスは複数のインターフェイスを実装できます。したがって、次の Pet

    クラスは PHP では完全に有効です:

    リーリー この Pet

    クラスのオブジェクトは、

    Greeter ライブラリおよび Feeder

    ライブラリで使用できるようになりました。

    ArrayAccess インターフェイスについてはどうですか? ArrayAccess

    インターフェイスはサードパーティのインターフェイス ライブラリ ライターによって宣言されていませんが、コア PHP ライターによって書かれています。コアの PHP ライターは、これに対するより詳細なサポートを提供します。

    前に述べたインターフェイスと似ていますが、PHP はそれを実装するクラスに機能を提供します。ただし、上記の Greeter

    または

    Feeder の例を提供する代わりに、コア PHP は ArrayAccess を実装するクラスに syntax Sugar

    を提供します。これは、AccessAccess インターフェイスを実装するクラスを操作するときに、

    より単純なコードを使用できることを意味します。 公式の例では、 リーリー これらを実装する場合は、次のように置き換えてください: リーリー

    配列のような構文で $obj を使用すると、コードを短くできます。

    リーリー

    返事
    0
  • キャンセル返事