问题描述
考虑以下PHP接口:
interface Item {
// some methods here
}
interface SuperItem extends Item {
// some extra methods here, not defined in Item
}
interface Collection {
public function add(Item $item);
// more methods here
}
interface SuperCollection extends Collection {
public function add(SuperItem $item);
// more methods here that "override" the Collection methods like "add()" does
}
我正在使用PHPStorm,当我这样做时,我在IDE中出现一个错误,它基本上说明 add()
的定义code> SuperCollection 与其扩展的界面中的定义不兼容, Collection
。
I'm using PHPStorm, and when I do this, I get an error in the IDE that basically states the definition for add()
in SuperCollection
is not compatible with the definition in the interface it extends, Collection
.
在某种程度上,我可以看到这是一个问题,因为该方法的签名与覆盖完全的签名不匹配。但是,我确实认为这是兼容的,因为 SuperItem
扩展 Item
,所以我会查看 add(SuperItem)
与 add(Item)
相同。
In one way, I can see this being a problem, as the signature of the method does not match the one it "overrides" exactly. However, I do feel that this would be compatible, as SuperItem
extends Item
, so I would view add(SuperItem)
the same as add(Item)
.
I我很好奇这是否支持PHP(版本5.4或更高版本),并且IDE可能存在一个无法正确识别错误的错误。
I'm curious as to if this is supported by PHP (version 5.4 or above), and maybe the IDE has a bug that doesn't properly catch this.
推荐答案
不,我很确定PHP在任何版本中都不支持这一点,而且它宁愿打败接口点。
No, I'm pretty sure PHP doesn't support this, in any version, and it would rather defeat the point of an interface.
接口的关键在于它为您提供了与引用相同接口的其他代码的固定合同。
The point of an interface is that it gives you a fixed contract with other code that references the same interface.
例如,考虑这样的函数:
For example, consider a function like this:
function doSomething(Collection $loopMe) { ..... }
此函数需要接收一个实现 Collection
接口的对象。
This function expects to receive an object that implements the Collection
interface.
在函数中,程序员可以写入调用知道该对象将实现这些方法的方法在 Collection
中定义。
Within the function, the programmer would be able to write calls to methods that are defined in Collection
, knowing that the object would implement those methods.
如果你有一个被覆盖的接口像这样,你有一个问题,因为可以将 SuperCollection
对象传递给该函数。它会起作用,因为它继承了它也是 Collection
对象。但是函数中的代码不再能确定它知道 add()
方法的定义是什么。
If you have an overridden interface like this, then you have a problem with this, because a SuperCollection
object could be passed into the function. It would work because it also is a Collection
object due to the inheritance. But then the code in the function could no longer be sure that it knows what the definition of the add()
method is.
根据定义,接口是固定合同。它是不可变的。
An interface is, by definition, a fixed contract. It is immutable.
作为替代方案,您可以考虑使用抽象类而不是接口。这将允许您在非严格模式下覆盖,但如果您使用严格模式仍然会出现错误,原因相同。
As an alternative, you could consider using abstract classes instead of interfaces. This would allow you to override in non-Strict mode, although you'll still get errors if you use Strict Mode, for the same reasons.
这篇关于您可以使用不同但“兼容”的签名覆盖接口方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!