请解释一下什么时候我应该使用PHP接口,什么时候我应该使用抽象类?

我如何能改变我的抽象类在一个接口?


当前回答

当您希望强制在您的系统中工作的开发人员(包括您自己)在他们将要构建的类上实现一组方法时,请使用接口。

当你想强迫在你的系统中工作的开发人员(包括你自己)实现一组方法,并且你想提供一些基本方法来帮助他们开发他们的子类时,使用抽象类。

另一件需要记住的事情是客户端类只能扩展一个抽象类,而它们可以实现多个接口。因此,如果您在抽象类中定义行为契约,这意味着每个子类可能只符合一个契约。有时这是一件好事,当你想强迫你的用户程序员沿着特定的路径。其他时候就不好了。想象一下,如果PHP的Countable和Iterator接口是抽象类而不是接口。

当您不确定该走哪条路时(如下面的cletus所述),一种常见的方法是创建一个接口,然后让抽象类实现该接口。

其他回答

Also, just would like to add here that just because any other OO language has some kind of interfaces and abstraction too doesn't mean they have the same meaning and purpose as in PHP. The use of abstraction/interfaces is slightly different while interfaces in PHP actually don't have a real function. They merely are used for semantic and scheme-related reasons. The point is to have a project as much flexible as possible, expandable and safe for future extensions regardless whether the developer later on has a totally different plan of use or not.

如果你的英语不是母语,你可以查一下抽象和接口到底是什么。还要注意同义词。

这也许可以作为一个比喻:

接口

比方说,你用草莓烤了一种新的蛋糕,你还写了一份食谱,描述了配料和步骤。 只有你自己知道为什么它的味道这么好,你的客人喜欢它。 然后你决定公布你的食谱,这样其他人也可以尝试这个蛋糕。

这里的重点是

-为了弥补错误 -小心 防止事情变坏(比如草莓吃多了之类的) -让尝试的人容易上手 -告诉你要做多长时间(比如搅拌) ——告诉你哪些事情你可以做,但不必做

这就是接口的描述。它是一份指南,一套遵守食谱内容的说明。 就像你要用PHP创建一个项目,你想把代码提供给GitHub或你的伙伴或其他什么。 界面是指人们可以做什么,你不应该做什么。如果你不遵守其中一条,整个结构就会被打破。

抽象

继续这个比喻……想象一下,这次你是吃蛋糕的客人。那你现在就用这个食谱做蛋糕。 但你想添加新的食材或更改/跳过食谱中描述的步骤。那么接下来会发生什么?计划一个不同版本的蛋糕。 这次用的是黑莓,不是草莓,更多的香草奶油…

这是你可以考虑的原始蛋糕的扩展。你基本上是通过创建一个新食谱来对它进行抽象,因为它有点不同。它有一些新的步骤和其他成分。然而,黑莓蛋糕的一些部分是你从原来的蛋糕中继承来的——这些是每种蛋糕都必须具备的基本步骤。就像牛奶一样的成分-这是每个派生类都有的。

现在你想要交换原料和步骤,这些必须在新版本的蛋糕中定义。这些都是抽象方法,必须为新蛋糕定义,因为蛋糕中应该有水果,但是是哪个呢?所以这次你选黑莓。完成了。

好了,你已经扩展了蛋糕,遵循了界面,并从中提取了步骤和成分。

最佳实践是使用接口来指定契约,并将抽象类作为契约的一个实现。该抽象类可以填充大量样板文件,因此您可以通过重写需要或想要的内容来创建实现,而不必强制使用特定的实现。

抽象类和接口之间的技术差异已经在其他答案中列出了。为了面向对象编程,我想在编写代码时对类和接口之间的选择添加一个解释。

类应该代表实体,而接口应该代表行为。

让我们举个例子。计算机显示器是一个实体,应该表示为一个类。

class Monitor{
    private int monitorNo;
}

它的设计目的是为您提供一个显示界面,因此功能应该由接口定义。

interface Display{
    void display();
}

正如其他答案中解释的那样,还有许多其他的事情需要考虑,但这是大多数人在编码时忽略的最基本的事情。

主要的区别是抽象类可以包含默认实现,而接口不能。

接口是没有任何实现的行为契约。

当您希望强制在您的系统中工作的开发人员(包括您自己)在他们将要构建的类上实现一组方法时,请使用接口。

当你想强迫在你的系统中工作的开发人员(包括你自己)实现一组方法,并且你想提供一些基本方法来帮助他们开发他们的子类时,使用抽象类。

另一件需要记住的事情是客户端类只能扩展一个抽象类,而它们可以实现多个接口。因此,如果您在抽象类中定义行为契约,这意味着每个子类可能只符合一个契约。有时这是一件好事,当你想强迫你的用户程序员沿着特定的路径。其他时候就不好了。想象一下,如果PHP的Countable和Iterator接口是抽象类而不是接口。

当您不确定该走哪条路时(如下面的cletus所述),一种常见的方法是创建一个接口,然后让抽象类实现该接口。