首頁  >  文章  >  後端開發  >  深入了解PHP物件導向、模式與實務-高階特性(二)

深入了解PHP物件導向、模式與實務-高階特性(二)

黄舟
黄舟原創
2017-03-20 09:54:401221瀏覽

抽象類別

抽象類別不能直接被實例化。抽象類別只定義(或部分實作)子類別所需的方法。子類別可以繼承它並且透過實作其中的抽象方法,使抽象類別具體化。你可以用abstract關鍵字定義一個抽象類別。大多數情況下,抽象類別至少包含一個抽象方法。抽象方法用abstract關鍵字聲明,其中不能有具體內容。

abstract class ShopProductWriter{
    protected $products = array();   
     public function addProduct(ShopProduct $shopProduct)
    {
        $this->products[] = $shopProduct;
    }    abstract public function write();}

建立抽象方法後,要確保所有的子類別中都實作了該方法,但實作的細節可以先不確定。每個子類別都必須實作抽象類別中的所有抽象方法,或者把它們本身也聲明為抽象方法。擴展類別不僅負責簡單實作抽象類別中的方法,還必須重新聲明方法。新的實作方法的存取控制不能比抽象方法的存取控制更嚴格。新的實作方法的參數個數應該和抽象方法的參數個數一樣,重新產生對應的型別提示。

class XmlProductWriter extends ShopProductWriter{

    public function write()
    {
        $str=&#39;<?xml version="1.0" encoding="UTF-8"?>&#39;."\n";        
        $str.="<products>\n";        
        foreach ($this->products as $shopProduct) {            
        $str.="\t<product title=\"{$shopProduct->getTitle()}\">\n";            
        $str.="\t\t<summary>\n";            
        $str.="\t\t{$shopProduct->getSummaryLine()}\n";            
        $str.="\t\t</summary>\n";            
        $str.="\t</product>\n";
        }        
        $str.="</products>\n";        
        print $str;
    }
}class TextProductWriter extends ShopProductWriter{

    public function write()
    {
        $str="PRODUCTS:\n";        
        foreach ($this->products as $shopProduct) {            
        $str.=$shopProduct->getSummaryLine()."\n";
        }        
        print $str;
    }
}

介面

抽象類別提供了具體的實作的標準,而介面(interface)則是純粹的模板。介面只能定義功能,而不包含實現的內容。介面可用關鍵字interface來聲明。介面可以包含屬性和方法聲明,但是方法體為空。

interface Chargeable{
    public function getPrice();}

任何實作介面的類別都要實作介面中所定義的所有方法,否則類別必須宣告為abstract。一個類別可以在聲明中使用implement關鍵字來實作某個介面。

class ShopProduct implements Chargeable
{
    //...
    function getPrice()
    {        return ($this->getPrice-$this->discount);
    }
    //...}

ShopProduct類別已經有一個getPrice()方法,那麼實作Chargeable介面還有用嗎?答案是肯定的,因為類型。實作介面的類別接受了它繼承的類別及實作的介面的類型。

任何類別都可以實作接口,介面可以有效地將不相關的型別聯結起來。一個類別可以同時繼承一個父類別和實作任意個介面。 extends子句一個在implements子句之前。

class Consultancy extends TimedService implements Bookable, Chargeable{//...}

延遲靜態綁定:static關鍵字

該特性最明顯的標誌就是新關鍵字static。 static類似於self,但它指的是被呼叫的類別而不是包含類別。在本例中,它的意思是呼叫Document::create()將產生一個新的Document物件,而不是試圖實例化一個DomainObject物件。

abstract class DomainObject{

    public static function create()
    {
        return new static();
    }
}class User extends DomainObject{   }class Document extends DomainObject{}

print_r(Document::create());//输出为Document Object//      (//      )

static關鍵字不只可以用於實例化。和self和parent一樣,static也可以作為靜態方法呼叫的標識符,甚至是從非靜態上下文中呼叫。

abstract class DomainObject{
    private $group;    public function construct()
    {
        $this->group=static::getGroup();
    }    public static function create()
    {
        return new static();
    }    static function getGroup(){
        return "default";
    }
}class User extends DomainObject{   }class Document extends DomainObject{
    static function getGroup(){
        return "document";
    }
}class SpreadSheet extends Document{}

print_r(User::create());
print_r(SpreadSheet::create());//输出为User Object//      
(//          
[group:DomainObject:private]=>default
//      
)//      
SpreadSheet Object//      
(//          
[group:DomainObject:private]=>document//      
)

以上是深入了解PHP物件導向、模式與實務-高階特性(二)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn