【问题标题】:Expanded implementation of php interfacesphp接口的扩展实现
【发布时间】:2016-05-12 07:16:27
【问题描述】:

Object Interfaces 上的 PHP 手册说:

实现接口的类必须使用与接口中定义的完全相同的方法签名。不这样做会导致致命错误。

不考虑以下情况:我有一个接口

interface Foo
{
    public function foo(SpecialClass $object);
}

它只包含一个方法foo,它以SpecialClass 作为参数,以及一个具体的类

class Bar
{
    public function foo(BaseClass $object)
    {
        // do something with $object
    }
}

除了foo 采用BaseClass 之外,它与Foo 具有相同的签名,其中SpecialClass implements BaseClass。

从理论上来说,每当我的代码需要满足Foo 接口的需求时,我都可以使用Bar 的实例,并且一切都应该正常工作(因为SpecialClass 是BaseClass)。换句话说,Bar 满足Foo 声明的契约,因为它有一个方法foo 可以处理任何SpecialClass 对象。

为了明确这一点,并能够在我的代码中实际使用它,我希望能够编写 Bar implements Foo,但如文档中所述,这会引发致命错误。

这个致命错误的原因是什么?只是因为目前是这样做的,还是有特定的理由这样做?

【问题讨论】:

    标签: php oop interface


    【解决方案1】:

    DateTime 不是 StdClass,它们实际上是两个不同的类。

    这不是Java,每个人都从Object扩展

    【讨论】:

    • 感谢您指出这一点。我用两个泛型类从另一个继承一个来纠正这个问题
    【解决方案2】:

    正如@dynamic DataTime 所述,不是stdClass。看看下面的例子。

    class A {
        public function foo();
    }
    
    class B extends A {
        public function foo();
        public function bar();
    }
    
    interface C {
       public function baz(B $obj)
    }
    
    class D implements C {
        public function baz(A $obj);
    }
    

    您可以看到C 接口的函数baz 接受参数B。然而,该实现采用参数A。问题是B 有更多的扩展接口,而A 不能满足它。换句话说,C 接口需要访问foo() 和bar()。但是A 只有foo()。如果情况相反,那么事情会起作用 - B 满足 A 的界面。

    所以这不是暂时的行为,是正确的。

    【讨论】:

    • 感谢您的支持,但实际上@dynamic 是对的。 DateTime 不是 stdClass 您可以检查:var_dump(new \DateTime instanceof \stdClass); 将导致 false
    • 我更正了这个示例,其中两个泛型类相互扩展。此外,我不确定我是否遵循您的回答:您能否改进它,提供一个示例,说明我想做的事情如何不起作用?
    • 我不同意,我认为你说C interface is requiring access the foo() and bar() 是错误的,因为C 只是一个接口。 $obj 的作用只是实现的责任,而不是接口本身的责任。从我的观点来看,C 只是说它的任何实现都将能够管理传递给其baz 方法的B 对象。而D 实际上能够管理传递给其baz 方法的任何B 对象
    • 我是在形象地说我所说的“需要访问”。您的观点可能也是正确的,但是\当您注入一个对象时,您是想管理它还是使用它的功能来完成某些工作?你能举个例子吗,一般的会更好,你在哪里传递对象来管理它?
    • 只是在一个具体案例中勾勒出一些我想要的东西可能有用的东西......3v4l.org/naSJm随时编辑它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多