![](/img/trans.png)
[英]Closures in PHP… what, precisely, are they and when would you need to use them?
[英]What is a ABSTRACT CLASS and INTERFACE and when would you use them in PHP?
什么是PHP中的抽象類和接口,何時使用它們? 一個外行人回答一個例子對我的理解很有幫助。
抽象類和接口不是特定於PHP的; 它們是許多現代面向對象語言的特征。
抽象類是具有一個或多個未實現的成員函數的類。 您可以在需要一組具有相似行為的類的情況下使用一個,僅在少數方法中有所不同。 這些類中的每一個都將派生自抽象類,並以適合其特定情況的方式實現未實現的方法。
接口類似於抽象類,但它不包含方法實現,只包含簽名。 實現接口的類必須實現所有方法。
類可以實現許多接口,但只能從一個抽象類(或任何類型的父類)派生,因為PHP不支持多重繼承。
抽象類和接口都允許多態性; 也就是說,您可以將引用指定為抽象類型(可以引用從中派生的類的任何實例)或實現接口的對象。
假設您理解為什么在其他語言中使用它們,相同的概念適用於PHP。 接口是類“簽名”......它們不包含代碼。 抽象類無法實例化,但它們可以包含實現和抽象(空)函數。
請注意,類只能擴展單個父類(或抽象類),但它可以根據需要實現任意數量的接口。
typically make do without them, unlike in languages like C++ or Java. 但考慮到PHP沒有嚴格的類型,沒有編譯時檢查的概念,通常使沒有他們,不像在像C ++或Java語言。
核心PHP需要一些東西的接口。 例如:
class Foo implements Countable
{
public function count()
{
return 5;
}
}
echo count(new Foo()); // returns 5
如果刪除“implements Countable”,PHP將不會調用您的count
方法。 您可以實現許多其他接口,允許自定義對象以類似的方式運行。 例如,您可以創建一個使用foreach
迭代的對象。
正如我之前提到的,用戶級別的接口在PHP中並不是非常有用。 但是如果你使用類型提示,它們可以是:
function foo(MyInterface $bar)
{
$bar->someMethod();
}
假設someMethod
在聲明MyInterface
,那么你就保證了調用$bar->someMethod()
的存在。 (之所以這在PHP中並不像在其他語言中那樣有用,是因為函數簽名中的類型提示直到運行時才會被檢查。)
空接口也可用作分類類的方法。 假設您想對特定的一組對象執行某些操作。 他們都可以實現一些空接口。 然后你的代碼可以檢查該接口,而不必知道有關該對象的任何信息。
interface Red {}
class Foo implements Red { }
$foo = new Foo();
if ($foo instanceof Red)
{
// do something
}
當你有很多在子類之間共享的代碼時,抽象類很有用,但它本身沒有意義。 您可以將基類聲明為抽象,實現所有共享功能,並將其余功能保留為空。 通過將基類聲明為抽象,沒有人能夠自己使用它。
接口定義了類必須實現的一組方法。 這樣的類通過提供這些方法的具體實現來實現接口。 接口不能包含自己的任何實現; 它只是一組方法簽名。 如果我定義一個名為ILogger
的接口,那么我可以編寫使用ILogger
定義的方法(可能是write
和writeLine
)來傳遞要記錄的消息的代碼。 我可以傳入任何實現ILogger
類,它與客戶端代碼完全相同。
抽象類是類似的,但可以實現一些方法和狀態。 抽象類無法實例化,任何擴展它們的類都必須提供父類中每個abstract
方法的實現。 如果一組類共享一些實現細節但在其他類中有所不同,那么您可以在抽象類中定義共享實現,聲明不同的方法abstract,並讓子類用自己的實現填充它們。 如果我想要一個統一的方法來收集系統信息,添加我的所有記錄器共享的時間戳等,我可能會選擇創建一個處理這些細節的抽象類LoggerBase
,標記write
和writeLine
abstract
這樣任何擴展LoggerBase
類都會只需要指定如何寫入他們的特定日志。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.