2009-07-03 5 views
28

私は最近、アヒルのタイピングについて聞きました。Wikipedia articleについて読んでいますが、例をJavaに翻訳するのは苦労しています。Javaでのダックタイピングの例は何ですか?

誰でもJavaでダックタイピングの明確な例を与えることができますか、どのように私はそれを使用する可能性がありますか?

+1

はい、しかし、ここで他の人が読んでいない可能性がありますその記事を。 –

答えて

38

Javaは、設計上、ダックタイピングに適合しません。あなたがそれを行うことを選択するかもしれない方法が反映している:

public void doSomething(Object obj) throws Exception { 

    obj.getClass().getMethod("getName", new Class<?>[] {}).invoke(obj); 
} 

しかし、私は、このような、それはより多くの意味になりGroovyの、として、動的言語でそれをやって主張します:

class Duck { 
    quack() { println "I am a Duck" } 
} 

class Frog { 
    quack() { println "I am a Frog" } 
} 

quackers = [ new Duck(), new Frog() ] 
for (q in quackers) { 
    q.quack() 
} 

Reference

+2

++ニースのアヒルの例ですが、私は新しいオブジェクト作成メソッドが好きです。 – Secko

+3

Javaの反射経路を下っている場合は、「duckapter」と呼ばれるエレガントなライブラリを使いました:http://code.google.com/p/duckapter/ – penfold

+0

ダックタイピングを実装するのがなぜ難しいのかJavaまたは任意の静的型言語?人々は私たちができるインタフェースを使用して言う。 Plzは説明します。 – kamal

5

check this library

interface MyInterface { 
    void foo(); 
    int bar(int x, int y); 
    int baz(int x); 
} 

public class Delegate { 
    public int bar() { 
     return 42; 
    } 
} 

DuckPrxy duckProxy = new DuckPrxyImpl(); 
MyInterface prxy = duckProxy.makeProxy(MyInterface.class, new Delegate()); 
prxy.bar(2, 3); // Will return 42. 

インターフェースダックタイピングではDynamic Proxyを使用して簡単です、あなたはメソッド名と戻り値の型と一致する必要があります。

+1

これは厳密にはダックタイピングではなく、動的プロキシ(これが行うことです)を使用することは、Javaと同じくらい近いことです。 – cletus

4

Javaはダックタイピングを実装していません。

1

Javaの入力は公称です - 互換性は名前に基づいています。ダックタイピング(または構造型の入力)がJavaのように見える例が必要な場合は、このページをご覧ください。http://whiteoak.sourceforge.net/#Examplesは、Whiteoakで書かれたプログラムの例を提供しています。

1

通常、ダックタイピングは、動的に型指定された言語で使用されます。実行時に、継承階層に関係なく、ニーズを満たすために必要なメソッドまたはプロパティの存在をチェックします。

醜いリフレクションを使用する以外は、ダックタイピングに必要な基準に一致する最小限のインターフェイスを使用することで最も近いものが得られます。このblog postは、このコンセプトを説明してくれています。それは、PythonやRubyやJavascriptでのダックタイピングの単純さの多くを失いますが、再利用性の高いレベルを探しているなら、Javaでの実際のところかなり良い方法です。

10

this blog postを参照してください。これは、動的プロキシを使用してJavaでダックタイピングを実装する方法を詳しく説明しています。要約すると

  • は、このインターフェイスとのインターフェイスのメソッドを呼び出す実装オブジェクトを使用して、動的プロキシを作成
  • を入力してアヒルを経由して使用する方法を表すインターフェイスを作成します

    N:のJava 8と

+0

これは良い記事です。何か起こった場合に備えて、ここで与えられた解決策を要約することができると思いますか? – Shog9

+1

非常に基本的な説明が追加されました。 –

+0

動的プロキシ*を使用したダックタイピングは、少量のコードでも実装できます。[this gist](https://gist.github.com/unix-junkie/b9481245904892f07780)を参照してください。 'Proxy'によって実装されたインタフェースの順序が重要であることに注意してください。間違っていると、' java.lang.IllegalArgumentException:オブジェクトがクラスを宣言するインスタンスではありません。 – Bass

3

(署名の一致を仮定して)反射により、基礎となるオブジェクトは、2つの方法を持っていますº1:あなたが唯一の方法が必要な場合は、ラムダ

を使用
static interface Action { public int act(); } 

public int forEachAct(List<Action> actionlist) { 
    int total = 0; 
    for (Action a : actionList) 
     total += a.act(); 
} 

public void example() { 
    List<Action> actionList = new ArrayList<>(); 
    String example = "example"; 
    actionList.add(example::length); 
    forEachAct(actionList); 
} 

nº2:使用匿名クラス(ない非常に性能面は、いくつかの非クリティカルな部分で、それを行うことができます)

static interface Action { 
    public int act(); 
    public String describe(); 
} 

public void example() { 
    List<Action> actionList = new ArrayList<>(); 
    String example = "example"; 

    actionList.add(new Action(){ 
     public int act() { return example.length(); } 
     public String describe() { return "Action: " + example; } 
    }); 
} 
0

ニース定義:

オブジェクトは、共通の基本クラスまたはインタフェースによって関連性がなく、多態性です。

Reference

0

私は、動的オブジェクトのデコレータを作成するためのユーティリティクラスを書きました。あなたはダックタイピングのためにそれを使用することができます。 https://gist.github.com/stijnvanbael/5965616

例:

interface Quacking { 
    void quack(); 
} 

class Duck { 
    public void quack() { System.out.println("Quack!"); } 
} 

class Frog { 
    public void quack() { System.out.println("Ribbip!"); } 
} 

Quacking duck = Extenter.extend(new Duck()).as(Quacking.class); 
Quacking frog = Extenter.extend(new Frog()).as(Quacking.class); 

duck.quack(); 
frog.quack(); 

出力:

Quack! 
Ribbip! 
関連する問題