2010-10-02 169 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