接口允许您创建定义实现接口的类的方法的代码。但是,您不能向这些方法添加任何代码。

抽象类允许您做同样的事情,同时向方法添加代码。

现在,如果可以用抽象类实现同样的目标,我们为什么还需要接口的概念呢?

有人告诉我,这与从c++到Java的面向对象理论有关,这也是PHP面向对象的基础。这个概念在Java中有用而在PHP中没有吗?这仅仅是一种避免在抽象类中布满占位符的方法吗?我遗漏了什么吗?


当前回答

我不了解其他语言,界面的概念是什么。但对于PHP,我将尽力解释。耐心点,如果有帮助请评论。

接口就像“契约”一样工作,指定一组子类做什么,但不指定它们如何做。

规则

An Interface can't be instantiate. You can't implement any method in an interface,i.e. it only contains .signature of the method but not details(body). Interfaces can contain methods and/or constants, but no attributes. Interface constants have the same restrictions as class constants. Interface methods are implicitly abstract. Interfaces must not declare constructors or destructors, since these are implementation details on the class level. All the methods in an interface must have public visibility.

现在让我们举个例子。 假设我们有两个玩具:一个是狗,另一个是猫。

正如我们所知,狗叫,猫叫。这两者具有相同的说话方法,但具有不同的功能或实现。 假设我们给用户一个带有说话按钮的遥控器。

当用户按下说话按钮时,玩具必须说话,无论它是狗还是猫。

这是使用接口而不是抽象类的好情况,因为实现是不同的。 为什么?还记得

如果您需要通过添加一些非抽象方法来支持子类,则应该使用抽象类。否则,接口将是您的选择。

其他回答

在我看来,接口应该优于非函数抽象类。如果性能受到影响,我也不会感到惊讶,因为只实例化了一个对象,而不是解析两个对象,并将它们组合在一起(尽管,我不能确定,我不熟悉OOP PHP的内部工作原理)。

的确,与Java相比,接口没有那么有用/有意义。另一方面,PHP6将引入更多的类型提示,包括返回值的类型提示。这将为PHP接口增加一些价值。

interfaces定义了需要遵循的方法列表(想想API),而抽象类提供了一些基本/通用的功能,这些功能由子类细化以满足特定需求。

这个概念在面向对象编程中非常有用。对我来说,我认为接口是一种契约。只要我的类和你的类同意这个方法签名合同,我们就可以“接口”。至于抽象类,我认为更多的是存根一些方法的基类,我需要填充细节。

我不了解其他语言,界面的概念是什么。但对于PHP,我将尽力解释。耐心点,如果有帮助请评论。

接口就像“契约”一样工作,指定一组子类做什么,但不指定它们如何做。

规则

An Interface can't be instantiate. You can't implement any method in an interface,i.e. it only contains .signature of the method but not details(body). Interfaces can contain methods and/or constants, but no attributes. Interface constants have the same restrictions as class constants. Interface methods are implicitly abstract. Interfaces must not declare constructors or destructors, since these are implementation details on the class level. All the methods in an interface must have public visibility.

现在让我们举个例子。 假设我们有两个玩具:一个是狗,另一个是猫。

正如我们所知,狗叫,猫叫。这两者具有相同的说话方法,但具有不同的功能或实现。 假设我们给用户一个带有说话按钮的遥控器。

当用户按下说话按钮时,玩具必须说话,无论它是狗还是猫。

这是使用接口而不是抽象类的好情况,因为实现是不同的。 为什么?还记得

如果您需要通过添加一些非抽象方法来支持子类,则应该使用抽象类。否则,接口将是您的选择。

我不记得PHP在这方面是否有所不同,但在Java中,您可以实现多个接口,但不能继承多个抽象类。我认为PHP也是这样工作的。

在PHP中,您可以通过用逗号分隔多个接口来应用它们(我认为,我不认为这是一个干净的解决方案)。

至于多个抽象类,你可以有多个相互扩展的抽象(同样,我不完全确定,但我想我以前在某个地方见过)。唯一不能扩展的是final类。

对我来说,使用接口和抽象类之间的区别更多地与代码组织有关,而不是由语言本身强制执行。在为其他开发人员准备代码时,我经常使用它们,以便它们保持在预期的设计模式内。接口是一种“契约式设计”,您的代码同意响应一组规定的API调用,这些API调用可能来自您没有访问权限的代码。

虽然从抽象类继承是一个“是一个”关系,但这并不总是你想要的,实现接口更像是一个“像一个”关系。在某些情况下,这种差异可能相当显著。

例如,假设您有一个抽象类Account,许多其他类都是从这个抽象类扩展而来的(Account的类型等等)。它有一组特定的方法,只适用于该类型组。但是,这些帐户子类中的一些实现了Versionable、Listable或Editable,以便它们可以被扔到期望使用这些api的控制器中。控制器并不关心对象的类型

相比之下,我还可以创建一个不从Account扩展的对象,比如User抽象类,仍然实现Listable和Editable,但不实现Versionable,这在这里没有意义。

通过这种方式,我说FooUser子类不是一个帐户,但确实像一个可编辑对象。同样,BarAccount从Account扩展而来,但不是User子类,而是实现了可编辑、可列表和可版本。

将所有这些可编辑的、可列表的和可版本的api添加到抽象类本身不仅是混乱和丑陋的,而且会重复Account和User中的公共接口,或者强制我的User对象实现Versionable,可能只是抛出一个异常。