java 鸭子类_Java中实现鸭子类型机制
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。“【引用维基】
一般而言,鸭子类型机制常见/用于动态语言,如Python、Ruby、JS。来段Python代码实例:
class Duck:
def quack(self):
print "Quaaaaaack!"
def feathers(self):
print "The duck has white and gray feathers."
class Person:
def quack(self):
print "The person imitates a duck."
def feathers(self):
print "The person takes a feather from the ground and shows it."
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的形参duck,只要有方法quack和feathers即可,不用关注具体类型,这样使设计更加”范化“。当然鸭子类型机制并不仅限动态语言,在静态语言中也可见,本文主要阐述在Java中的鸭子类型机制(亦称潜在类型机制或结构化类型机制)实现。
实现方式一: 使用一个类或接口,并用有边界泛型方法实现,见代码:
// interface Performs.class
public interface Performs {
void quack();
void feathers();
}
// class Duck.class
public class Duck implements Performs {
public void quack() {
System.out.println("Quaaaaak!");
}
public void feathers() {
System.out.println("The duck has white and gry feathers!");
}
}
// class Person.class
public class Person implements Performs {
public void quack() {
System.out.println("The person imitates a duck!");
}
public void feathers() {
System.out.println("The person has yellow feather!");
}
}
// class MainClass.class
public class MainClass {
public static void inTheForest(T duck) {
duck.quack();
duck.feathers();
}
public static void main(String[] args) {
Duck d = new Duck();
Person p = new Person();
MainClass.inTheForest(d);
MainClass.inTheForest(p);
}
}方式一使用的前提是都有共同的基类或者接口,但是当两个类之间没有这个条件仅有相同的方法签名时如何实现呢?这时可以采用如下两种方法:
方式二: 利用反射,见代码
// class Duck.class
public class Duck {
public void quack() {
System.out.println("Quaaaaak!");
}
public void feathers() {
System.out.println("The duck has white and gry feathers!");
}
}
// class Person.class
public class Person {
public void quack() {
System.out.println("The person imitates a duck!");
}
public void feathers() {
System.out.println("The person has yellow feather!");
}
}
// class MainClass.class
import java.lang.reflect.*;
public class MainClass {
public static void inTheForest(Object duck) {
Class> duk = duck.getClass();
try {
try {
Method quack = duk.getMethod("quack");
quack.invoke(duck);
} catch(NoSuckMethodException e) {
System.err.println(duck + " cannot quack");
}
try {
Method feathers = duk.getMethod("feathers");
feathers.invoke(duck);
} catch(NoSuckMethodException e) {
System.err.println(duck + " cannot feathers");
}
} catch(Exception e) {
throw new RuntimeException(duck.toString(), e);
}
}
public static void main(String[] args) {
Duck d = new Duck();
Person p = new Person();
MainClass.inTheForest(d);
MainClass.inTheForest(p);
}
}
方式三: 模拟接口,使用适配器设计模式
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
// interface Performs.class
// 先前不包含这个接口,也不继承这个接口
interface Performs {
void quack();
void feathers();
}
// class Duck.class
class Duck {
public void quack() {
System.out.println("Quaaaaak!");
}
public void feathers() {
System.out.println("The duck has white and gry feathers!");
}
}
// class Person.class
class Person {
public void quack() {
System.out.println("The person imitates a duck!");
}
public void feathers() {
System.out.println("The person has yellow feather!");
}
}
// Adapter
class PerformsAdapter implements Performs {
private Object d;
public PerformsAdapter(Object d) {
this.d = d;
}
public void quack() {
Class> dk = d.getClass();
try {
Method qk = dk.getMethod("quack");
qk.invoke(d);
} catch (NoSuchMethodException e) {
System.out.println(d + " cannot quack");
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public void feathers() {
Class> dk = d.getClass();
try {
Method ft = dk.getMethod("feathers");
ft.invoke(d);
} catch (NoSuchMethodException e) {
System.out.println(d + " cannot have feathers");
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
// class MainClass.class
public class DuckTest {
public static void inTheForest(T duck) {
duck.quack();
duck.feathers();
}
public static void main(String[] args) {
Duck d = new Duck();
Person p = new Person();
DuckTest.inTheForest(new PerformsAdapter(d));
DuckTest.inTheForest(new PerformsAdapter(p));
}
}
参考文献:
1. 鸭子类型 http://zh.wikipedia.org/wiki/%E9%B8%AD%E5%AD%90%E7%B1%BB%E5%9E%8B
2. 《Thinking in Java》
java 鸭子类_Java中实现鸭子类型机制相关推荐
- java 继承示例_Java中的继承类型以及示例
java 继承示例 Prerequisite: Inheritance and its implementation in Java 先决条件: 继承及其在Java中的实现 Java中的继承类型 (T ...
- java double 计算_Java中的Double类型计算
一.问题的提出: 如果我们编译运行下面这个程序会看到什么? public class Test{ public static void main(String args[]){ System.out. ...
- java sleep唤醒_Java中的等待唤醒机制—至少50%的工程师还没掌握!
Java中的等待唤醒机制-至少50%的工程师还没掌握! 发布时间:2019-12-14 01:53, 浏览次数:222 , 标签: Java 这是一篇走心的填坑笔记,自学Java的几年总是在不断学习新 ...
- java 通配符 泛型_java中泛型之类型通配符(?)
实体类 package cn.xy.model; /** * 生物类 * @author xy * */ public class Living { private String name; publ ...
- java类加密_Java中常用加密类型
1.对称加密 image.png 密钥:加解密钥相同 缺点:无法确保密钥被安全传递 常用算法:DES.3DES(TripleDES).AES等 2.非对称加密 image.png image.png ...
- java cache教程_Java 中常用缓存Cache机制的实现
缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式: 二.内存缓存,也就是实现一个类中静态Map,对这个Map ...
- Python 语言中的 “鸭子类型”
Python 语言中的 "鸭子类型" 继承 多态 鸭子类型 不要检查它是不是鸭子.它的叫声像不像鸭子.它的走路姿势像不像鸭子,等等.具体检查什么取决于你想使用语言的哪些行为.(co ...
- python中的鸭子类型
浅层理解 走路像鸭子,说话像鸭子,它就是鸭子 深层理解 指的是面向对中,子类不需要显示的继承某个类,只要有某个的方法和属性,那我就属于这个类 编程语言中的鸭子类型说明 假设有个鸭子类Duck类,有两个 ...
- Java如何给Mysql中插入year类型数据
文章目录 Java如何给Mysql中插入year类型数据 实际问题: 解决方案: 从数据库中读取year类型数据到Java 从Java中往数据库存储year数据 Java如何给Mysql中插入year ...
最新文章
- python私有函数
- Boston房价PaddlePaddle测试程序
- Codeforces Round #232 Editorial Div2-B
- 【控制】遗传算法(GA,Genetic Algorithm)及 Matlab 实现
- boost::multiprecision模块debug_adaptor相关的测试程序
- Characterizing stochastic time series with ordinal networks
- react classname多个_React全家桶简介
- java scala中传递变长参数
- 在html插入数学公式,在网页中显示数学公式
- 问题:检测到远端X服务正在运行中(CVE-1999-0526)
- 如何解决CPU过热100度自动关机
- 计算机一级win7win10,一招win7免费升级成win10系统的简单方法(图文)
- 安装Hadoop3.2.1(很多坑)
- c# opengl tao
- 幂指函数的极限运算法则
- 【编程题】【Scratch四级】2021.03 程序优化
- 成为大数据工程师需要具备什么能力?发展前景好么
- AF1210深信服网关配置
- 神马笔记 版本2.0.0——新的旅程
- 铂链获美国顶级区块链投资基金 Draper Dragon Digital Fund投资