将接口传递给另一个接口方法

问题描述 投票:0回答:1

我需要在OOP中实现事件监听器模型。现在我有EventInterfaceListenerInterface。但我想将事件传递给侦听器,如:

interface ListenerInterface {
  public function listen(EventInterface $event);
}

但是即使我传递给侦听器的Event实现了EventInterface,我也无法做到这一点。那我该怎么办?我想将其抽象化以便于简单使用。

PhpStorm的屏幕截图:enter image description here

php oop covariance contravariance php-7.4
1个回答
0
投票

您的SendUserNotificationListener 遵守ListenerInterface订立的合同。

该错误会告诉您这一点。如果尝试运行此代码,则会出现致命错误,并且脚本将崩溃。

如果您有几个这样的接口:

interface ParentInterface {
    public function foo();
}

interface ChildInterface extends ParentInterface {
    public function bar();
}

interface AnotherChildInterface extends ParentInterface {
    public function baz();
}

interface OriginalHandlerInterface
{
    public function handle(ParentInterface $a): string;
}

实现OriginalHandlerInterfce的任何类都必须遵循它完全

例如

class OriginalImplementor implements OriginalHandlerInterface
{
    public function handle(ParentInterface $a) : string
    {
        return class_name($a);
    }
}

如果您尝试使实现在parameter上使用covariance,则它将失败,因为实现不会遵循该界面。例如:

class WrongOriginalImplementor implements OriginalHandlerInterface
{
    public function handle(ChildInterface $a) : string
    {
        return class_name($a);
    }
}

此逻辑简单而合理。如果有人使用您声明的实现OriginalHandlerInterface的类,则该用户根本不需要查看您的实现,只需查看接口即可。

如果原始接口声明handle()需要一个ParentInterface对象,则意味着我可以从实现ParentInterface的类中传递对象,但是来自实现ChildInterfaceAnotherChildInterface的类中的对象也将是有效的。

[另一方面,如果您的实现能够说出handle(ChildInterface $a),那么用户就会背弃他们的期望,因为尽管他们无法从实现handle()的类中传递AnotherChildInterface对象,根据OriginalHandlerInterface有效。

另一方面,如果您具有此界面:

interface AnotherHandlerInterface
{ 
    public function handle(ChildInterface $a): string;
}

您的实现可以在handle()参数上使用contravariance。他们可以指定较少限制参数类型。例如:

class ContravariantImplementor implements AnotherHandlerInterface
{
    public function handle(ParentInterface $a): string {
        return class_name($a);
    }
}

此实现,尽管未跟在圆点后面,有效。同样,如果您考虑采用相同的逻辑:类的使用者可以查看AnotherHandlerInterface并看到handle()期望ChildInterface。因此,如果遵循原始合同,您的实施将永远不会绊倒他们。

您的实现没有那么严格的限制,并且可以接受原始接口不会接受的对象,但这很好,因为协变和逆变的规则允许它。

请注意,协方差和对数支持在PHP and has been added only in PHP 7.4中是相当新的。

您可以看到上面的代码在工作here(包括错误)

© www.soinside.com 2019 - 2024. All rights reserved.