【问题标题】:Should 'type' be allowed to inherit by both interfaces and classes?接口和类都应该允许“类型”继承吗?
【发布时间】:2014-12-30 19:30:09
【问题描述】:

使用 PHP 5.5,如果我指定接口的层次结构和类的并行层次结构,我最终会得到通过多个关系继承某种类型的子类。这是否表明设计不佳?它会产生问题吗?

例如看代码:

interface foo {}
interface bar extends foo {}

class myFoo implements foo {}
class myBar extends myFoo implements bar {}

在本例中,myBar 通过两个关系继承类型 'foo':

  • 它从它的具体父级 (myFoo) 继承“foo”
  • 它从它实现的接口(bar)继承“foo”

我在接口和类之间建立一对一关系的原因是,我可以用代理和模拟替换细粒度的具体类。 (我所有的方法参数都用接口表示)。

我可以停止在我的接口中使用继承,但这似乎违背了多态性。此外,当我使用我的接口来定义方法签名(即不仅仅是建立一个通用类型)时,它也会产生问题。

【问题讨论】:

  • 既然接口没有任何代码,为什么要扩展呢?无论如何,您不能重载接口中的函数。将 foo 和 bar 解耦,你应该没问题。
  • @JvO 因为想要表达“我希望这个接口定义所有与其他接口相同的方法,但也有一堆额外的方法。”

标签: php oop inheritance interface


【解决方案1】:

无论哪种方式都无关紧要。从接口的“消费者”的角度来思考,而不是从接口本身的抽象概念来考虑:

function (bar $bar) {
    ...
}

这是橡胶与接口的交汇点。所有这个函数感兴趣的是一个对象,它的方法符合bar 接口中定义的方法。它不关心这个对象究竟是如何实现这些方法的,只关心它具有interface bar 定义的所有方法。继承哪些方法也无关紧要,无论是在接口中还是在对象中。实例化对象的总和才是最重要的。

话虽如此,您可能还想多考虑一下您的界面和类设计。您所做的本身并没有错,但可能有更好的方法来处理接口。不要将接口视为类的草图,将接口视为能力的定义。为此,再次考虑这种界面的消费者。例如:

function renderThumbnail(Imaginable $item) {
    printf('<img src="%s">', $item->getHighestResolutionImage()->getUrl());
}


interface Imaginable {

    /**
     * @return Image[]
     */
    public function getImages();

    /**
     * @return Image
     */
    public function getHighestResolutionImage();

}

这展示了一个对象可能具有的一种特定的能力任何对象都可能有相关的图像。任何实现Imaginable 接口的类都简单地声明它可以根据请求提供图像。 renderThumbnail 函数只需要任何具有图像的对象。传入什么对象并不重要,该对象也可以实现一千个其他接口并且属于任何类型的类,重要的是它可以完成这一特定的事情。

如果您从“-able”功能接口的角度考虑它,很明显您可能不会最终得到两个并行运行的层次结构,这可能是更好的设计。

【讨论】:

  • 谢谢 deceze,很好的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2013-02-19
  • 2013-02-25
  • 1970-01-01
相关资源
最近更新 更多