Php 使用具体类型类实现具有接口类型提示的抽象方法
这里有一个我无法解释的简单问题 在PHP手册中: 若类或接口被指定为类型提示,那个么它的所有子类或实现也是允许的 我记得这是一个抽象方法的例子,但在我看来,它似乎“没有逻辑” 以下是一个例子: 我通过以下方式搜索如何实现方法(在本例中为invoke):Php 使用具体类型类实现具有接口类型提示的抽象方法,php,Php,这里有一个我无法解释的简单问题 在PHP手册中: 若类或接口被指定为类型提示,那个么它的所有子类或实现也是允许的 我记得这是一个抽象方法的例子,但在我看来,它似乎“没有逻辑” 以下是一个例子: 我通过以下方式搜索如何实现方法(在本例中为invoke): <?php namespace Foo\Bundle\BarBundle; abstract class BaseClass { //... abstract public function invoke(AddCon
<?php
namespace Foo\Bundle\BarBundle;
abstract class BaseClass {
//...
abstract public function invoke(AddContactCommandInterface $command);
}
<?php
namespace Foo\Bundle\UpBarBundle;
use Foo\Bundle\BarBundle\BaseClass;
class UpClass extends BaseClass
{
public function invoke(AddContactCommand $command)
{
//...
}
}
在第二个类中,您正在重写基类;调用
方法--
这要求子类中的invoke
方法接受相同的参数-
在本例中,您已经输入了提示参数,$command
的类型是AddContactCommandInterface
——但是,在您的子类中,您使用了参数AddContactCommand
因此,您可以通过使基类中的
$command
与子类中的$command
类型相同来修复它,反之亦然。抽象方法定义了所有派生类都需要实现的函数。在定义抽象方法时,您说过它需要一个AddContactCommandInterface
,然后在子类中将其更改为AddContactCommand
。您正在更改抽象类中指定的“契约”
AddContactCommand
实现接口并不重要。并非所有的addContactCommandInterface
都是AddContactCommands
从使用的角度来看,如果允许这样做,将会造成困难,因为我可能有一个方法希望使用基类
对象。我有一个不同的对象Foo
,它实现了AddContactCommandInterface
。现在,我的方法获得了UpClass
的一个实例,并尝试使用invoke
方法传入我的Foo
对象。这将导致一个致命错误,即使从我对抽象类中指定的契约的理解来看,我应该能够使用我的Foo
对象。混乱和集体歇斯底里接踵而至
这不是逻辑问题,而是一致性问题。如果确实要键入hint
AddContactCommand
,请更改抽象方法。但是,如果您打算使用所有实现AddContactCommandInterface
的东西,那么请更改派生类 BaseClass
规定,任何子类必须具有名为invoke的公共方法,该方法接受实现AddContactCommandInterface
的任何对象
UpClass
不满足此要求。
其invoke函数只接受AddContactCommand
或子对象的具体实例
如果您的代码被允许,以下操作将失败:
class SomeOther implements AddContactCommandInterface
{
//implementation of interface
}
$up = new UpClass();
$up->invoke(new SomeOther());
为什么不让
UpClass->invoke
接受inteface的实现呢?您仍然可以传递一个具体的AddContactCommand
感谢大家的快速响应!问题是我想先写一个抽象包,然后有无限数量的child包。(在我的工作中,a做了一些类似于HumanBundle、man and Women Bundle的事情)。业务逻辑必须集中在抽象包中。因此,invokes方法的提示类型不应该与我们的示例中的man或womanbundle相同,但它们都有著名的CommandInterface,我唯一的解决方案是不将invoke方法(或其他“precisions”方法)引用到我的abtractbundle中。太糟糕了!您可能需要重新考虑您的设计,因为您的AbstractBundle
有点像上帝的职业,可能会限制将来设计中的一些灵活性。它的名称“AbstractBundle”这一事实对我来说是一种代码味道,因为它没有给我关于这个类的职责是什么的线索。