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


Interfaces and abstract class inheritance, implementation in extended classes

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

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{}

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

我认为你走的是正确的道路。当扩展一个已经implements的类时,没有必要声明你正在实现接口。对我来说,如果需要更改,这只是另一段需要维护的代码。所以,是的,你是对的!

是否未能实现接口在子对象中,由家长,被认为是不良行为或某物有什么技术问题吗省略的缺点在孩子身上实施?

我无法比这家伙更好地回答你的问题:

从本质上讲,尽管有时它们看起来可能非常相似、抽象类和类接口服务非常明显的目的。

类的接口是指该类的"用户"的工具。一界面是该类,它应该做广告任何考虑使用它的人,什么方法和常量可用并且可从外部进入。所以顾名思义,它总是坐着在用户和类之间

另一方面,抽象类是一种旨在帮助类的"实现者"扩展它。它是一个基础设施可以施加限制关于具体内容的指导方针类应该看起来像。来自课堂设计视角,抽象类在架构上更重要而不是接口。在这种情况下实现者坐在抽象之间阶级与混凝土阶级、建筑后者在前者之上。

参考

因此,根据谁将使用(实例化)您的类以及谁将编写这些类,由您来决定。如果你是类的唯一用户和编写者,那么,也许,只是也许,你不需要它们两者。但是,如果您想为类编写器和类用户为每个人提供一个精简到核心的蓝图,那么您应该考虑使用抽象和实现。

可能有点晚了,但我看到上面的评论并没有澄清OP问题背后的主要误解。

因此,潜在的问题是:

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

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

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

    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. 我们需要一个接口来复制相同的方法声明吗

答案:

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

    像这样:

    class MyConcreteClass 
        extends MyAbstractClass 
        implements MyInterface, MyAnotherInterface {
        // Methods and data implementations go here.
    }
    
  2. 答案1的结果是,接口最好不要重复抽象类方法的声明(这基本上是无用的)。接口应该标记可能有助于增强具体(或另一个抽象类,为什么不呢)功能的方法,为将使用这些方法的程序员提供在这些类和接口之上构建的每个对象的固定合同。

最后,对于OP问题,是将接口用于抽象类还是用于具体类的答案是:

  • 只要Interface通过新方法的声明增强了类约定,就可以用于其中一个或两个(或根据需要)

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

孩子总是实现接口,这是不可能的。

我不知道这是不是不好的做法。我认为这是一种语言特征。

省略在孩子身上的实现是否有任何技术缺陷?

例如,不能测试抽象类的反射是否具有接口。

然而,抽象类已经是一个接口,所以从技术上讲,它们本身并不真正需要接口,但您可以这样做,以保持继承中的流动性。

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