什么是Java中鸭子类型的例子吗?什么是Java中鸭子类型的例子吗?(What's an e

2019-05-16 16:04发布

我只是最近听说鸭打字和我读了维基百科的文章这件事,但我有一个很难翻译的例子为Java,这将真正帮助我的理解。

会有人能够给Java中鸭子类型的一个明显的例子,我怎么有可能会使用它吗?

Answer 1:

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

参考



Answer 2:

请参见这篇博客 。 它给出了一个非常详细的介绍如何使用动态代理在Java中实现鸭打字。

综上所述:

  • 创建一个表示要使用的方法通过鸭子类型的接口
  • 创建使用这个接口,并调用由反射底层对象上的接口的方法的一个实现对象的动态代理(假设签名匹配)


Answer 3:

检查这个库 :

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.

与接口鸭打字使用很简单的动态代理 ,你应该匹配的方法名称和返回类型。



Answer 4:

Java不执行鸭打字。



Answer 5:

与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; }
    });
}


Answer 6:

打字在Java是标称 - 兼容性是基于名称。 如果您需要在鸭打字(或结构打字)怎么可能看起来像Java中的例子,请看看这个页面: http://whiteoak.sourceforge.net/#Examples它提供了写在Whiteoak程序的例子:一个基于Java兼容的语言,也支持结构类型。



Answer 7:

通常情况下,鸭打字使用动态类型语言。 您将检查在运行时的所需要的满足您的需求,方法或属性的存在,无论继承层次的。

除了使用反射,这将变得丑陋,你可以得到最接近的是使用匹配的,你需要什么鸭子类型的标准是最少的接口。 该博客文章做得很好描述的概念。 它失去了很多鸭打字的Python或Ruby或JavaScript的简单性,但其在Java中其实还不错的做法,如果你正在寻找一个高水平的可重用性。



Answer 8:

尼斯的定义:

对象是没有通过一个共同的基类或接口被相关的多态。

参考



Answer 9:

我写了一个工具类的一个对象动态创建的装饰。 你可以使用它的鸭子类型: 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!


Answer 10:

迟到了(像往常一样),但我写了一个快速类做一些鸭子类型自己。 见这里 。

它只会去的接口,但对于一个使用示例:

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的类的所有方法(包括私人)。 还没有对通用接口的任何测试尚未虽然。



文章来源: What's an example of duck typing in Java?