我有以下课程。
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
。
但它似乎没有这种方法。
有人能告诉我哪里出错了吗?
答案 0 :(得分:3)
虽然您从parent::singleton()
班级致电sub
,但singleton()
仍会创建base
班级的实例(因为您执行了new base()
),没有foo()
方法。
通常,您不应该使用/调用基类中的任何方法,这些方法没有在其中定义。因为它会使您的代码不干净:如果您将实现扩展base
类的另一个类,但忘记实现foo()
方法,该怎么办?你可以很快地结束致命错误......
如果您确定,这个foo()
方法将始终由任何子类实现 - 您可以在基类中定义为抽象方法 - 那么任何子类都将被强制实现它。或者至少作为同一基类中的空方法......这样你的代码就会变得干净整洁。
答案 1 :(得分:3)
方法foo
将不存在,因为正在创建的单例是base
的实例。这是正在发生的事情:
sub
sub
的构造函数获取单例实例。singleton()
创建base
base
构造函数检查base
类是否包含名为foo的方法。它不是。 修改强>
我得到了一个网址,例如site.com/sub/foo所以调用了class sub,我希望base检查foo是否不存在然后我会破坏代码... foo可以是任何东西,只要它作为子类的方法存在< / p>
在这种情况下,单例模式是多余的。相反,您可以从实现所需前控制器模式的基本工厂类开始:
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');