Php 子方法的声明必须与父方法兼容
这是我的密码: 我有一个类Php 子方法的声明必须与父方法兼容,php,Php,这是我的密码: 我有一个类a,它有一个方法foo,该方法返回一个Bar对象 class A { public function foo(): Bar { //some ops return $bar; //'Bar' object } } class B extends A { public function foo(): BarX { //some ops return $barX; //'BarX' o
a
,它有一个方法foo
,该方法返回一个Bar
对象
class A {
public function foo(): Bar {
//some ops
return $bar; //'Bar' object
}
}
class B extends A {
public function foo(): BarX {
//some ops
return $barX; //'BarX' object
}
}
我还有一个类B
,它扩展了类a
,使用一个重写的方法foo
,返回一个BarX
对象
class A {
public function foo(): Bar {
//some ops
return $bar; //'Bar' object
}
}
class B extends A {
public function foo(): BarX {
//some ops
return $barX; //'BarX' object
}
}
重要的是条码类扩展了条码类
当我运行代码时,在类B
上有一个错误,说:
B::foo():Bar的声明必须与A::foo():Bar兼容
既然BarX
扩展了Bar
,它们怎么会不兼容呢?我怎样才能解决这个问题呢
谢谢。让Bar和BarX都实现一个接口,并将其作为返回类型
<?php
interface BarInterface(){ }
class Bar implements BarInterface(){ }
class BarX implements BarInterface(){ }
class A {
public function foo(): BarInterface {
//some ops
return $bar; //'Bar' object
}
}
class B extends A {
public function foo(): BarInterface {
//some ops
return $barX; //'BarX' object
}
}
让Bar和BarX实现一个接口,并将其作为返回类型
<?php
interface BarInterface(){ }
class Bar implements BarInterface(){ }
class BarX implements BarInterface(){ }
class A {
public function foo(): BarInterface {
//some ops
return $bar; //'Bar' object
}
}
class B extends A {
public function foo(): BarInterface {
//some ops
return $barX; //'BarX' object
}
}
您可以返回一个BarX,但由于B扩展了a,它必须返回相同的类型,但由于BarX是Bar,您可以这样做:
class B extends A {
public function foo(): Bar {
$barX = new BarX;
//some ops
return $barX; //'BarX' object
}
}
您可以返回BarX,但由于B扩展了a,它必须返回相同的类型,但由于BarX是Bar,您可以这样做:
class B extends A {
public function foo(): Bar {
$barX = new BarX;
//some ops
return $barX; //'BarX' object
}
}
仔细研究并考虑:
function (A $a) {
$bar = $a->foo();
}
$bar
将成为bar
还是BarX
?你不知道。由于$a
既可以作为a
注入,也可以作为B
注入(因为B是a
的实例,因为B扩展了a
),因此无法预测$a
将是什么,也无法预测$bar
将是什么
这就是为什么统一和可预测的界面很重要,这也是PHP抱怨的原因。仔细研究并考虑:
function (A $a) {
$bar = $a->foo();
}
$bar
将成为bar
还是BarX
?你不知道。由于$a
既可以作为a
注入,也可以作为B
注入(因为B是a
的实例,因为B扩展了a
),因此无法预测$a
将是什么,也无法预测$bar
将是什么
这就是为什么统一和可预测的接口很重要,这也是PHP抱怨的地方。考虑:function(a$a){$b=$a->foo();}
——是$b
aBar
还是BarX
?你不知道。可以说,如果两种类型都兼容,那也没关系。但是你不应该在你的打字系统中有这样的反复无常。@deceze:是的,我有$b
是一个条形图
,因为$a
是一个a
对象,而a
对象的foo
方法返回条形图
对象。在您的示例中没有B
对象,$B
怎么可能是BarX
对象?既然B
是a
的子类,调用方还可以为$a
注入B
@deceze我理解:),所以我认为让两个foo
函数都返回一个Bar
是最好的解决方案,谢谢,我只是在写这个作为答案的过程中…:DConsider:function(a$a){$b=$a->foo();}
-是$b
aBar
还是BarX
?你不知道。可以说,如果两种类型都兼容,那也没关系。但是你不应该在你的打字系统中有这样的反复无常。@deceze:是的,我有$b
是一个条形图
,因为$a
是一个a
对象,而a
对象的foo
方法返回条形图
对象。在您的示例中没有B
对象,$B
怎么可能是BarX
对象?既然B
是a
的子类,调用方还可以为$a
注入B
@deceze我理解:),所以我认为让foo
函数返回Bar
是最好的解决方案,谢谢,我只是在写这个作为答案的过程中…:DThanks@Goon3r,但实际上这意味着a::foo()
和B::foo()
方法可以返回Bar
或BarX
对象。这等于有:A::foo():**Bar**
和B::foo()**Bar**
…这使得界面变得无用,不是吗?谢谢@Goon3r,但实际上这意味着A::foo()
和B::foo()
方法都可以返回Bar
或BarX
对象。这等于有:A::foo():**Bar**
和B::foo()**Bar**
…这使得界面毫无用处,不是吗?是的,我想我除了做soYep别无选择,我想我除了做soYep别无选择