Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用具体类型类实现具有接口类型提示的抽象方法_Php - Fatal编程技术网

Php 使用具体类型类实现具有接口类型提示的抽象方法

Php 使用具体类型类实现具有接口类型提示的抽象方法,php,Php,这里有一个我无法解释的简单问题 在PHP手册中: 若类或接口被指定为类型提示,那个么它的所有子类或实现也是允许的 我记得这是一个抽象方法的例子,但在我看来,它似乎“没有逻辑” 以下是一个例子: 我通过以下方式搜索如何实现方法(在本例中为invoke): <?php namespace Foo\Bundle\BarBundle; abstract class BaseClass { //... abstract public function invoke(AddCon

这里有一个我无法解释的简单问题

在PHP手册中:

若类或接口被指定为类型提示,那个么它的所有子类或实现也是允许的

我记得这是一个抽象方法的例子,但在我看来,它似乎“没有逻辑”

以下是一个例子:

我通过以下方式搜索如何实现方法(在本例中为invoke):

<?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”这一事实对我来说是一种代码味道,因为它没有给我关于这个类的职责是什么的线索。