• 締切済み

ダック・タイピングのメリット

Rubyには「ダック・タイピング」が可能とのことを知りました。 しかしその有用性がわかりません。 ダック・タイピングのメリットを教えてください。 Wikipediaには以下のように書いてありました。 ダック・タイピング - Wikipedia http://ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0 「オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、たとえそのクラスがそのインタフェースを宣言的に実装していなくとも、オブジェクトはそのインタフェースを実行時に実装しているとみなせる」 とりあえず意味はわかりました。しかし、すべてのメソッドを実装する努力をしながらインターフェイスの宣言をしないメリットがわかりません。そのインターフェイスを使うことがわかっているのなら宣言すればいい話だと思いますし、宣言を記述しなくて済むというメリットしかないということもないと思います。 ダック・タイピングのメリットを教えてください。 よろしくお願いします。

みんなの回答

  • siffon9
  • ベストアンサー率64% (136/211)
回答No.1

> ダック・タイピングのメリットを教えてください。 メリットはリンク先に書かれている 「オブジェクト(変数の値)に何ができるかはオブジェクトそのものが決定する」ではないでしょうか。 リンク先のRubyスクリプト例で言えば、testの引数に与えられるオブジェクトにsoundというメソッドが在りさえすれば、それに応じた戻り値を返すということです。 > 「オブジェクトがあるインタフェースのすべてのメソッドを持っているならば、(以下略)」 については以下のようなスクリプトでは如何ですか def test(foo) puts foo.sound end class Duck def sound 'quack' end end class Cat def sound 'myaa' end end dog = String.new("pochi") def dog.sound 'bow' end test(Duck.new) # => quack test(Cat.new) # => myaa test(dog) # => bow Stringというクラスは、soundというメソッドを実装していませんけれども、dogというオブジェクトはsoundメソッドを持っているので"bow"という値を返します。

mibusys
質問者

お礼

反応非常に遅くて失礼しました。 いまさらながらになんとなくわかりました。 この部分は、 def test(foo) puts foo.sound end 引数で渡されるfooはsoundというメソッドを持っているかどうかは 保証されないということですね?(Javaばっかりの人なので意味がわかりませんでした) 仮にfooにsoundがなかった場合には Javaだったらコンパイル時にエラーになる、実行前に保証されている、 Rubyだったら実行時にエラーになる、実行するまでわからない。 でも、1つのインターフェイスでメソッドの有無を保証しなくとも 実装者がきちんと書いてくれれば、インターフェイスを限定しなくとも いいじゃん。そのほうが柔軟で便利でしょということですね。タブン。 なんというか理念の違いのようなものなのでしょうかね。 Rubyはまったくわからないために時間がかかりましたがようやくわかりました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • インターフェイスの使い方がわかりません(初心者です)

    Javaを始めたばかりの初心者です。 「やさしいJava」を買って一通り学んだのですが、 インターフェイスの使い方がよくわからず、困っています。 インターフェイスを実装することでインターフェイスが持つメソッドがすべて定義されてることが保障される、 というのはわかるんですが、そのことがどうして有用なのでしょう? また、具体的にはスレッドを扱うときにRunnableインターフェイスを実装する理由がわかりません。 Threadクラスのオブジェクトを作成するときに、 Runnableを実装したクラスのオブジェクトの変数を 引数にしないといけないんですよね? このとき、Runnableインターフェイスが 「runメソッドが定義されていなければならない」 とだけいうものだったとしたら、 Runnableを実装してなくてもrunメソッドさえ定義してあれば 実行できそうな気がするんですが・・・

    • ベストアンサー
    • Java
  • RubyでJavaのInterfaceに相当するものはありますか?

    RubyでJavaのInterfaceに相当するものはありますか? Ruby 上で Javaの interface のようなものものを実現するには、どうしたらよ いのでしょうか? Rubyは型を宣言しないので機能的には interface は不要ですが。 クラスを実装する人に、あるクラスに実装しなければいけないメソッドを伝える (強制する)目的としての interface 的な使い方をしたいのです。 宜しくお願いいたします。

  • 抽象クラスのオブジェクトを生成できない理由は?

    ・抽象クラスは、なぜ(オーバーライドしないと)オブジェクトを生成できないのでしょうか? ・インタフェースみたいに、抽象メソッドしか宣言することができないなら話は分かるのですが… ・抽象メソッドでない普通のメソッドを実装できるのなら、オブジェクトを生成してくれても良いと思うのですが… ・そういう問題ではない?

    • ベストアンサー
    • Java
  • インターフェース

    インターフェースについて学ぼうと思っているのですが、 どうもいまいち何がなんだかわからなくなっています。 インターフェースはクラスによって実装され、 実装クラスはインターフェースで宣言されている 抽象メソッドを実行する とあるのですが、実装とは何ですか? 抽象メソッドとは何ですか?

    • ベストアンサー
    • Java
  • インターフェイスと抽象クラス

    なかなか理解が難しくて苦しんでいます。 で自分なりに理解したのですが、 抽象クラス→内容に決まっているメソッドと決まっていないメソッドがある場合に決まっていないメソッドを あとからオーバーライドするだけでスーパークラスで定義したすべてのメソッドを利用できる。 これでただしいでしょうか? で、インターフェイスなのですが、この抽象クラスとそっくりなんですが、 (1)変数は定数になる(強制static)(2)メソッドは名前のみの宣言(内容は記述できない) と言うことで、かなり???なのです。 何のために・・・???記述するんでしょうか?? ただひとつメリットがあるとしたら、インターフェイスを実装すると、インターフェイスの配列でインスタンスを 生成出来るということぐらいでしょうか。 そこでちょっとお門違いの疑問かもしれないんですが、 Runnable、やMouselistenerはメソッドの内容が書かれていないのに、 なぜ機能を持たせることが出来るのでしょう??? 認識違い、間違い等ありましたら、教えてください よろしくお願いいたします。

    • ベストアンサー
    • Java
  • インターフェイスと抽象メソッドについてお願いします。

    PHPの参考書で「抽象メソッド」と「インターフェイス」それに「実装」という言葉が出てきました。 プログラミングが初めてで全然理解できなく困っています。 ・抽象メソッド ・インターフェイス ・実装 上記の意味とメリットなどを教えてください。それとどのような面で使うのかも教えていただけると嬉しいです。 すみませんが、よろしくお願いします。

    • ベストアンサー
    • PHP
  • 継承・実装の関係で悩んでいます。

    継承・実装の関係について悩んでいます。 ここでは、アクセス制御を考えずに、インスタンスかstaticかabstract(ここではabstract final staticやabstract classのこと)の違いで、どう継承するのか考えています。 // 継承 はメソッドのオーバーライドのことを考えます。(オーバーロードは考えない) クラスAからクラスBでオーバーライドしたメソッドは、 クラスCでさらにオーバーライドできるのでしょうか? クラスCが クラスBのクラスAからオーバーライドしたメソッド をクラスBのメソッドとして見たときに、オーバーライドすることは可能なのでしょうか? クラスA │ インスタンスフィールドA │ staticフィールドA │ │ クラスA() { } │ │ インスタンスメソッドA () { } │ staticメソッドB() { } ↓ クラスB extends クラスA │ インスタンスフィールドA // 継承 │ インスタンスフィールドB │ staticフィールドB │ │ サブクラス1() { } // コンストラクタは継承しない、super()で呼び出す │ │ インスタンスメソッドA () { } // 継承 │ │ インスタンスメソッドB () { } │ staticメソッドB () { } ↓ クラスC extends クラスB implements インタフェースD, ... ↑ インスタンスフィールドA // クラスBのフィールドを継承 │ インスタンスフィールドB // クラスBのフィールドを継承 │ インスタンスフィールドC │ staticフィールドC │ │ サブクラス2() { } │ │ インスタンスメソッドA () { } // クラスBのメソッドを継承 │ インスタンスメソッドB () { } // クラスBのメソッドを継承 │ インスタンスメソッドD () { } // インタフェースDのメソッドを実装 │ インスタンスメソッドE () { } // インタフェースDのメソッドを実装 │ │ │ インスタンスメソッドC () { } │ staticメソッドC() { } │ interface インタフェースD extends インタフェースE ↑ │ staticフィールドD // public static final │ │ インスタンスメソッドD() { } // public abstract │ インスタンスメソッドE() { } // 継承 │ interface インタフェースE staticフィールドE // public static final インスタンスメソッドE() { } // public abstract

    • ベストアンサー
    • Java
  • 「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」

    「インタフェースを実装してそれが持つ抽象メソッドをオーバーライドする」は正しい? はじめまして。Javaのインタフェースに関する質問です。 私はこれまで、インタフェースを使うときは、インタフェースを実装してクラスを宣言し、そのクラス、またはサブクラスでインタフェースがもつすべての抽象メソッドを定義する、と理解していました。 しかし、下の例をみてください。抽象メソッドの定義を、インタフェースの実装の以前で与えています。問題無くコンパイルでき、実行できます。実行結果も以下の通りです。 インタフェースの抽象メソッドへの定義の与え方やその実行のされ方は、メソッドのオーバーライドと同様と思っていましたので、下記のコードでは「クラスBが抽象クラスではありません」や、「インタフェースの抽象メソッドがオーバーライドされていません」などの文法エラーがでると思っていました。 そこで、質問です。 インタフェースが持つ抽象メソッドの定義を与える場所について、または、これに関する説明のあるページなど、何かご存知でしたら教えてください。 ★コード★ interface X{   void show(); } class A{   public void show(){     System.out.println("A");   } } class B extends A implements X{ } public class Main{   public static void main(String[] args){     X x=new B();     x.show();   } } ★実行結果★ >java Main A ★Java環境★ java 1.6.0_21 javac 1.6.0_16

    • ベストアンサー
    • Java
  • タッチタイピングの正しい指の割り当て

    タッチタイピング(ブラインドタッチ)を練習して習得しようと思っています。 タッチタイピングで、各キーをどの指でタッチするのか、画像を検索してみたところ、 数字のキーを受け持つ指が、まちまちです。 https://www.google.co.jp/search?q=%E3%83%96%E3%83%A9%E3%82%A4%E3%83%B3%E3%83%89%E3%82%BF%E3%83%83%E3%83%81&hl=ja&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjE5anIyJzMAhVoHKYKHcoeD3kQ_AUICCgC&biw=1347&bih=1039&dpr=0.9 https://www.google.co.jp/search?q=%E3%82%BF%E3%83%83%E3%83%81%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0&hl=ja&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjGqaHTyJzMAhUjJqYKHclaAwMQ_AUICCgC&biw=1347&bih=1039&dpr=0.9 これを見ると、例えばある画像では数字の「0(ゼロ)」は「右手薬指」なのに、別の画像では「右手小指」となっています。ほかの数字キーも画像によってずれています。 どれが正しいのでしょうか。 「自分にとってやりやすい方の指」という考え方もあるでしょうが、 どうせなら正しい指で覚えたいと思っておりす。

  • 戻り値で返したオブジェクトの寿命について

    Ruby初心者です。 【前置き】 メソッドで宣言した変数(以下arr)に値(以下[1,2,3])を代入し戻り値として返した場合、 メソッドの戻り値(以下retArr)には、[1,2,3]への参照(arr.object_id)が設定されると認識しております。 ----------------------- def method arr = [1,2,3] return arr end retArr = method() ----------------------- 【質問】 C言語の場合、関数内で宣言したローカル変数のアドレスを戻り値として返却した場合、 関数を抜けた時点で、そのアドレスの内容は保障されなくなりますが、 1.Rubyではその様な問題がなく動作するのは、何故でしょうか? 2.また、メソッド内で宣言したオブジェクト(上記[1,2,3])の寿命はいつまでなのでしょうか? 【備考】 いろいろと調べてみたのですが、オブジェクトの参照(object_id)は、ポインタに近い概念であることは記載されているのですが、その仕組みを理解できずに悩んでします。

    • ベストアンサー
    • Ruby