[英]“Class X extends Y (abstract), Y implements Z (interface). ”Cannot call abstract method of interface Z"
Here are my PHP abstraction classes. 这是我的PHP抽象类。 The bottom most class is one of the classes that will extend the abstract class and leave some of the complex calculation logic to the parent implementation. 最底层的类是扩展抽象类并将一些复杂的计算逻辑留给父实现的类之一。
The point of the interface class (the top most abstraction) is to force those lower implementations have their own static public function id($params=false){
method. 接口类(最顶层的抽象)的要点是强制那些较低的实现具有自己的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';
}
}
The end result is that if I call: 最终的结果是,如果我打电话:
$o = new MyImplementation();
$o->run();
I get a fatal error: Fatal error: Cannot call abstract method MyInterface::id();
我得到致命错误: Fatal error: Cannot call abstract method MyInterface::id();
Why is MyAbstraction::run()
calling the id()
method of its parent (interface) instead of the method found in its child (descendant) class? 为什么MyAbstraction::run()
调用其父(接口)的id()
方法而不是在其子(后代)类中找到的方法?
All methods declared in an interface must be public; 在接口中声明的所有方法都必须是公共的; this is the nature of an interface. 这是界面的本质。 Reference - PHP interface 参考 - PHP界面
You are using self::id()
in MyAbstraction
class, self
always refers same class. 你在MyAbstraction
类中使用self::id()
, self
总是指同一个类。 reference self vs static 引用自我与静态
you should use static instead of self. 你应该使用静态而不是自我。 Refer below code. 请参阅以下代码。
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();
In above code static::id()
will call function of class which is in context ie MyImplementation
class. 在上面的代码中, static::id()
将调用上下文中的类函数,即MyImplementation
类。
This phenomenon known as Late Static Binding 这种现象称为后期静态绑定
"self" is reference to "MyAbstraction" class (itself). “self”是指“MyAbstraction”类(本身)。 So it try to search MyAbstraction::id()
, and got an error. 所以它试图搜索MyAbstraction::id()
,并得到一个错误。
static::id();
你应该使用“static”关键字static::id();
($this->id)
. 你不能在静态方法中使用$ this ($this->id)
。 MyImplementation::run();
您可以使用静态调用执行相同的操作: MyImplementation::run();
Try to replace your self::id()
by static::id()
. 尝试用static::id()
替换你的self::id()
static::id()
。
You use the Late Static Bindings of PHP here. 你在这里使用PHP的Late Static Bindings 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.