为什么Ruby人说他们不需要接口?
ruby与其他OOP语言有什么不同(例如:PHP)会使接口无用吗? 它有什么替代品吗?
编辑:
一些澄清:
-
在其他语言(例如:PHP)中,您不需要“接口”(在代码级别它们不是必需的)。 您可以使用它们签订合同,以改进软件的架构。 因此,肯定’在ruby中你不需要接口/在其他语言中你需要接口,因为XXX’是错误的。
-
不,mixins不是接口,它们是完全不同的东西(PHP 5.4实现mixins)。 你有没有使用过接口?
-
是的,PHP是OOP。 语言不断发展,欢迎来到现在。
这个问题有点开放,但这是我的看法:
接口声明的目的是两件事:
- 向你的未来自己或同事宣告这个class级必须具备的方法
- 向您的计算机声明此类必须具有的方法
如果我们首先考虑第二个目的,那么永远不会编译Ruby源代码,因此永远不会有选项来validation与接口声明的一致性,并警告开发人员不遵守。 这意味着如果Ruby有一些内置的接口支持,它就没有选项来validation一致性,直到运行时,由于缺少实现,应用程序将崩溃。
所以回到第一个目的。 代码可读性。 这可能有意义,并且指定接口的正式Ruby约定可能会有所帮助。 现在,您可能会使用注释或规范或 – 我可能更喜欢 – 一个声明性模块包含来传达此信息。 例如
module Shippable # This is an interface module. If your class includes this module, make sure it responds to the following methods # Returns an integer fixnum representing weight in grams def weight raise NotImplementedError.new end # Returns an instance of the Dimension class. def dimensions raise NotImplementedError.new end # Returns true if the entity requires special handling. def dangerous? raise NotImplementedError.new end # Returns true if the entity is intended for human consumption and thereby must abide by food shipping regulations. def edible? raise NotImplementedError.new end end class Product include Shippable end
一种强制执行此接口的方法是创建一个规范,该规范创建包含Shippable
模块的每个类的实例,调用这四个方法并期望它们不会引发NotImplementedError
。
由于ruby是duck-typed
,不需要单独的接口,但是对象只需要实现常用方法。 看看下面的“经典”示例:
class Duck def move "I can waddle." end end class Bird def move "I can fly." end end animals = [] animals << Duck.new animals << Bird.new animals.each do |animal| puts animal.move end
在这个例子中,“接口”是move
方法,由Duck
和Bird
类实现。
我是一个’Ruby人’,我想要接口,或类似的东西。
不执行合同 – 因为强制执行任何事情都不是Ruby,并且有点破坏了动态语言的意义,无论如何没有“编译”步骤来强制执行它 – 但是要记录客户端子类可以选择符合的合同到(或不,如果他们选择不,他们不能抱怨如果代码不起作用)。
当我遇到这个问题时,也就是说,当我编写一个类或模块时,我期望子类提供方法,我通常会记录我期望子类提供的方法,如下所示:
module Enumerable def each raise NotImplementedError, "Subclasses must provide this method" end end
这不是理想的,但它是一个相当罕见的情况,它适用于我。
我相信这是因为Ruby是动态类型的,而其他语言是静态类型的。 您需要在PHP中使用接口的唯一原因是在传递对象时使用类型提示。
取决于界面的含义。
如果通过接口表示您inheritance或实现的语言中存在的具体对象,那么不要使用像ruby这样的语言的接口。
如果你的意思是接口在对象中有一些记录良好的接口,那么当然,对象仍然有一个记录良好的接口,它们具有你期望在那里的属性和方法。
我同意接口是你脑海中存在的东西和文档,而不是作为对象的代码。