单分派 (Single Dispatch)
分派是指在方法调用过程中,根据接收者对象的实际类型来决定调用哪个方法的机制。在 Java 中,单分派是最常见的形式,它通常在运行时根据对象的实际类型来确定要调用的方法版本。例如,当你有一个基类和几个继承自这个基类的子类,并且基类中定义了一个虚方法(在 Java 中即为 virtual 或 override 方法),那么在运行时,会根据实际的对象类型来调用相应的子类方法。
示例
class Animal {
public void makeSound() {
System.out.println("Some generic sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound(); // 输出 "Woof!"
myCat.makeSound(); // 输出 "Meow!"
}
}
makeSound() 方法的调用是基于 myDog 和 myCat 实际引用的对象类型(Dog 和 Cat 类型)来决定的,这就是单分派。
双分派 (Double Dispatch)
双分派是一种设计模式,它允许在运行时根据两个对象的类型来选择一个合适的方法执行。在传统的单分派中,方法的选择只基于接收者对象的类型,而在双分派中,方法的选择还考虑到了传递给方法的参数的类型。
在 Java 中,由于语言本身不支持动态的多分派,因此需要通过一些技巧来实现双分派。一种常见的方法是使用访问者模式(Visitor Pattern)。访问者模式通过定义一个包含多个访问方法的访问者接口,以及被访问的元素类来实现双分派的行为。
示例
interface Element {
void accept(Visitor visitor);
}
class ConcreteElementA implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class ConcreteElementB implements Element {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor {
void visit(ConcreteElementA element);
void visit(ConcreteElementB element);
}
class ConcreteVisitor1 implements Visitor {
public void visit(ConcreteElementA element) {
System.out.println("Visitor 1 visited Element A");
}
public void visit(ConcreteElementB element) {
System.out.println("Visitor 1 visited Element B");
}
}
public class Main {
public static void main(String[] args) {
ConcreteElementA elementA = new ConcreteElementA();
ConcreteElementB elementB = new ConcreteElementB();
Visitor visitor1 = new ConcreteVisitor1();
elementA.accept(visitor1); // 输出 "Visitor 1 visited Element A"
elementB.accept(visitor1); // 输出 "Visitor 1 visited Element B"
}
}
accept 方法实现了第一次分派,它根据 elementA 或 elementB 的类型调用 visitor 的适当方法。然后,visit 方法实现了第二次分派,它根据 visitor 的类型来决定具体的行为。这种方法允许在运行时根据两个对象的类型来选择合适的行为,这就是双分派。
评论区