前言
正文
介绍
我的理解是,利用多态特点,也就是在运行时确定对象的实际类型的特点,来间接让单分派语言实现双分派。简单的说,就是让下面的代码合理
场景类
package cn.zjm404.stu.dp.behavior.visitor;public class Client {public static void main(String[] args) {AbstractObject ao = new ConcreteObject1();Executor executor = new Executor();executor.doSomething(ao);}}
执行类
package cn.zjm404.stu.dp.behavior.visitor;public class Executor implements Visitor{@Overridepublic void visit(ConcreteObject1 co1) {System.out.println("co1 执行");}@Overridepublic void visit(ConcreteObject2 co2) {System.out.println("co2 执行");}}
Bean
AbstractObject 与 ConcreteObject1,ConcreteObject2 关系如下
至于为什么需要实现这个功能,在“使用”进行介绍。先看如何实现
实现
以上代码问题出在无法确定调用对象的哪个方法,对于对象调用哪个方法,是在编译阶段确定的,而使用参数的父类,并无法在编译阶段确定具体的调用方法。会出现问题
如何实现呢?正如介绍中说的那样,多态特性保证了可以在运行时确定对象的实际类型,那么可以借用这种特性,在确定对象之后,再确定方法,实现方式就是将当前对象传递过去。代码如下
中间类
package cn.zjm404.stu.dp.behavior.visitor;public interface Visitor {public void doSomething(ConcreteObject1 co1);public void doSomething(ConcreteObject2 co2);}
执行类
package cn.zjm404.stu.dp.behavior.visitor;public abstract class AbstractObject {public abstract void accept(Visitor visitor);}
package cn.zjm404.stu.dp.behavior.visitor;public class Executor implements Visitor{@Overridepublic void doSomething(ConcreteObject1 co1) {System.out.println("co1 执行");}@Overridepublic void doSomething(ConcreteObject2 co2) {System.out.println("co2 执行");}}
Bean
package cn.zjm404.stu.dp.behavior.visitor;public class ConcreteObject1 extends AbstractObject{@Overridepublic void accept(Visitor visitor) {visitor.doSomething(this);}}
package cn.zjm404.stu.dp.behavior.visitor;public class ConcreteObject2 extends AbstractObject {@Overridepublic void accept(Visitor visitor) {visitor.doSomething(this);}}
场景类
package cn.zjm404.stu.dp.behavior.visitor;public class Client {public static void main(String[] args) {AbstractObject ao = new ConcreteObject1();Executor executor = new Executor();// executor.doSomething(ao);ao.accept(executor);}}
