我们可以像在java中一样在Ruby中公开接口,并强制Ruby模块或类实现接口定义的方法吗.

一种方法是使用继承和方法来实现相同的功能,但是还有其他更合适的方法吗?

推荐答案

Ruby和其他语言一样有Interfaces个.

请注意,您必须小心不要将Interface的概念与interface的概念混为一谈,前者是一个抽象的单元责任、保证和协议规范,后者是Java、C#和VB中的一个关键字.NET编程语言.在Ruby中,我们一直使用前者,但后者根本不存在.

区分两者是非常重要的.重要的是Interface,而不是interface.interface告诉你几乎没有什么有用的东西.没有什么比Java中的marker interfaces更好地证明了这一点,它是一种完全没有成员的接口:看看java.io.Serializablejava.lang.Cloneable;这两个interface代表very种不同的东西,但它们有exact same个签名.

那么,如果两个interface代表不同的东西,有相同的签名,那么interface代表什么呢?

另一个好例子:

package java.util;

interface List<E> implements Collection<E>, Iterable<E> {
    void add(int index, E element)
        throws UnsupportedOperationException, ClassCastException,
            NullPointerException, IllegalArgumentException,
            IndexOutOfBoundsException;
}

百分之Interface是什么?

  • Collection 的长度不会减少
  • 之前Collection 的所有物品都还在
  • element块在Collection 中

而其中哪一个真正出现在interface强中?没有一个interface中没有任何内容表明Add方法甚至必须是add,它可能只是集合中的一个元素.

这是一个完全有效的interface:

class MyCollection<E> implements java.util.List<E> {
    void add(int index, E element)
        throws UnsupportedOperationException, ClassCastException,
            NullPointerException, IllegalArgumentException,
            IndexOutOfBoundsException {
        remove(element);
    }
}

另一个例子:在java.util.Set<E>中,它实际上在哪里说它是set?无处或者更准确地说,在文档中.用英语

在几乎所有的interfaces个 case 中,都是来自Java和.NET,所有relevant个信息实际上都在文档中,而不是在类型中.所以,如果这些类型没有告诉你任何有趣的事情,为什么还要保留它们呢?为什么不坚持使用文档呢?这正是Ruby所做的.

请注意,有other种语言可以用有意义的方式描述Interface种语言.然而,这些语言通常不把描述Interface的构造称为"interface",而是称之为type.例如,在依赖类型的编程语言中,您可以表示以下属性:sort函数返回与原始函数长度相同的集合,原始函数中的每个元素也在已排序的集合中,并且较小的元素之前不会出现较大的元素.

简而言之,Ruby没有Java interface的类似功能.然而,它does与JavaInterface有一个类似功能,它与Java中的文档完全相同.

而且,就像在Java中一样,Acceptance Tests也可以用来指定Interfaces.

尤其是在Ruby中,一个对象的Interface是由它可以do的东西决定的,而不是class是什么,或者它混入了什么module.任何具有<<方法的对象都可以附加到.这在单元测试中非常有用,在单元测试中,您可以简单地通过ArrayString,而不是更复杂的Logger,尽管ArrayLogger不共享显式interface,只是它们都有一个称为<<的方法.

另一个例子是StringIO,它实现了与IO相同的Interface,因此是FileInterface的很大一部分,但除了Object之外没有共享任何共同祖先.

Ruby相关问答推荐

用函数组合枚举器的Ruby方法

如何用 yield_self 断链

如果嵌套数组为空,如何判断 ruby​​?

Procs的绑定

有没有一种简单的方法可以在 Ruby 中获取图像尺寸?

Sinatra 与 EventMachine WebSockets 一起工作是否成功?

如何从 url 获取文件扩展名?

Ruby gem 权限被拒绝 /var/lib/gems 使用 Ubuntu

复制文件,在 Ruby 中根据需要创建目录

Ruby - net/http - 重定向

判断字符串是否包含Ruby数组中的任何子字符串

Ruby 中的排序稳定吗?

在 Ruby 中,有没有办法使用 hash.each_with_index do |[k,v], i| 之类的东西?

. vs ::(点与双冒号)用于调用方法

如何在 ruby​​ 中进行命名捕获

通过 x 个字符在 Ruby 中获取子字符串

如何打破Ruby中的外循环?

Ruby:除非与如果不是

如何使用 Ruby 的 self 关键字

Ruby:是否可以在模块中定义类方法?