gpt4 book ai didi

php - 使用不兼容的函数实现接口(interface)和错误

转载 作者:可可西里 更新时间:2023-11-01 13:26:19 38 4
gpt4 key购买 nike

我有这个测试脚本:

<?php
interface A
{
function myfunction();
}

class B implements A
{
function myfunction($var = "default")
{
echo $var;
}
}

class C extends B
{
function myfunction()
{
echo "myfunction";
}
}

$c = new C();
$c->myfunction();

$b = new B();
$b->myfunction();

这运行良好并输出 myfunctiondefault

现在,当我删除接口(interface) A 并让 B 不再实现 A 时,如下所示:

<?php
class B
{
function myfunction($var = "default")
{
echo $var;
}
}

class C extends B
{
function myfunction()
{
echo "myfunction";
}
}

$c = new C();
$c->myfunction();

$b = new B();
$b->myfunction();

我收到这个错误:

PHP Strict standards:  Declaration of C::myfunction() should be compatible with that of B::myfunction() in /var/www/test/index.php on line 16

Strict standards: Declaration of C::myfunction() should be compatible with that of B::myfunction() in /var/www/test/index.php on line 16

myfunctiondefault

为什么这在第一次就奏效了?我希望在这两种情况下都会出现错误......

最佳答案

使用接口(interface)时,BC 根据接口(interface)声明独立验证。 C extends B 无关紧要。 C间接实现了AC::myfunction兼容A::myfunction,所以没有问题. B::myfunction 也与 A::myfunction 兼容,所以也没有问题。

在没有接口(interface)的情况下,B::myfunction 是该方法的规范声明,并且由于它接受参数但重写的 C::myfunction 不接受,a引发了 STRICT 警告。

基本上,您要确保此代码有效:

if ($obj instanceof <classWhoseInterfaceIExpect>) {
$obj-><interfaceIExpect>();
}

更具体地说:

if ($obj instanceof A) {
$obj->myfunction();
}

因为 A::myfunction 被规范地声明为不接受任何参数,所以上面的代码将始终有效。但是,没有界面:

if ($obj instanceof B) {
$obj->myfunction('foo');
}

如果 B::myfunction 是接受参数的规范声明,但 C 提供了一个不接受参数的实现,那么您就产生了冲突。因此警告。这是为了回答为什么它以这种方式工作的问题,这是 PHP 的思想解释。


警告:是的,即使您使用界面,这仍然会产生相同的冲突:

interface A { ... }
class B implements A { ... }
class C extends B { ... } // conflicting implementation to B

$obj = new C;

if ($obj instanceof B) {
$obj->myfunction('foo');
}

Cinstanceof AB,但它与这两个实现不兼容myfunction 同时。这是您创建两个相互冲突的实现的问题。 PHP 是否应该在这里发出警告是值得商榷的。 PHP 不能鱼与熊掌兼得。它的类型系统可以帮助您尽早发现某些错误;它当然不是完美的,无法保护您免于从所有可能的角度射自己的脚。

如果您想避免此类问题,您基本上不应该更改方法签名。那,或者让变化向下级联;这意味着每个扩展类都与其直接父类的方法签名兼容。所以 C::myfunction 应该至少接受一个可选参数。也许 PHP 应该捕获这种情况,也许它可以被认为是一个错误,您不会在所有情况下都收到警告。同样,这是值得商榷的,您应该从一开始就避免陷入这种情况。

关于php - 使用不兼容的函数实现接口(interface)和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23558934/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com