这是我的PHP抽象类。最底层的类是扩展抽象类并将一些复杂的计算逻辑留给父实现的类之一。
接口类(最顶层的抽象)的要点是强制那些较低的实现具有自己的static public function id($params=false){
方法。
// My top level abstraction, to be implemented only by "MyAbstraction"
interface MyInterface{
static public function id();
}
// My second (lower) level of abstraction, to be extended
// by all child classes. This is an abstraction of just the
// common heavy lifting logic, common methods and properties.
// This class is never instantiated, hence the "abstract" modifier.
// Also, this class doesn't override the id() method. It is left
// for the descendant classes to do.
abstract class MyAbstraction implements MyInterface{
// Some heavy lifting here, including common methods, properties, etc
// ....
// ....
static public function run(){
$this->id = self::id(); // This is failing with fatal error
}
}
// This is one of many "children" that only extend the needed methods/properties
class MyImplementation extends MyAbstraction{
// As you can see, I have implemented the "forced"
// method, coming from the top most interface abstraction
static public function id(){
return 'XXX';
}
}
最终结果是,如果我打电话:
$o = new MyImplementation();
$o->run();
我收到致命错误:
Fatal error: Cannot call abstract method MyInterface::id();
为什么MyAbstraction::run()
调用其父(接口)的id()
方法而不是在其子(后代)类中找到的方法?
答案 0 :(得分:4)
接口中声明的所有方法都必须是公共的;这是界面的本质。 Reference - PHP interface
您在self::id()
班级中使用MyAbstraction
,self
始终引用相同的班级。 reference self vs static
你应该使用静态而不是自我。请参阅下面的代码。
interface MyInterface{
public function id();
}
abstract class MyAbstraction implements MyInterface{
public $id;
// Some heavy lifting here, including common methods, properties, etc
// ....
// ....
public function run(){
$this->id = static::id(); // This is failing with fatal error
}
}
class MyImplementation extends MyAbstraction{
// As you can see, I have implemented the "forced"
// method, coming from the top most interface abstraction
public function id(){
return 'XXX';
}
}
$o = new MyImplementation();
$o->run();
在上面的代码中,static::id()
将调用类的函数,该函数位于上下文中,即MyImplementation
类。
这种现象称为Late Static Binding
答案 1 :(得分:2)
“self”是对“MyAbstraction”类(本身)的引用。因此,它尝试搜索MyAbstraction::id()
,并收到错误。
static::id();
($this->id)
中使用$ this。MyImplementation::run();
答案 2 :(得分:1)
尝试将self::id()
替换为static::id()
。
您可以在此处使用PHP的Updated JSFiddle。