kul*_*hch 5 php oop inheritance
为什么我会收到此错误:
Fatal error: Declaration of ConcreteFooMapper::load() must be compatible with that of AbstractFooMapper::load() on line 18
Run Code Online (Sandbox Code Playgroud)
从这个代码:
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
abstract class AbstractFooMapper {
abstract public function load(Foo $entity, array $data);
}
class ConcreteFooMapper extends AbstractFooMapper {
public function load(ConcreteFoo $entity, array $data) {
}
}
?>
Run Code Online (Sandbox Code Playgroud)
我最初的想法是这是一个错误;PHP在评估方法声明时没有检测到ConcreteFoo实现了Foo。我认为这是因为当您运行此代码时:
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
$foo = new ConcreteFoo();
if ($foo instanceof Foo)
{
print 'w00t!';
}
else
{
print 'FAIL!';
}
?>
Run Code Online (Sandbox Code Playgroud)
它打印w00t!表示ConcreteFoo是Foo 的一个实例。
关于这种行为是否正确的任何见解?
实现接口的类必须使用与接口中定义的完全相同的方法签名。不这样做将导致致命错误。对于扩展抽象类的类也有相同的规则。
这就是正确的行为\逻辑。
检查此处抽象类型很有用,因为它们可用于定义和强制执行协议;所有实现协议的对象都必须支持的一组操作。
如果我们假设您的代码将毫无异常地工作,那么我们会遇到以下问题:ConcreteFooMapper不能使用 some 的实例class ConcreteFoo2 implements Foo作为load方法的参数,但应该(通过抽象类定义)
另外,如果您使用相同的签名,这实际上不是问题,因为所有类\类型信息都可用。请检查以下代码
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
abstract class AbstractFooMapper {
abstract public function load(Foo $entity, array $data);
}
class ConcreteFooMapper extends AbstractFooMapper {
public function load(Foo $entity, array $data) {
var_dump($entity instanceof Foo);
var_dump($entity instanceof ConcreteFoo);
}
}
$someConcreteFoo = new ConcreteFoo();
$someFooMapper = new ConcreteFooMapper();
$someFooMapper->load($someConcreteFoo, array('somekey' => 'somevalue'));
// output
// bool(true) bool(true)
?>
Run Code Online (Sandbox Code Playgroud)