关于php:接口只是“语法糖”吗?

Are Interfaces just “Syntactic Sugar”?

我主要玩PHP和Python。

我一直在阅读OO编程中的接口,但看不到使用它的优势。

多个对象可以实现同一个接口,但是多个继承也不能提供这个接口?

为什么我需要创建一个"不带实现"的接口——主要是一个"契约"——如果我可以检查一个方法是否存在于从多个类继承的Python对象中?

接口是否是用其他语言创建的,因为它们不提供多个继承?还是我错过了更重要的东西?


首先,最重要的是,不要在Python和Java之间进行比较和对比。它们是不同的语言,具有不同的语义。比较和对比只会导致令人困惑的问题,例如,你试图比较Python与Java所需的一些东西。

这很像比较数字7和绿色。它们都是名词。除此之外,你将很难比较两者。

这是底线。

python不需要接口。

Java需要它们。

Multiple objects can implement the same interface, but multiple inheritance doesn't provide this as well?

这两个概念几乎没有任何关系。

我可以定义大量共享公共接口的类。在python中,由于"duck-typing",我不必仔细确保它们都有一个通用的超类。

接口是对不相交的类层次结构的"意向"声明。它提供了一个通用规范(编译器可以检查它),它不是简单类层次结构的一部分。它允许多个类层次结构实现一些公共特性,并对这些特性具有多态性。

在python中,您可以在不带接口的情况下使用多个继承。多重继承可以包括接口类,也可以不包括接口类。

Java甚至没有多重继承。相反,它使用了一种完全不同的称为"混合"的技术。

Why do I need to create an Interface"with no implementation" - mainly a"contract" - if I can just check if a method exists in an object in Python, that inherits from multiple classes?

如果您在Python中创建一个接口,它可以是一种正式的契约。声明所有子类都将绝对执行接口声明的操作。

当然,一个麻木的人完全可以自由地说谎。它们可以从接口继承并错误地实现所有内容。没有什么能阻止反社会者的不良行为。

您在Java中创建一个接口,允许多个对象类具有共同的行为。由于在python中你不太了解编译器,所以这个概念甚至不适用。

Do Interfaces were created in another languages because they don't provide multiple inheritance?

因为这些概念没有关联,所以很难回答这个问题。

在爪哇,他们使用的是"混血",而不是多重继承。"接口"允许一些额外功能的混合。这是接口的一个用途。

另一种使用接口将"is"与"do"分开。类层次结构定义对象是什么。接口层次结构定义类的作用。

在大多数情况下,is和do是同构的,所以没有区别。

在某些情况下,对象是什么和对象做什么是不同的。


接口的有用性直接与静态类型的有用性联系在一起。如果您使用的是像php或python这样的动态类型语言,那么接口确实不会显著增加语言的表达能力。也就是说,任何可以被描述为使用接口的程序都可以在不使用接口的情况下表达,而没有显著的差异。

因此,python有一个相当模糊的"协议"概念(一个符合某种模式的实现,如迭代协议),其本质上是相同的,但是没有编译时检查其值的其他好处是有限的。

另一方面,在静态类型语言中,接口对于实现与实现分离是必不可少的。在静态语言中,所有表达式的类型必须在编译时解析,因此通常必须在编译时绑定到实现,从而限制了运行时的灵活性。接口定义了如何在不定义特定实现的情况下访问功能,这允许静态语言在不访问实现的情况下证明表达式是正确的。

没有接口(或等价的公式,如C++的纯虚函数),静态类型语言的表达将受到严重阻碍。事实上,存在许多实现(Win32和COM立即出现),通过在结构中存储函数指针(从而重新实现C++的虚拟函数和手动的VTE调用),基本上再现了C中的接口和虚拟调度的大部分功能。在这种情况下,表达能力有很大的不同,因为在程序中表达相同的概念需要进行许多更改。

接口只是多态类型的一个例子,在这方面是相当有限的。在支持参数多态性(也称为泛型)的语言中,您可以完成更多工作。(例如,如果没有通用接口,C的LINQ就不可能实现。)对于同一类型的更强大的形式,请查看haskell的typeclass。


即使在类似于python的duck类型语言中,界面也可以更清晰地表达您的意图。如果您有许多实现,并且它们共享一组方法,那么接口是记录这些方法的外部行为、为概念命名并使概念具体化的好方法。

没有显式接口,系统中就有一个重要的概念,没有物理表示。这并不意味着您必须使用接口,但接口提供了具体性。


在动态类型语言(如PHP和Python)中,接口的使用是有限的。您可以随时尝试调用任何对象上的方法,如果不存在运行时错误,您将得到一个运行时错误。

在静态类型语言(如Java和.NET)中,接口变得重要,因为在编译时检查方法及其参数。

现在,对于接口:

除了数组外,Java还有EDCOX1×0的S。一般来说,数组是用于原语的(主要是数字类型),而Lists是用于对象的。

我可以有一个List,它是一个字符串列表。我知道我可以用add串接它,用get串接它。

我不知道它是哪个实现。它可以是一个ArrayList(数组支持的列表)、一个LinkedList(双重链接列表支持的列表)、一个CopyOnWriteArrayList(ArrayList的线程安全版本)等。

多亏了多态性和接口,我不需要知道在它上面执行List操作的是哪种类型的List


因为您希望针对接口而不是具体的实现进行编程(Gof 1995:18)


请阅读有关python中zope接口的强大功能的Twisted框架文章。


对。至于PHP,接口只是一种克服缺乏多重继承的方法。有一些对IDES有用的小语义差异,并且由接口引起的冲突更少,这显然有助于新手程序员。但正如前面所说,在动态语言中,这并不是严格必要的。http://c2.com/cgi/wiki?多重遗传


因为有时候你不想提供一个实现。

Java接口

Java类


它通常用于替换多个继承(C)。我认为一些语言/程序员也使用它们作为强制对象结构需求的一种方式。