接口和抽象类继承,扩展类中的实现

时间:2011-06-16 08:36:34

标签: php inheritance interface abstract-class

在我看过的每个例子中,扩展类都实现了父类的接口。作为参考,以下示例:

interface MyInterface{
    public function foo();
    public function bar();
}

abstract class MyAbstract implements MyInterface{
    public function foo(){ /* stuff */ }
    public function bar(){ /* stuff */ }
}

// what i usually see
class MyClass extends MyAbstract implements MyInterface{}

// what i'm curious about
class MyOtherClass extends MyAbstract{}

是否未能在子级中实现接口,这是由父级实现的,被视为不良做法或其他什么?省略孩子的实施是否有任何技术缺陷?

5 个答案:

答案 0 :(得分:20)

我会认为你走的是正确的道路。在扩展已经implements的类时,无需声明您正在实现接口。对我而言,如果需要进行更改,这只是另一段代码。所以,是的,你是对的!

答案 1 :(得分:18)

  

无法实现接口   在一个孩子,由一个人实施   父母,被认为是不良做法或   什么?有技术吗?   省略的缺点   在孩子身上实施?

我不能比这家伙更好地回答你的问题:

  

就其本质而言,虽然有时候   它们看起来很相似,很抽象   类和类接口服务   非常不同的目的。

     

类的接口是指   该类“用户”的工具。一个   界面是一个公开的演示文稿   这个班,应该做广告   什么人考虑使用它,什么   方法和常量可用   并可从外面访问。所以,   顾名思义,它总是坐着   用户和班级之间   实施它。

     

另一方面,抽象类   是一个旨在帮助   那个类的“实现者”   延伸它。这是一个基础设施   可以施加限制和   关于什么具体的指导方针   课程应该是这样的。来自一个班级   设计视角,抽象类   在建筑上更重要   比接口。在这种情况下,   实现者坐在抽象之间   阶级和具体的,建设   后者在前者之上。

Reference

因此,由您来决定,根据谁将要使用(实例化)您的类,以及谁将要编写它们。如果您是班级的唯一用户和作者,那么,也许,只是也许,您不需要它们。但是,如果你想让每个人都被剥离到类编写者和类用户的核心位蓝图,那么你应该考虑使用抽象和实现。

答案 2 :(得分:1)

也许有点迟到但我看到上述评论并没有澄清OP问题背后的主要误解。

所以潜在的问题是:

  • 为什么我们在同一行上同时使用Abstract类和Interface?
  • 抽象方法和接口都应该声明相同的方法吗?

但在澄清之前,为什么要使用上述两种方法之一:

  • 一个程序员使用它们中的任何一个来定义其他程序员在创建具体类(最终是整个软件应用程序)时必须遵守的合同(要求,义务,限制),这些类基于由它开发的抽象类/接口。程序员。
  • 反过来,Abstract类用于为后来创建的具体类提供方法&数据结构蓝图通过:

    1. 数据结构声明(可选),
    2. 方法的基础实现(及其签名,可选)
    3. 只是方法声明(类似于接口用法,可选)。
  • 接口用于通过

    为方法蓝图提供具体类
    1. 只是方法(及其签名,可选)声明。

以下是抽象和具体类的示例。

abstract class MyAbstractClass {

    public function foo() {
        // Base implementation of the method here.
    }

    public function bar() {
        // Base implementation of the method here.
    }

    // Effectively similar to baz() declaration within some interface:
    public abstract function baz($value);

}

class MyConcreteClass extends MyAbstractClass {

    // foo() and bar() are inherited here from MyAbstractClass.

    // baz() must be implemented or declared abstract again.
    public function baz($value) {
        // implementation.
    }

}

然后问题来了:

  1. 为什么我们需要一个接口?
  2. 我们是否需要一个接口来复制相同的方法声明?
  3. 答案:

    1. 由于PHP只允许每个子类的单一继承(你不能写class MyConcreteClass extends MyAbstractClass, MyAnotherClass {}),当我们需要扩展已经使用的Abstract类之外的具体类功能时,我们必须声明这个通过一个或多个接口的附加功能。

      像这样:

      class MyConcreteClass 
          extends MyAbstractClass 
          implements MyInterface, MyAnotherInterface {
          // Methods and data implementations go here.
      }
      
    2. 作为答案1的结果,接口最好不要复制抽象类方法的声明(这基本上没用)。接口应该对可能有助于增强具体(或另一个抽象类,为什么不)的功能的方法进行十分转换,以便为程序员提供将在这些类和接口之上构建的每个对象的公司合同使用这些方法。

    3. 最后,回答OP问题是否为Abstract类或具体类使用接口是:

      • 只要接口使用新方法的声明增强了类合同,就可以使用其中一个或两个(或根据需要)。

答案 3 :(得分:0)

  

是否未能在子级中实现接口,该接口由父级实现,被认为是不良做法或什么?

孩子总是实现界面,它无法解决这个问题。

我不知道这是不好的做法还是其他什么。我会说这是一种语言功能。

  

在儿童中省略实施是否有任何技术缺陷?

例如,您无法测试抽象类的反射以获得接口。

但是,抽象类已经是一个接口,所以从技术上讲,它们本身并不需要接口,但是你可以这样做,以便在继承中保持流畅。

答案 4 :(得分:0)

好吧,我也很困惑,但我认为你应该使用后者,你是对的,如果你在抽象类中实现接口,那么就没有必要编写接口,你可以在将所有接口都抽象为抽象方法,因为你将扩展抽象类,当你在其他地方使用类时,你将不得不使用抽象类作为参数类型,这不是一件好事,我认为抽象类不应该用作参数类型,而接口应该是。