我们能否像在 java 中那样在 Ruby 中公开接口(interface),并强制 Ruby 模块或类实现接口(interface)定义的方法。
一种方法是使用继承和 method_missing 来实现相同的目的,但是还有其他更合适的方法吗?
最佳答案
Ruby 与任何其他语言一样具有接口(interface)。
请注意,您必须注意不要将接口(interface) 的概念与interface
的概念混淆,接口(interface) 是一个单元的职责、保证和协议(protocol)的抽象规范。这是 Java、C# 和 VB.NET 编程语言中的关键字。在 Ruby 中,我们一直使用前者,但后者根本不存在。
区分两者非常重要。重要的是接口(interface),而不是interface
. interface
告诉你几乎没有用。没有什么比 Java 中的标记接口(interface) 更能说明这一点了,它们是根本没有成员的接口(interface):看看 java.io.Serializable
就知道了。和 java.lang.Cloneable
;那两个interface
这意味着非常不同的东西,但它们具有完全相同的签名。
所以,如果两个 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;
}
java.util.List<E>.add
的接口(interface) 是什么? ?
- 集合的长度不会减少
- 之前收藏中的所有元素都还在
- 那个
element
在收藏中
其中哪些实际出现在 interface
中?没有任何! interface
里面什么都没有那就是说 Add
方法甚至必须添加,也可能从集合中删除一个元素。
这是 interface
的一个完全有效的实现:
class MyCollection<E> implements java.util.List<E> {
void add(int index, E element)
throws UnsupportedOperationException, ClassCastException,
NullPointerException, IllegalArgumentException,
IndexOutOfBoundsException {
remove(element);
}
}
另一个例子:where in java.util.Set<E>
它实际上是说它是一个集合吗?无处!或者更准确地说,在文档中。英语。
在几乎所有 interfaces
的情况下,无论是来自 Java 还是 .NET,所有相关信息实际上都在文档中,而不是在类型中。所以,如果这些类型无论如何都不能告诉您任何有趣的事情,那为什么还要保留它们呢?为什么不只坚持文档?而这正是 Ruby 所做的。
请注意,其他语言实际上可以用有意义的方式描述接口(interface)。但是,这些语言通常不会调用描述接口(interface) 的构造“interface
”,他们将其称为type
。 .例如,在依赖类型的编程语言中,您可以表达 sort
的属性。函数返回一个与原始集合长度相同的集合,原始集合中的每个元素也在排序后的集合中,并且没有更大的元素出现在更小的元素之前。
所以,简而言之:Ruby 没有等同于 Java 的 interface
.但是,它确实具有与 Java 接口(interface) 等效的功能,并且与 Java 中的完全相同:文档。
此外,就像在 Java 中一样,验收测试也可用于指定接口(interface)。
特别是,在 Ruby 中,一个对象的接口(interface)是由它能做什么决定的,而不是class
。是,还是什么module
它混入。任何具有 <<
的对象方法可以附加到。这在单元测试中非常有用,您可以简单地传入 Array
。或 String
而不是更复杂的 Logger
, 即使 Array
和 Logger
不要共享明确的 interface
除了它们都有一个名为 <<
的方法之外.
另一个例子是 StringIO
, 它实现了与 IO
相同的接口(interface)因此,File
的界面 的很大一部分, 但除了 Object
之外没有共享任何共同的祖先.
关于ruby - Ruby 中的 java 接口(interface)等价物是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4437291/