2014 年 11 月发布的 PHP 7.4改进了类型变化。
问题中的代码仍然无效:
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); // This will still be a compile error
// more methods here that "override" the Collection methods like "add()" does
}
因为Collection
接口保证任何实现它的东西都可以接受任何类型Item
的对象作为add
.
但是,以下代码在 PHP 7.4 中有效:
interface Item {
// some methods here
}
interface SuperItem extends Item {
// some extra methods here, not defined in Item
}
interface Collection {
public function add(SuperItem $item);
// more methods here
}
interface SuperCollection extends Collection {
public function add(Item $item); // no problem
// more methods here that "override" the Collection methods like "add()" does
}
在这种情况下Collection
保证它可以接受任何SuperItem
. 由于所有SuperItem
的 s 都是Item
s,SuperCollection
所以也做了这个保证,同时也保证它可以接受任何其他类型的Item
. 这称为逆变方法参数类型。
在早期版本的 PHP 中存在有限的类型变化形式。假设其他接口与问题中的一样,则SuperCollection
可以定义为:
interface SuperCollection extends Collection {
public function add($item); // no problem
// more methods here that "override" the Collection methods like "add()" does
}
这可以解释为意味着任何值都可以传递给该add
方法。这当然包括所有Item
的 s,所以这仍然是类型安全的,或者它可以解释为意味着一个未指定的值类,通常记录为mixed
可以传递,程序员需要使用其他知识来确切地知道什么可以使用该函数.