2010-10-02 222 views
0

我有以下類。php oop擴展問題

class base { 

    private function __construct(){ 
     //check if foo method exists 
     //$this->foo(); // if it exists 
    } 

    public static function singleton(){ 
     if(!isset(self::$singleton)){ 
      self::$singleton = new base(); 
     } 
     return self::$singleton; 
    } 
} 

class sub extends base{ 
    public function __construct() { 
     parent::singleton(); 
    } 

    public function foo(){ 

    } 
} 

然後初始化它像這樣

$test = new sub(); 

我的問題是,我想檢查base __construct如果子有foo方法。 但它似乎沒有這種方法。

有人能告訴我我哪裏出錯了嗎?

+2

爲什麼要檢查'foo'方法?而你的單例實現有點奇怪。 – NullUserException 2010-10-02 18:46:02

+0

我想檢查foo,因爲如果找不到,它可以調用默認方法。爲什麼這個單身人士很奇怪? – Val 2010-10-02 18:51:37

+2

也許是因爲你的單例方法正在實例化一個完全不同的類,名爲'controller'? – BoltClock 2010-10-02 18:56:21

回答

3

雖然你叫parent::singleton()sub類,但仍singleton()創建你base類的實例(因爲你new base()),它並沒有你foo()方法。

一般而言,您不應該使用/調用基類中的任何方法,這些方法中沒有定義它。因爲它會讓你的代碼不清潔:如果你將實現一些擴展base類的其他類,但忘記實現foo()方法會怎麼樣?你可以用相當快的速度結束致命的錯誤...

如果你確定,這個foo()方法將總是由任何子類實現 - 你可以在基類中以抽象方法定義 - 那麼任何子類都會被迫執行它。或者至少在同一個基類中作爲一個空方法......這樣你的代碼就會變得清晰和結構化。

+0

致命錯誤:無法實例化抽象類基地...在... file.php ...在線28 – Val 2010-10-02 19:11:52

3

方法foo將不存在,因爲正在創建的單例是base的實例。這裏發生的事情:

  1. 創建的sub
  2. sub構造得到單實例的實例。
  3. singleton()如果base類包含一個名爲foo方法創建的base
  4. base構造檢查一個實例。它不是。

編輯

i got a url e.g. site.com/sub/foo so the class sub is called and i want the base to check if foo does not exist then i will break the code... foo can be anything as long as it exists as a method on sub class

在這種情況下單例模式是多餘的。相反,您可以從實現所需前端控制器模式的基本工廠類別開始:

class factory { 
    static public function go($path) { 
    list($type, $action) = explode('/', $path); 
    if (class_exists($type) && // Does the requested type/class exist? 
     is_subclass_of($type, 'factory') && // Basic security. Make sure URL requests can't create an instance of *any* PHP class 
     method_exists($type, $action)) // Check requested method/action 
    { 
     $o = new $type; 
     $o->$action(); 
    } 
    } 
} 

class sub extends factory { 
    public function foo() { 
    echo('To foo or not to foo that is the question.'); 
    } 
} 

factory::go('sub/foo'); 
+0

這是有道理的... ... oop正在做我的標題...:)所以我會怎麼做呢? – Val 2010-10-02 19:23:21

+0

我不是100%確定你想做什麼,但是我會採取一個措施:你希望'base'的每個子類都有一個靜態的'singleton()'方法,它返回一個單例子類型。是這個嗎? – leepowers 2010-10-02 19:30:19

+0

我有一個網址,例如'site.com/sub/foo'所以調用了類的子類,並且我希望基類檢查foo是否不存在,那麼我將打破代碼...只要它存在作爲子方法,foo就可以是任何東西類 – Val 2010-10-02 19:38:34