我只是最近听说鸭打字和我读了维基百科的文章这件事,但我有一个很难翻译的例子为Java,这将真正帮助我的理解。
会有人能够给Java中鸭子类型的一个明显的例子,我怎么有可能会使用它吗?
我只是最近听说鸭打字和我读了维基百科的文章这件事,但我有一个很难翻译的例子为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.
与接口鸭打字使用很简单的动态代理 ,你应该匹配的方法名称和返回类型。
Java不执行鸭打字。
与Java 8,你有2种方式:
Nº1:如果你只需要一个方法,使用lambda表达式
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中其实还不错的做法,如果你正在寻找一个高水平的可重用性。
尼斯的定义:
对象是没有通过一个共同的基类或接口被相关的多态。
参考
我写了一个工具类的一个对象动态创建的装饰。 你可以使用它的鸭子类型: 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!
迟到了(像往常一样),但我写了一个快速类做一些鸭子类型自己。 见这里 。
它只会去的接口,但对于一个使用示例:
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的类的所有方法(包括私人)。 还没有对通用接口的任何测试尚未虽然。