根據 PHP 文檔,
物件介面可讓您建立指定類別必須實作哪些方法的程式碼,而無需定義這些方法的實作方式。
因此,介面就像一個具有預先定義方法的類,仍然需要使用 ->
符號來存取
但是,ArrayAccess 介面提供對物件作為陣列的存取。可以使用 $object->property
和 $object["property"]
我無法理解 ArrayAccess 如何讓更改物件語法成為可能。我寫了一段程式碼來嘗試複製 ArrayAccess
方法只有一個的效果,但它拋出錯誤
// Using the PHP ArrayAccess Interface namespace A { class myclass implements \ArrayAccess { public function offsetExists($offset) { return true; } public function offsetGet($offset) { // changed behaviour return $this->{$offset} ?? null; } public function offsetSet($offset, $value) {} public function offsetUnset($offset) {} } $myclass = new myclass(); $myclass->access = 'Interface'; echo $myclass['access']; // "Interface" }; //Trying to implement my own ArrayAccess Interface namespace B { interface MyArrayAccess { public function offsetGet($offset); } class myclass implements MyArrayAccess { public function offsetGet($offset) { // change behaviour return $this->{$offset} ?? null; } } $myclass = new myclass(); $myclass->access = 'Interface'; echo $myclass['access']; // Fatal error: Uncaught Error: Cannot use object of type B\myclass as array }
請幫我正確解釋。謝謝
我並不是說介面“改變了類別的行為”,而是說介面使擴充類別功能變得容易。
要理解接口,作為一個物件導向的程式設計概念,我們首先應該理解它要解決什麼問題。
「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
與類似陣列的語法一起使用,以使程式碼更短: