美文网首页技术栈
2019-02-11——鸭子模型

2019-02-11——鸭子模型

作者: 烟雨乱平生 | 来源:发表于2019-02-12 11:38 被阅读1次

鸭子类型(duck typing)是动态类型的一种风格。在这种风格中一个对象的有效语义不是由继承自特定的类或实现特定的接口,而是由当前的方法和属性的集合决定。

"当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。
由于鸭子类型机制常见于动态语言,我们先看个Python的例子:


class Duck:
    def quack(self): 
        print "鸭子叫"
    def feathers(self): 
        print "鸭子有羽毛"
 
class Person:
    def quack(self):
        print "模仿鸭子叫"
    def feathers(self): 
        print "人没有羽毛"
 
def in_the_forest(duck):
    duck.quack()
    duck.feathers()
 
def game():
    donald = Duck()
    john = Person()
    in_the_forest(donald)
    in_the_forest(john)
 
game()

在该例中in_the_forest方法不关注传入的参数是那种类型,而关心该对象是否有特定的方法。

Java 实现鸭子类型

  • 其中一种方式是通过多态
public interface Performer {
    void eat();
    void walk();
}




public class Dog implements Performer {
    @Override
    public void eat() {
        System.out.println("狗吃狗粮");
    }

    @Override
    public void walk() {
        System.out.println("狗跑的很快");
    }
}




public class Cat implements Performer {
    @Override
    public void eat() {
        System.out.println("猫吃猫粮");
    }

    @Override
    public void walk() {
        System.out.println("猫走路很轻盈");
    }
}




public class T {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();
        perform(dog);
        perform(cat);
    }

    static <T extends Performer> void perform(T duck){
        duck.eat();
        duck.walk();
    }
}

严格来说这种实现并非准确的鸭子模型,因为perform方法的参数必须实现了Performer接口,即关注了对象的本身的类型

  • 常用方式是使用反射
public class Cat {
    public void eat() {
        System.out.println("猫吃猫粮");
    }

    public void walk() {
        System.out.println("猫走路很轻盈");
    }
}




public class Dog {
    public void eat() {
        System.out.println("狗吃狗粮");
    }

    public void walk() {
        System.out.println("狗跑的很快");
    }
}




public class T {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Cat cat = new Cat();
        try {
            perform(dog);
            perform(cat);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    static void perform(Object duck) throws Exception {
        Class clazz = duck.getClass();
        Method eat = clazz.getMethod("eat");
        eat.invoke(duck);
        Method walk = clazz.getMethod("walk");
        walk.invoke(duck);
    }
}

比起使用多态,使用反射更接近于鸭子模型,perform方法不关心传入的对象的类型,只关心该对象是否拥有指定的方法。


相关文章

  • 2019-02-11——鸭子模型

    鸭子类型(duck typing)是动态类型的一种风格。在这种风格中一个对象的有效语义不是由继承自特定的类或实现特...

  • 设计模式--策略模式

    一、问题的产生举例:鸭子模型鸭子模型中会出现各种鸭子,会游泳,会呱呱叫,于是设计一个鸭子超类(Duck),并让各种...

  • NSProxy

    objc与鸭子对象(上)分析"objc与鸭子对象"代码,该作者使用protocol实现一个模型的协议,使用NSPr...

  • 2019-02-11 盘后分析和后市预测直播录像

    2019-02-11 盘后分析和后市预测直播录像

  • 符合Python风格的对象

    基于 Python 的数据模型,自定义类型可以实现和内置类型一样自然的行为,实际上靠的是 鸭子类型。 鸭子类型:按...

  • 鸭子,鸭子,鹅

    有一天,小鸭子特别想玩单脚跳,特别特别想,可是刺儿头却不在。 小鸭子对小鹅说:“小鹅,你最喜欢做什么?” 小鹅从花...

  • 嘿,鸭子,鸭子

    看《那些年》的时候我在想,谁高中没个后桌呢。 对盼记忆最深的印象还是,我弄坏了她数学书的一页,心中忐忑不安。那时候...

  • 2019-02-11 第63章 “养成良好的工作习惯”白雪在悦

    2019-02-11 第63章 “养成良好的工作习惯”白雪在悦读 书名:《人性的弱点》 作者:(美)戴尔•卡耐基...

  • 要事优先!!60天易效能时间管理践行-打卡第32天

    打卡日期:2019-02-11 打卡累计天数:32/60 60天践行目标: 1、早起6:00-6:30,早睡22:...

  • 语法

    鸭子类型 动态语言中经常提到鸭子类型,所谓鸭子类型就是:如果走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子(If ...

网友评论

    本文标题:2019-02-11——鸭子模型

    本文链接:https://www.haomeiwen.com/subject/jutceqtx.html