最近、ダックタイピングのことを聞いて、それについて Wikipediaの記事 を読みましたが、例をJavaに翻訳するのに苦労しています。これは、私の理解に非常に役立ちます。
誰かがJavaと入力するアヒルの明確な例と、それをどのように使用する可能性があるかを示すことができますか?
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()
}
このブログ投稿 を参照してください。動的プロキシを使用してJavaでダックタイピングを実装する方法について非常に詳細に説明しています。
要約すれば:
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 を使用すると簡単です。メソッド名と戻り値の型を一致させる必要があります。
Javaはダックタイピングを実装していません。
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互換言語。
通常、ダックタイピングは動的に型付けされた言語で使用されます。継承階層に関係なく、ニーズを満たすために必要なメソッドまたはプロパティの存在を実行時にチェックします。
醜くなるリフレクションを使用する以外に、最も近い方法は、ダックタイピングに必要なものの基準に一致する最小限のインターフェイスを使用することです。これ ブログ投稿 は概念を説明するのに良い仕事をします。 pythonまたはRubyまたはjavascriptでのダックタイピングの単純さの多くを失いますが、実際にはJava =高レベルの再利用性を探している場合。
パーティーに遅れましたが(いつものように)、自分でダックタイピングをするための簡単なクラスを書きました。 ここ を参照してください。
それはインターフェースにのみ行きますが、使用例については:
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のクラス(プライベートを含む)のすべてのメソッドをチェックします。ただし、汎用インターフェイスを使用したテストはまだ行っていません。
オブジェクトのデコレータを動的に作成するユーティリティクラスを作成しました。ダックタイピングに使用できます: 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!