什么是 Ruby 中的 java 接口等价物? [英] What is java interface equivalent in Ruby?

查看:29
本文介绍了什么是 Ruby 中的 java 接口等价物?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们能否像在 Java 中那样在 Ruby 中公开接口,并强制 Ruby 模块或类实现接口定义的方法.

Can we expose interfaces in Ruby like we do in java and enforce the Ruby modules or classes to implement the methods defined by interface.

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

One way is to use inheritance and method_missing to achieve the same but is there any other more appropriate approach available ?

推荐答案

Ruby 拥有接口,就像任何其他语言一样.

Ruby has Interfaces just like any other language.

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

Note that you have to be careful not to conflate the concept of the Interface, which is an abstract specification of the responsibilities, guarantees and protocols of a unit with the concept of the interface which is a keyword in the Java, C# and VB.NET programming languages. In Ruby, we use the former all the time, but the latter simply doesn't exist.

区分两者非常重要.重要的是接口,而不是接口.interface 告诉你几乎没有任何用处.没有什么比 Java 中的标记接口更能说明这一点了,这些接口根本没有成员:看看 java.io.Serializablejava.lang.Cloneable;这两个接口意味着非常不同的东西,但它们具有完全相同的签名.

It is very important to distinguish the two. What's important is the Interface, not the interface. The interface tells you pretty much nothing useful. Nothing demonstrates this better than the marker interfaces in Java, which are interfaces that have no members at all: just take a look at java.io.Serializable and java.lang.Cloneable; those two interfaces mean very different things, yet they have the exact same signature.

那么,如果两个 interface 表示不同的事物,具有相同的签名,那么 interface 究竟能保证什么?

So, if two interfaces that mean different things, have the same signature, what exactly is the interface even guaranteeing you?

另一个很好的例子:

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.add接口是什么?

  • 集合的长度不会减少
  • 之前收藏中的所有项目仍然存在
  • 那个元素在集合中

其中哪些实际出现在 interface 中?没有任何!interface 中没有任何内容表明Add 方法必须甚至add,它也可以removeem> 集合中的一个元素.

And which of those actually shows up in the interface? None! There is nothing in the interface that says that the Add method must even add at all, it might just as well remove an element from the collection.

这是该接口的完全有效的实现:

This is a perfectly valid implementation of that 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 吗?无处!或者更准确地说,在文档中.英文版.

Another example: where in java.util.Set<E> does it actually say that it is, you know, a set? Nowhere! Or more precisely, in the documentation. In English.

在几乎所有接口的情况下,包括Java和.NET,所有相关信息实际上都在文档中,而不是在类型中.那么,如果这些类型无论如何都不会告诉您任何有趣的事情,那为什么还要保留它们呢?为什么不只坚持文档?而这正是 Ruby 所做的.

In pretty much all cases of interfaces, both from Java and .NET, all the relevant information is actually in the docs, not in the types. So, if the types don't tell you anything interesting anyway, why keep them at all? Why not stick just to documentation? And that's exactly what Ruby does.

请注意,在其他语言中,界面实际上可以用有意义的方式进行描述.然而,这些语言通常不会将描述Interface 的构造称为interface",而是将其称为type.例如,在依赖类型的编程语言中,您可以表达这样的属性,即 sort 函数返回与原始长度相同的集合,原始中的每个元素也在排序后的集合,并且没有更大的元素出现在更小的元素之前.

Note that there are other languages in which the Interface can actually be described in a meaningful way. However, those languages typically don't call the construct which describes the Interface "interface", they call it type. In a dependently-typed programming language, you can, for example, express the properties that a sort function returns a collection of the same length as the original, that every element which is in the original is also in the sorted collection and that no bigger element appears before a smaller element.

所以,简而言之:Ruby 没有与 Java interface 等效的东西.但是,它确实具有与 Java Interface 等效的功能,并且与 Java 中的完全相同:文档.

So, in short: Ruby does not have an equivalent to a Java interface. It does, however, have an equivalent to a Java Interface, and it's exactly the same as in Java: documentation.

此外,就像在 Java 中一样,验收测试也可用于指定接口.

Also, just like in Java, Acceptance Tests can be used to specify Interfaces as well.

特别是,在 Ruby 中,对象的接口取决于它可以做什么,而不是class是什么,或者它混合了什么 module.任何具有 << 方法的对象都可以附加到.这在单元测试中非常有用,您可以简单地传入 ArrayString 而不是更复杂的 Logger,即使 ArrayLogger 不共享显式的 interface 除了它们都有一个名为 <<< 的方法>.

In particular, in Ruby, the Interface of an object is determined by what it can do, not what class is is, or what module it mixes in. Any object that has a << method can be appended to. This is very useful in unit tests, where you can simply pass in an Array or a String instead of a more complicated Logger, even though Array and Logger do not share an explicit interface apart from the fact that they both have a method called <<.

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

Another example is StringIO, which implements the same Interface as IO and thus a large portion of the Interface of File, but without sharing any common ancestor besides Object.

这篇关于什么是 Ruby 中的 java 接口等价物?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆