PHP インターフェースが実際にクラスの動作をどのように変更するか
P粉289775043
2023-09-02 23:49:28
<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>
インターフェイスによって「クラスの動作が変わる」と言っているのではなく、インターフェイスによって クラスの機能の拡張が簡単になるということです。
インターフェイスをオブジェクト指向プログラミングの概念として理解するには、まずインターフェイスが解決したい問題を理解する必要があります。コントラクトです。これは、duck-typing が PHP で実装される方法です。機能を他の人に公開したいライブラリ作成者の観点から考える必要があります。例えば、### リーリー
$personには
ここで、ユーザーが食事と挨拶の両方ができるgetName()
メソッドが必要であることをライブラリ ユーザーに確実に知らせるために、 # を持つクラスperson
> を作成できます。 ##getName()メソッド。
型宣言は、コードが解決されるときに潜在的なエラーを検出するために使用されます。
リーリー 食べ物を物に与える別のライブラリがあるとします。 リーリー ###このことを考慮...###Pet
クラスを作成したいとします。ユーザーは、単にPet
するためだけにこれらの機能を再度作成することを望んでいません。Greeter
ライブラリとライブラリの両方を使用する Pet
おそらくこれは事実ですか?
をサポートしていません。クラスはを作成するにはどうすればよいですか?
リーリー
残念ながら、PHP は多重継承1 つのクラスのみを拡張できます。上記のコードは無効です。したがって、現在の状況では、ユーザーはいずれかのライブラリしか使用できません。
さらに、「名前」は、さまざまなものによって非常に異なる概念になる可能性があります (たとえば、getName() を使用して $first_name
# #)。ライブラリ クラスにと
$last_name# を返す場合がありますgetName()
インターフェイスを使用すると、次のように両方のライブラリをオーバーライドできます。メソッドの適切なデフォルト実装が存在しない可能性があります。
したがって、ライブラリ作成者は、自分のライブラリがユーザーにとって可能な限り柔軟であることを望んでいます。何ができるの?
PHP の「インターフェイス」を使用してこの問題を解決するにはどうすればよいですか? 代码>
インターフェイスはメソッドのシグネチャの宣言です。これは、具体的なクラス/継承要件を使用せずにライブラリ要件を宣言する簡単な方法です。
グリーター
ライブラリリーリー
フィーダー
ライブラリリーリー
クラスは PHP では完全に有効です:特定のクラス (または親クラスの継承) は必要なく、クラスは複数のインターフェイスを実装できます。したがって、次の
Petリーリー
クラスのオブジェクトは、この
PetGreeter
ライブラリで使用できるようになりました。ライブラリおよび
FeederArrayAccess
インターフェイスについてはどうですか?
ArrayAccess
前に述べたインターフェイスと似ていますが、PHP はそれを実装するクラスに機能を提供します。ただし、上記の
GreeterFeeder の例を提供する代わりに、コア PHP は ArrayAccess を実装するクラスに syntax Sugar
を提供します。これは、AccessAccess インターフェイスを実装するクラスを操作するときに、より単純なコード
を使用できることを意味します。
公式の例では、
リーリー これらを実装する場合は、次のように置き換えてください: リーリー配列のような構文で
リーリー$obj
を使用すると、コードを短くできます。