在像Java这样的静态语言中,你需要接口,否则类型系统就不会让你做某些事情.但是在PHP和Python这样的动态语言中,你只需要利用duck-typing.
PHP支持接口.Ruby和Python没有它们.所以你可以在没有他们的情况下幸福地生活.
我一直在用PHP工作,并且从未真正使用定义接口的能力.当我需要一组类来实现某些通用接口时,我只是在文档中描述它.
所以你怎么看?如果不使用动态语言中的接口,你最好不是最好的吗?
我认为它更像是一种便利.如果你有一个带有"类文件"对象并且只调用read()方法的函数,那么强迫用户实现某种File接口是不方便的 - 甚至是限制.检查对象是否具有读取方法同样容易.
但是,如果您的函数需要大量方法,则更容易检查对象是否支持接口,然后检查每个方法的支持.
是的,有一点
如果你没有显式地使用接口,你的代码仍然使用该对象,就好像它实现了某些方法一样,它只是不清楚未说出的接口是什么.
如果你定义一个函数来接受一个接口(在PHP中说),那么它将会提前失败,问题将出在调用者身上而不是使用该方法完成工作.一般来说,早先失败是一个很好的经验法则.
接口实际上为具有它们的静态语言添加了一定程度的动态类似灵活性,如Java.它们提供了一种查询对象的方法,该对象在运行时实现了哪些契约.
这个概念很好地融入了动态语言.当然,根据你对"动态"这个词的定义,它甚至包括Objective-C,它在Cocoa中广泛使用了Protocols.
在Ruby中,您可以询问对象是否响应给定的方法名称.但这是一个非常微弱的保证,它会做你想要的,特别是考虑到一遍又一遍地使用了很少的单词,没有考虑完整的方法签名等.
在Ruby中我可能会问
object.respond_to? :sync
所以,是的,它有一个名为"sync"的方法,无论那意味着什么.
在Objective-C中,我可能会问类似的东西,即"看起来/走路/嘎嘎像是同步的东西吗?":
[myObject respondsToSelector:@selector(sync)]
更好的是,以一些冗长的代价,我可以问一些更具体的东西,即"看起来/走路/嘎嘎就像是与MobileMe同步的东西?":
[myObject respondsToSelector:@selector(sync:withMobileMeAccount:)]
这是鸭子打字到物种水平.
但要真正问一个对象是否有希望实现与MobileMe的同步...
[receiver conformsToProtocol:@protocol(MobileMeSynchronization)]
当然,您可以通过检查是否存在一系列选择器来实现协议,这些选择器您认为是协议/ duck的定义,以及它们是否足够具体.在这一点上,协议只是一大堆丑陋的responds_to的缩写?查询,以及编译器/ IDE使用的一些非常有用的语法糖.
接口/协议是对象元数据的另一个维度,可用于在处理这些对象时实现动态行为.在Java中,编译器恰好要求正常的方法调用.但即使是像Ruby,Python,Perl等动态语言也实现了一种类型的概念,它不仅仅是"对象响应的方法".因此class关键字.Javascript是唯一没有这个概念的常用语言.如果你有课程,那么接口也是有意义的.
对于更复杂的库或类层次结构而言,它比大多数应用程序代码更有用,但我认为这个概念在任何语言中都很有用.
另外,还有人提到了mixins.Ruby mixins是一种共享代码的方式 - 例如,它们与类的实现有关.接口/协议是关于类或对象的接口.它们实际上可以相互补充.您可能有一个指定行为的接口,以及一个或多个帮助对象实现该行为的mixin .
当然,我想不出任何真正具有独特的一流语言特征的语言.在mixins中,包括mixin通常意味着它实现的接口.