在接口中实现类型提示“父级”会引发错误
Posted
技术标签:
【中文标题】在接口中实现类型提示“父级”会引发错误【英文标题】:Implement type hinting 'parent' in interface throws an error 【发布时间】:2019-11-12 09:30:55 【问题描述】:可以在界面中输入提示self
:
interface I
public function instanceOfSelf(self $object);
class A implements I
private function printBool(bool $b)
echo ($b ? 'true' : 'false') . "\n";
public function instanceOfSelf(I $object)
$this->printBool($object instanceof I);
$a = new A;
$a->instanceOfSelf($a); // true
也可以在界面中输入提示parent
,这意味着下面的代码不会产生错误:
interface I1
interface I2 extends I1
public function instanceOfSelf(self $object);
public function instanceOfParent(parent $object);
但是,当根据I2::instanceOfParent
提示I1
时会抛出错误:
// Duplication for completion...
interface I1
interface I2 extends I1
public function instanceOfSelf(self $object);
public function instanceOfParent(parent $object);
class A implements I1
class B implements I2
private function printBool(bool $b)
echo ($b ? 'true' : 'false') . "\n";
public function instanceOfSelf(I2 $object)
$this->printBool($object instanceof I2);
public function instanceOfParent(I1 $object)
$this->printBool($object instanceof I1);
$a = new A;
$b = new B;
$b->instanceOfSelf($b); // true
$b->instanceOfParent($a); // true
$b->instanceOfParent($b); // true
这会产生以下错误(php 5.6.30、7.3.3、7.4.0):
Fatal error: Declaration of B::instanceOfParent(I1 $object) must be compatible with I2::instanceOfParent(parent $object)
那么如果I1
不是I2
的父级,那么谁是?
这是一个已知的错误,可以在界面中键入提示parent
而无法实现此功能?
【问题讨论】:
【参考方案1】:PHP 7.4 will thrown new deprecation error message 如果在没有父类型的地方使用了parent
伪类型。接口就是其中一个例子。
When I execute your code I get 2 errors in PHP 7.4:
不推荐使用:当当前类范围在第 8 行的 /in/tOSug 中没有父级时,不能使用“父级”
致命错误:无法检查 B::instanceOfParent(I1 $object) 和 I2::instanceOfParent(parent $object) 之间的兼容性,因为第 22 行的 /in/tOSug 中没有类父级
这表明问题出在哪里。您不能在界面中使用parent
。
您可以通过将parent
替换为接口的实际名称来解决此问题:
// Duplication for completion...
interface I1
interface I2 extends I1
public function instanceOfSelf(self $object);
public function instanceOfParent(I1 $object);
class A implements I1
class B implements I2
private function printBool(bool $b)
echo ($b ? 'true' : 'false') . "\n";
public function instanceOfSelf(I2 $object)
$this->printBool($object instanceof I2);
public function instanceOfParent(I1 $object)
$this->printBool($object instanceof I1);
$a = new A;
$b = new B;
$b->instanceOfSelf($b); // true
$b->instanceOfParent($a); // true
$b->instanceOfParent($b); // true
在Type declarations 下的 PHP 手册中没有记录使用 parent
的足够有趣的类型提示
解释为什么代码的行为不符合您的预期。
关键字parent
始终指代父类,或者换句话说,您所扩展的类。在您的示例中,B
类没有父级。它只实现了一个接口。
class B
public function amIanOrphan()
var_dump(parent::class);
$b = new B;
$b->amIanOrphan();
这段代码会报错:
致命错误:未捕获的错误:当前类范围没有父级时无法使用“父级”
接口本身不是类。接口只告诉你类有哪些方法。 这段代码和上面一模一样:
interface I1
public function amIanOrphan();
interface I2 extends I1
class B implements I2
public function amIanOrphan()
var_dump(parent::class);
接口从另一个接口扩展而来,但类本身仍然没有父类。上面的代码仍然会抛出错误,因为 B 没有父级,同样的逻辑也适用于类型提示。
【讨论】:
谢谢,我没有收到“已弃用”警告,因为我使用了 wandbox。以上是关于在接口中实现类型提示“父级”会引发错误的主要内容,如果未能解决你的问题,请参考以下文章
“/”应用程序中的服务器错误。引发类型为“System.OutOfMemoryException”的异常。
在 python 中使用 cppyy 时,指针变量引发错误为未知类型