1. ホーム
  2. ruby

[解決済み] Rubyでjavaのインターフェースに相当するものは何ですか?

2022-05-16 17:33:24

質問

RubyでもJavaのようにインターフェースを公開し、Rubyモジュールやクラスがインターフェースで定義されたメソッドを実装するように強制することができますか?

継承とmethod_missingで実現する方法もありますが、他にもっと適切な方法はないのでしょうか?

どのように解決するのですか?

Rubyには インターフェイス があります。

の概念を混同しないように注意する必要があります。 インターフェース という概念を混同しないように注意する必要があります。 interface という概念と、Java、C#、VB.NETなどのプログラミング言語におけるキーワードである。Rubyでは、前者は常に使用しますが、後者は単に存在しないだけです。

この2つを区別することは非常に重要です。重要なのは インターフェース ではなく interface . また interface はほとんど何も教えてくれません。このことをよりよく表しているのは マーカーインターフェース を見てみてください。 java.io.Serializable java.lang.Cloneable この2つの 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 ?

  • コレクションの長さが減少しないように
  • 以前からコレクションにあったすべてのアイテムがまだそこにあること
  • その 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);
    }
}

別の例として java.util.Set<E> と書いてあるのでしょうか? セット ? どこにもありません! 正確には、ドキュメントに。英語では

のかなり多くのケースで interfaces の場合、Javaと.NETの両方から、すべての 関連する の情報は、実は型の中ではなく、ドキュメントの中にあるのです。では、もし型が何も面白いことを教えてくれないのであれば、なぜそれを維持するのでしょうか?なぜドキュメントだけにこだわらないのでしょうか?そして、それはまさにRubyが行っていることです。

があることに注意してください。 他の が使用できる言語があります。 インターフェース は実際に意味のある方法で記述することができます。しかし、それらの言語では一般的に インターフェース "です。 interface と呼ばれています。 type . 依存型プログラミング言語では,たとえば sort 関数は元のコレクションと同じ長さのコレクションを返し、 元のコレクションにある全ての要素はソートされたコレクションにもあり、 小さい要素の前に大きい要素が現れないという特性を表現することができます。

要するに、RubyにはJavaの interface . それは しかし、Java の インターフェース に相当するものがあり、それはJavaと全く同じものです:ドキュメントです。

また、Javaと同じように 受入テスト を指定することができます。 インターフェイス を指定することもできます。

特に、Rubyでは インターフェース は、そのオブジェクトができること できること で決まるのであって class が何であるか、あるいは module に混じる。を持つオブジェクトはすべて << メソッドを持つ任意のオブジェクトに付加することができます。これはユニットテストでは非常に便利で、単に Array または String の代わりに、より複雑な Logger であっても Array そして Logger は、明示的な interface というメソッドを持っていることを除けば、両者は明示的に << .

他の例として StringIO を実装しており、同じ インターフェース として IO というように、大部分は インターフェース File の他に共通の祖先を持たないが Object .