web-dev-qa-db-ja.com

Javaでのダックタイピングの例は何ですか?

最近、ダックタイピングのことを聞いて、それについて Wikipediaの記事 を読みましたが、例をJavaに翻訳するのに苦労しています。これは、私の理解に非常に役立ちます。

誰かがJavaと入力するアヒルの明確な例と、それをどのように使用する可能性があるかを示すことができますか?

36
Cuga

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()
}

参照

44
Robert Munteanu

このブログ投稿 を参照してください。動的プロキシを使用してJavaでダックタイピングを実装する方法について非常に詳細に説明しています。

要約すれば:

  • ダックタイピングを介して使用するメソッドを表すインターフェイスを作成します
  • このインターフェイスを使用する動的プロキシと、リフレクションによって基になるオブジェクトのインターフェイスのメソッドを呼び出す実装オブジェクトを作成します(署名が一致すると仮定)
11
Dean Povey

このライブラリを確認してください

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 を使用すると簡単です。メソッド名と戻り値の型を一致させる必要があります。

6
dfa

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

5
cd1

Java 8の場合、2つの方法があります。

nº1:メソッドが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; }
    });
}

Javaは名目上のものです-互換性は名前に基づいています。ダックタイピング(または構造型タイピング)がJavaこのページをご覧ください: http://whiteoak.sourceforge.net/#Examples Whiteoakで書かれたプログラムの例を提供します:構造型をサポートするJava互換言語。

1
Itay Maman

良い定義:

オブジェクトは、共通の基本クラスまたはインターフェイスによって関連付けられていないポリモーフィックです。

参照

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

醜くなるリフレクションを使用する以外に、最も近い方法は、ダックタイピングに必要なものの基準に一致する最小限のインターフェイスを使用することです。これ ブログ投稿 は概念を説明するのに良い仕事をします。 pythonまたはRubyまたはjavascriptでのダックタイピングの単純さの多くを失いますが、実際にはJava =高レベルの再利用性を探している場合。

1
Russell Leggett

パーティーに遅れましたが(いつものように)、自分でダックタイピングをするための簡単なクラスを書きました。 ここ を参照してください。

それはインターフェースにのみ行きますが、使用例については:

interface Bird {
    void fly();
}

interface Duck extends Bird {
    void quack();
}

class PseudoDuck {
    void fly() {
        System.out.println("Flying");
    }

    void quack() {
        System.out.println("Quacking");
    }
}

class Tester {
    @Test
    void testDuckTyping() {
        final Duck duck
                = DuckTyper.duckType(new PseudoDuck(), Duck.class);
    }
}

デフォルトのインターフェースメソッド、パラメーターをサポートし、例外タイプのチェックは互換性があり、PseudoDuckのクラス(プライベートを含む)のすべてのメソッドをチェックします。ただし、汎用インターフェイスを使用したテストはまだ行っていません。

1
BeUndead

オブジェクトのデコレータを動的に作成するユーティリティクラスを作成しました。ダックタイピングに使用できます: 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!
1
Stijn Van Bael