[英]Why are abstract classes necessary in PHP?
我們可以使用簡單的繼承或接口而不是抽象。 為什么我們需要在PHP中使用抽象? 我們如何使用抽象隱藏基本功能? 我很困惑使用抽象和接口和繼承。 哪里用哪個? 請幫助理解我。
我認為首先澄清術語是非常重要的,以便更精細地回答這個問題。
abstract
,則此實現可以由抽象類本身提供,或者由擴展類提供。 它還允許實現屬性和私有/受保護方法,因為這里的繼承就像一個基類而不僅僅是一個需求。 所以回答這個問題,“ 為什么我們在PHP中有抽象類 ”,因為它很有用。 您可能會首先將這些視為棘手的想法,但它們實際上可以協同工作以提供聯合實用程序。
考慮到有時候接口不足以創建有用的實現。 接口只能強制存在方法,並且其簽名與實現的接口兼容。 例如,可能存在您希望提供接口的默認實現的情況。
interface Device {
public function input(Stream $in);
public function output(): Stream;
}
abstract class DefaultDevice implements Device {
protected $buffer = "";
public function input(Stream $in) {
$this->buffer .= $in->read(1024);
$this->process();
}
abstract protected function process();
}
所以現在任何擴展DefaultDevice
類都可以選擇覆蓋input
方法的實現。 即使接口不需要它,它也必須實現一個process
方法。 這意味着實現Device
接口的其他類可以向后兼容,這仍然是一個實現細節。
將實現與規范分開通常是編寫良好的軟件的關鍵屬性。
作為一個很好的例子,看一下Device
接口本身。 我們依靠input
方法接受Stream
類型和output
方法來返回Stream
類型。 由於Stream
本身實際上可以是一個接口,這意味着任何實現Stream
類型都是可以接受的。 所以我可以創建自己的類並實現Stream
接口,而不會破壞此代碼。
class CustomStream implements Stream {
public function read($bytes = 1024) {
/* implementation */
}
public function write($data) {
/* implementation */
}
}
$device->input(new CustomStream); // this will not throw an error
abstract
類用於提供一組數據成員或方法,使其可用於從中繼承的類,即使基類在沒有繼承實現的情況下不是特別有用(並且永遠不應該自己實例化)。
從這里繼承接管。
另一方面, interface
是提供一組實現規則,要求每個使用該接口的類實現其中的規范。 實現相同接口的類不需要相互繼承,它們實現接口,因此可以在需要該組功能的任何應用程序中使用它們。
正如練習一樣,我們可以嘗試創建一些類來處理幾何形狀。
基類:
class Shape
{
public function draw()
{
}
}
上面的代碼片段中只描述了基類的相關部分。 當然,它應該具有存儲其位置,線條顏色等的屬性和方法(至少是構造函數)。
一些派生類:
class Circle extends Shape
{
public function draw()
{
// the code to draw a circle
}
}
class Rectangle extends Shape
{
public function draw()
{
// the code to draw a rectangle
}
}
我們可以在基類Shape
為方法draw()
提供實現嗎?
當然不是。 Shape
是通用的,它並不僅僅意味着“圓形”或“矩形”或“三角形”。 沒有辦法為Shape::draw()
提供合理的實現,因為我們甚至不知道它代表什么形狀。
是否可以為Shape::draw()
提供一個空的實現?
顯然它是。 然而,在第二個想法,很明顯,這是不安全的。 無法draw()
擴展Shape
並且不為方法draw()
提供其自己的實現的類的對象。
因為類Shape
無法為方法shape
提供合適的實現,所以它應該以某種方式向派生類發出信號,並強制它們提供實現。
它表明這種情況的方式是abstract
關鍵字。 abstract
方法告訴類的讀者該類無法提供實現,因為它太通用了,它將此責任委托給擴展它的每個類。
具有abstract
方法的類未完全定義。 這就是為什么它是一個abstract
類而無法實例化的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.