2012-01-17 143 views
11

我有一組擴展抽象類的類。抽象類包含使用後期靜態綁定來獲取子類中定義的信息的方法。因此,例如,抽象類可能具有包含線的方法:PHP - 強制類聲明屬性

$var = static::$childVar . ' some text'; 

以這種方式,能夠在運行時在抽象類中定義的方法,以基於一個變量的值不同串在子類中定義。

我想要做的是有一些機制,迫使子類聲明這個變量,消除如果變量沒有設置被調用方法的可能性。

使用接口,可能需要一個類來定義方法(以及常量,不幸的是它們的可見性不能通過public/protected/private修改)。所以如果一個類實現了一個接口,但是沒有定義接口中指定的所有方法,則會產生一個錯誤。但是,沒有辦法使用接口來要求類定義屬性。

我已經看到一些建議在接口中使用getter方法的材料(例如getChildVar())隱式地要求變量聲明,但這不適合我,因爲我不想讓變量在類之外訪問(他們有protected知名度)。

類似地,常量不起作用,因爲它們不支持protected可見性修改器。

我知道我總是可以使用isset()語句在抽象類的方法(或者甚至是構造函數)中檢查它,但與使用接口確保方法定義相比,這看起來不夠優雅。我想知道是否有一些標準的方法來做到這一點,而不用硬編碼抽象類中的需求。順便說一句,如果有人知道你爲什麼不能在接口中聲明變量,那麼我很想知道推理是什麼。這對我來說似乎是一個重大的監督。

任何幫助將不勝感激。

回答

10

您無法在界面中強制實施變量,因爲界面是關於如何使用您的課程的公開說明。如果我是另一位參與項目的開發人員,我希望能夠看看界面,並且知道我可以假設的所有方法都是在類中實現的,並且實現了該界面。這與私人或受保護的財產不是完全相關的,或者對於這個問題確實有任何特定的財產。吸氣劑/定型劑是這種事情的標準。

現在的監管權力是你不能有一個神奇的方法試圖訪問一個未定義的靜態屬性。這對你來說是理想的解決方案。

如果在運行時聲明靜態屬性,爲什麼不執行setChildVar()方法,或者放置父類方法來獲取靜態綁定屬性,並在未設置時引發錯誤?你甚至可以實現一個「驅動程序」模式來實現這一點:

<?php 

class MyParentClass { 

    public function __get($key) 
    { 
     if (!isset(static::$$key)) 
     { 
      throw new Exception('Child class '.get_called_class().' failed to define static '.$key.' property'); 
     } 

     return static::$$key; 
    } 

    public function getText() 
    { 
     return $this->childVar . ' some text'; 
    } 

} 

class MyChildClass extends MyParentClass { 

    protected static $childVar = 'some value:'; 

} 

$a = new MyChildClass; 
echo $a->getText(); // some value: some text 
+0

感謝您的解釋。我現在明白爲什麼接口不允許變量聲明(儘管我不確定我完全同意該決定背後的原因)。我實際上想出了幾乎與行相同的代碼,因此很高興知道我做得對。 – C106 2012-01-17 12:02:49