Wie PHP-Schnittstellen tatsächlich das Verhalten von Klassen verändern
P粉289775043
2023-09-02 23:49:28
<p>Laut der PHP-Dokumentation ist </p>
<blockquote>
<p>Mit Objektschnittstellen können Sie Code erstellen, der angibt, welche Methoden eine Klasse implementieren muss, ohne zu definieren, wie diese Methoden implementiert werden. </p>
</blockquote>
<p>Eine Schnittstelle ist also wie eine Klasse mit vordefinierten Methoden, auf die noch mit der <code>-></code>-Notation zugegriffen werden muss.
<p>Die ArrayAccess-Schnittstelle bietet jedoch Zugriff auf Objekte als Arrays. Auf Objekte kann mit <code>$object->property</code> und <code>$object["property"]</code></p> zugegriffen werden.
<p>Ich verstehe nicht, wie ArrayAccess es ermöglicht, die Objektsyntax zu ändern. Ich habe einen Code geschrieben, um zu versuchen, den Effekt der <code>ArrayAccess</code>-Methode zu reproduzieren. Es gibt nur eine</em>, aber es wird der Fehler</p>
<pre class="brush:php;toolbar:false;">// Verwenden der PHP-ArrayAccess-Schnittstelle
Namensraum A {
Klasse myclass implementiert ArrayAccess {
öffentliche Funktion offsetExists($offset) { return true;
öffentliche Funktion offsetGet($offset) {
// Verhalten geändert
return $this->{$offset} ?? null;
}
öffentliche Funktion offsetSet($offset, $value) {}
öffentliche Funktion offsetUnset($offset) {}
}
$myclass = new myclass();
$myclass->access = 'Schnittstelle';
echo $myclass['access']; // "Schnittstelle"
};
//Ich versuche, meine eigene ArrayAccess-Schnittstelle zu implementieren
Namensraum B {
Schnittstelle MyArrayAccess {
öffentliche Funktion offsetGet($offset);
}
Klasse myclass implementiert MyArrayAccess {
öffentliche Funktion offsetGet($offset) {
// Verhalten ändern
return $this->{$offset} ?? null;
}
}
$myclass = new myclass();
$myclass->access = 'Schnittstelle';
echo $myclass['access']; // Schwerwiegender Fehler: Nicht erfasster Fehler: Objekt vom Typ Bmyclass kann nicht als Array verwendet werden
}
</pre>
<p>Bitte helfen Sie mir, es richtig zu erklären. Vielen Dank</p>
我并不是说接口“改变了类的行为”,而是说接口使扩展类功能变得容易。
要理解接口,作为一个面向对象的编程概念,我们首先应该理解它要解决什么问题。
“Interface”旨在解决什么问题?
接口是一种契约。这是在 PHP 中实现 duck-typing 的方法。您需要从库编写者的角度思考,他希望向其他人公开功能。例如,
为了确保库用户知道
$person
需要有getName()
方法,您可以创建一个类Person
> 有一个getName()
方法。然后使用 类型声明 来检测代码执行时的潜在错误已解析。假设有另一个库可以用食物来喂养东西:
考虑这个...
现在,假设用户想要编写一个既可以吃饭又可以打招呼的
Pet
类。用户不想仅仅为了Pet
再次编写这些功能。如何编写
Pet
以便同时使用Greeter
和Feeder
库?也许是这样的?
不幸的是,PHP 不支持多重继承。一个类只能
扩展
一个类。上面的代码无效。所以在目前的情况下,用户只能使用其中一个库。此外,对于不同的事物,“名称”可能是一个非常不同的概念(例如,一个人可能会使用
getName() 返回
$first_name
和$last_name
代码>)。您的库类中可能没有合理的默认实现getName()
方法。所以,作为一名库编写者,您希望他/她的库对用户尽可能灵活。你能做什么?
如何用 PHP 中的“接口”解决这个问题?
接口是方法签名的声明。这是在没有具体类/继承要求的情况下声明库要求的快捷方式。
使用接口,您可以像这样重写两个库:
Greeter
库Feeder
库不需要一个具体的类(或父类继承),一个类可以实现多个接口。所以下面的
Pet
类在 PHP 中是完全有效的:现在,此
Pet
类的对象可以与Greeter
库和Feeder
库一起使用。ArrayAccess
接口怎么样?ArrayAccess 接口不是由第三方声明的接口库编写者,但由核心 PHP 编写者编写。核心PHP编写器对此提供了更深刻的支持。
有点像我们之前提到的接口,PHP 为实现它的类提供功能。但核心 PHP 不是提供上面的
Greeter
或Feeder
示例,而是提供 实现 ArrayAccess 的类的语法糖。这意味着您可以使用更简洁的代码来处理实现 AccessAccess 接口的类。在官方示例中,
如果您实现了它们,则代替这些:
您可以将
$obj
与类似数组的语法一起使用,以使代码更短: