鸭子类型(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 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方法不关心传入的对象的类型,只关心该对象是否拥有指定的方法。

定义一个鸭子的类java_2019-02-11——Java 鸭子模型相关推荐

  1. java定义一个door的类_再探Java抽象类与接口的设计理念差异

    原文:http://blog.csdn.net/sunboard/article/details/3831823 1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是 ...

  2. 【 定义一个长方形Rect类再派生出长方体类Cub】

    [问题描述]定义一个长方形Rect类,派生出长方体类Cub,计算派生类对象(长方体)的表面积和体积. [输入形式]长方体对象的长.宽.高. [输出形式]输出该长方体的表面积和体积. [样例输入] 输入 ...

  3. 《JAVA练习题目7》 定义一个素数生成器类PrimeGenerator,用于生成给定区间内的所有素数。(类PrimeGenerator都由类Main代替)

    题目内容: 定义一个素数生成器类PrimeGenerator,用于生成给定区间内的所有素数.要求PrimeGenerator类具有: 属性:start(区间起始值),end(区间终止值),两个属性均为 ...

  4. 构造方法与重载:定义一个网络用户类,信息有用户 ID、用户密码、 email 地址。在建立类的实例时把以上三个信息都作为构造函数的参数输入

    构造方法与重载:定义一个网络用户类,信息有用户 ID.用户密码. email 地址.在建立类的实例时把以上三个信息都作为构造函数的参数输入, 其中用户 ID 和用户密码时必须缺省时 email地址是用 ...

  5. 3.【练习题】构造方法与重载 定义一个网络用户类,要处理的信息有用户ID、用户密码、email地址。拓展:判断密码长度

    package day09;/*3.[练习题]构造方法与重载 定义一个网络用户类,要处理的信息有用户ID.用户密码.email地址. 在建立类的实例时,把以上三个信息都作为构造函数的参数输入, 其中用 ...

  6. 定义一个 圆形 Circle类 , 定义其中的长度length属性,定义一个求面积getArea()的方法。 并编写一个测试类,进行长度的赋值和展示,并调用求面积方法展示面积值。

    定义一个 圆形 Circle类 , 定义其中的长度length属性,定义一个求面积getArea()的方法. 并编写一个测试类,进行长度的赋值和展示,并调用求面积方法展示面积值. public cla ...

  7. 定义一个长方形(Rectangle)类,有长、宽属性,对每个属性都提供相应的get/set方法。

    // 定义一个长方形(Rectangle)类,有长.宽属性,对每个属性都提供相应的get/set方法. package ch3; import java.util.Scanner; public cl ...

  8. 定义一个圆形Circle类。属性: r:半径 成员方法:get/set方法 showArea方法:打印圆形面积 showPerimeter方法......

    需求: 定义一个圆形Circle类. 属性: r:半径 成员方法: get/set方法 showArea方法:打印圆形面积 showPerimeter方法:打印圆形周长 定义测试类,创建Circle对 ...

  9. c++ 定义一个字符栈类Stack(包括类的实现)。数据成员包括一个存放字符的数组stck[ ]和一个栈指针tos。栈数组的尺寸由常量SIZE确定。栈的基本操作为Push()和Pop()。

    定义一个字符栈类Stack(包括类的实现).数据成员包括一个存放字符的数组stck[ ]和一个栈指针tos.栈数组的尺寸由常量SIZE确定.栈的基本操作为Push()和Pop(). //定义一个字符栈 ...

  10. 首先定义一个Point (点)类,包含属性x,y(x,y为坐标点),方法有setPoint、getX、getY和OprintInfo...python编程题练习

    复习python编程题集合的第五题,若有错误和改进意见,欢迎评论交流!            首先定义一个Point (点)类:                   (1)包含属性x,y(x,y为坐标 ...

最新文章

  1. android从服务端获取json解析显示在客户端上面,Android服务端获取json解析显示在客户端上面.doc...
  2. C# 将DataTable数据源转换成实体类
  3. Ajax.net显示错误信息
  4. java 线上运维_一次java应用线上运维实战
  5. pycharm debug 断点调试
  6. 【面向对象】面向对象程序设计测试题11-类的高级特性测试题
  7. [转]https配合移动端开发
  8. python文本词频统计是字典吗,只使用字典python3计算.txt文件中的词频
  9. 易打卡模板微信签到打卡小程序源码在线下载
  10. Linux Patch 文件代码补丁
  11. CentOS服务器ntpdate同步及使用ntpdate同步时钟服务器时间
  12. Book04--修改软件的艺术:构建易维护代码的9条最佳实践
  13. 带tan计算机在线,tan等于(万能计算器在线使用)
  14. 用tikz画球坐标系下的体积微元
  15. k8s之滚动更新、金丝雀发布、蓝绿发布
  16. 3.vue3.2的父传子defineProps,子传父emits以及ref
  17. 跨库查询——mysql
  18. 去静态化 php,PHP页面静态化 - 菜鸟要飞啊的IT小窝 - OSCHINA - 中文开源技术交流社区...
  19. 非机动车检测数据集(用于训练目标跟踪)
  20. vue js 语音播报 语音读文字 window.speechSynthesis new SpeechSynthesisUtterance (补充无声音 问题解决办法)

热门文章

  1. Python计算化学式相对分子质量(含完整代码)
  2. Rust中iter()和into_iter()的区别
  3. 应用宝shangjia安全评估报告_【开发者必看】APP《安全评估报告》怎么写?附填写范例...
  4. Excel单元格的相对绝对混合引用
  5. jQuery之动画的淡入淡出效果
  6. layim即时通讯实例各功能整合
  7. 机器学习(Machine Learning and Data Mining)CS 5751——final复习记录(3)
  8. 第五章 Spanning Tree协议安全攻防
  9. 外贸邮箱企业邮箱,免费外贸企业邮箱大全,外贸企业邮箱都有哪些?
  10. What The F**k Python!!!