abstract class base {
abstract public function test();
public function run()
{
self::test();
}
}
class son extends base {
public function test()
{
echo 1;
}
}
son::run();
报道:
致命错误:无法调用抽象 方法base :: test()
但是son::test()
有效,为什么还有办法解决?
答案 0 :(得分:4)
当然:
致命错误:无法调用抽象方法base :: test()
它没有你可以调用的方法体。如果run()应该是Template Method,则使用$this
而不是self
引用类范围,然后创建$ son实例来调用run(),例如
abstract class BaseClass {
abstract public function test();
public function run()
{
$this->test();
}
}
class Son extends BaseClass {
public function test()
{
echo 1;
}
}
$son = new Son;
$son->run(); // 1
这很奇怪,因为那时你可以直接调用test()。
另请注意,在您的示例中
son::run();
是错误的,因为run()方法没有声明为静态,而PHP将执行run(),但它被认为是错误的用法并且会引发E_STRICT错误。但是,如果要定义run()static,则不能再引用$this
,因为不会从实例范围调用静态方法,而是调用类范围。
编辑我即将添加PHP5.3解决方案,但是在我输入时看到@erenon已经这样做了,所以我只在{{{ 3}}
答案 1 :(得分:4)
“self”是词法范围的,也就是说,如果你在Base的方法中使用“self”,“self”意味着“Base”,无论你如何在运行时调用这个方法。 php5.3引入了一种新的动态绑定,具有讽刺意味的是,它被称为“静态”。以下在php 5.3
中按预期工作abstract class base {
abstract public static function test();
static public function run()
{
static::test();
}
}
class son extends base {
static public function test()
{
echo 1;
}
}
son::run();
答案 2 :(得分:1)
Abstract methods没有实现,因此无法调用。如果方法没有被定义为抽象,并且实际上有一个实现,那么它可以由您的代码执行。例如:
public function test(){
echo "Hello from base!";
}
答案 3 :(得分:1)
工厂/单件模式混合:
class Base
{
static private $instance;
static function getSon() {
if (null === self::$instance) {
self::$instance = new Son;();
}
return self::$instance;
}
}
class Son
{
public function test() {
echo 1;
}
}
Base::getSon()->test(); //1