C++, Java 都是单分派语言。
有人把 Java 的重载说成是“静态多分派”,有待商榷。重载是在编译时决定要用哪个函数,是静态的,而一般来说,分派常常是指在运行时,如何决定调用哪个函数,是动态的。
单分派所调用的函数,由单个量决定,常常是被调用的Object 的实际类型,而不考虑传入参数的实际类型。但多分派,通常会考虑传入参数的实际类型。当然,具体细节在各个语言中还有不同。
举个例子,在Java中,先创建三个类, Fruit, Apple, Banana, 当然,apple,banana,是 Fruit 的子类。
class Fruit{
}
class Apple extends Fruit{
}
class Banana extends Fruit{
}
再创建两个类,People, Boy。Boy是People的子类,并 override People中的三个method.
class People{
public void eat(Fruit f)
{
System.out.println("People eat Fruit");
}
public void eat(Apple f)
{
System.out.println("People eat Apple");
}
public void eat(Banana f)
{
System.out.println("People eat Banana");
}
}
class Boy extends People{
public void eat(Fruit f)
{
System.out.println("Boy eats Fruit");
}
public void eat(Apple f)
{
System.out.println("Boy eats Apple");
}
public void eat(Banana f)
{
System.out.println("Boy eats Banana");
}
再来个main(),看看print 出来的是什么。
public static void main(String[] argu)
{
People boy = new Boy();
Fruit apple = new Apple();
Fruit banana = new Banana();
boy.eat(apple);
boy.eat(banana);
}
结果是:
Boy eats Fruit
Boy eats Fruit
分派发生在此,“boy”被声明为People,但调用的依然是Boy的函数,也就是所谓的多态。但是,虽然传入的参数"apple"的实际类型是Apple,但调用的函数依然是Boy的“ public void eat(Fruit f)”,不是“ public void eat(Apple f)”。运行时,Java参数的实际类型不影响分派,这就是单分派了。