【问题标题】:When to use extends/abstract and implements/interface in PHP何时在 PHP 中使用扩展/抽象和实现/接口
【发布时间】:2012-03-05 16:36:13
【问题描述】:

所以,我开始对 PHP 中的 abstractinterface 的概念感到震惊。
但它什么时候真正有用?

当然,我可以使用 界面 为我的课程制定规则,因此它们都遵循特定的模式。 但是什么时候它真的有用呢?

我为什么要创建一个抽象类,而不是只创建一个自己工作但对其他类有用的类。
抽象我也许可以转过头来看看很好的用途,例如创建一个通用类。就像制作一个抽象的数据库类,然后将其扩展到 Mysql 和 MsAccess 数据库类。提供两种相似的功能来使用,从而在两种情况下实现无缝体验。

但是说真的,谁能给我一个更好的例子说明 abstractinterface 什么时候真正有用?
而且请注意,我确实知道它是如何工作的,或者如何编写代码,只是不知道如何或何时使用它。

谢谢!

【问题讨论】:

  • 哦,伙计们。这不是重复的可能性有多大?为什么要回答?
  • 感谢@hakre,非常抱歉,我没有找到提到的那些类似问题。也许是因为我不认为这是两者之间的战斗,一场对抗,而是两件事分开,在两个不同的领域。我仍然认为我的问题是一个有效的问题,因为它是在另一种心态中设定的,如果你愿意,可以框架。但我确实很欣赏问题主题的链接以供进一步阅读。
  • @jamietelin 您的问题本身是有效的,但之前已经回答过,这使得它按照 SO 的定义重复。这里没有什么特别新的东西,所以应该关闭。在旁注中,即使在搜索中不使用“vs”,您也会发现更多可能的重复项:stackoverflow.com/search?q=abstract+interface

标签: php oop interface abstract-class


【解决方案1】:

Abstract 的意思是“这是你的课程的一个模式,以及一些可以让你开始的代码”。抽象类的设计者可以将一些方法标记为需要由扩展类提供(abstract),或者标记为final,表示类不能覆盖它们。

接口的意思是“这是你的类的一个模式,但你必须自己编写所有代码”。接口中声明的任何方法和属性都必须由实现该接口的类提供。

所以基本上一个经验法则是:

如果您的代码可以或必须由后代类使用,则需要一个抽象类。如果您只有方法和属性声明,则可以使用接口。

别忘了,使用抽象类在一定程度上限制了你,因为后代类只能扩展一个类,而它可以实现任意数量的接口。

【讨论】:

    【解决方案2】:

    接口不是类,抽象类已经是类。

    由于每个类都有一个接口(根据定义),interface 允许您为任何类指定一个接口next,无论它是否抽象。

    针对接口进行编程然后允许您用另一个类替换一个类同时保持相同的接口。因此,它使您的代码耦合度降低。它不再针对具体类进行编程,而是“仅”针对更轻量级的接口进行编程。如果您不想针对具体的类名而是针对类型进行编程,那么接口将很有用。然后,您可以将一个对象替换为实现相同接口的任何其他对象。

    另一方面,抽象类——甚至称为抽象类——是相当具体的。然而,它不是最终的,所以它形成了一个类的模式,就像一个规范应该如何为某个功能编写一个从它扩展的类。因为它是抽象的,所以如果不从它延伸出来,它就无法生存。抽象类用于创建基类,其代码将多次使用,以减少代码重复且无法直接实例化。

    【讨论】:

    • 那么,接口只是防止程序员忘记模式的一种方式吗?可以这么说,它是对如何编码的提醒,或者是对未来编码员的说明,这些编码员显然与第一个编码员不共享相同的内存(如果我们将来没有发明更好的人类记忆共享,也就是谈话,方法)^ ^
    • 至少你可以这样使用接口:) 我不会称之为“忘记”,只是为了定义它,指定接口。当然,这对团队合作有好处,但也有利于随着时间的推移对具体类进行更改,因为它不是针对某个类进行编码,而只是针对接口进行编码。类可以更改或交换(测试、应用程序增长)。一些编码人员在编写类之前总是有一个接口,但据我所知,这有时是多余的,因为不是必需的。只是说。
    【解决方案3】:

    接口的工作方式类似于合同。如果一个类实现了一个接口,那么使用这个类的其他代码现在知道它支持某些特性。

    PHP 中最好的接口示例是 Iterator 接口。

    接口的好处是类可以实现多个。 “扩展”不允许这样做。这意味着子类可以实现一个接口,但它的父类不需要。

    阅读设计模式。您会发现其中很多内容都涵盖了,并且您再也不会怀疑在哪些情况下它是有意义的。 'Head first design patterns' 我认为是一本好书,写得很好。尽管他们在示例中使用了 Java,但大多数东西都非常适用于 PHP。

    我还有一个真实的场景。

    每当发生错误时,我们的应用程序总是到处抛出异常。每种类型的异常都有其自定义类。 RecordNotFound 异常就是一个例子。

    如果没有捕获到异常,则有一个顶级异常块,看起来有点像这样:

    try {
    
     // Do everything in the app!
    
    } catch (Exception $e) {
    
      // draw a good error page
    
    }
    

    在某些情况下,需要将异常映射到某些 HTTP 状态代码,例如 404(未找到)。因此我们有这个接口:

    interface HTTPException {
    
      function getHTTPCode();
    
    }
    

    任何异常,无论继承树有多深,现在都可以实现此接口并发出特定的 HTTP 状态代码。

    我什至创建了接口,没有任何方法。我将留给您尝试思考为什么这可能有意义的原因。

    【讨论】:

    • 标记界面模式?!那么,有什么方法可以对相似的类进行分组?
    【解决方案4】:

    接口只是一个类的骨架结构,它不是类。我们可以只实现该类并添加一些额外的功能以使其更清晰。 implements 关键字可用于 interface 。通常在 interface 中使用 implement 来实现功能。

    abstract 是一个隐藏一些特征而只显示必要特征的类。 Extend 关键字可用于abstract 类。一般来说,extends 可以用来扩展抽象类的特性。

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 2012-12-19
      • 2012-10-08
      • 2010-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多