分派
变量被声明时的类型叫做静态类型,而变量所引用的类型叫做实际类型。如Map m=new HashMap(),m变量的静态类型是Map,实际类型是HashMap。根据对象的类型进行选择,就是分派。
动态分派
动态分派发生在运行期,分派会动态置换某个方法,如重写就是动态分派。
public class Animal {
public void execute(){
System.out.println("animal");
}
}
class Dog extends Animal{
@Override
public void execute() {
System.out.println("dog");
}
}
class Cat extends Animal{
@Override
public void execute() {
System.out.println("cat");
}
}
class Client{
public static void main(String[] args) {
Animal a1=new Animal();
Animal a=new Dog();
Animal b=new Cat();
a1.execute();
a.execute();
b.execute();
}
}
以上代码的运行结果很明了,这里会动态的置换掉execute方法,从而输出三个不同的值。
静态分派
静态分派发生在编译期,分派根据静态类型进行分派,如重载就是静态分派。
public class Animal {}
class Dog extends Animal{}
class Cat extends Animal{}
class Execute{
public void execute(Animal a){
System.out.println("animal");
}
public void execute(Dog a){
System.out.println("dog");
}
public void execute(Cat a){
System.out.println("cat");
}
}
class Client{
public static void main(String[] args) {
Animal a=new Animal();
Animal b=new Dog();
Animal c=new Cat();
Execute execute=new Execute();
execute.execute(a);
execute.execute(b);
execute.execute(c);
//输出结果
//animal
//animal
//animal
}
}
以上代码的运行输出是三个相同的值animal。原因就是重载的方法是根据静态类型,Animal,进行的,而且这个分派过程在编译期就完成了。
双分派
双分派就是在第一次的分派的基础上,进行第二次的分派。
public class Animal {
public void accetp(Execute execute){
execute.execute(this);
}
}
class Dog extends Animal {
public void accetp(Execute execute){
execute.execute(this);
}
}
class Cat extends Animal {
public void accetp(Execute execute){
execute.execute(this);
}
}
class Execute{
public void execute(Animal a){
System.out.println("animal");
}
public void execute(Dog a){
System.out.println("dog");
}
public void execute(Cat a){
System.out.println("cat");
}
}
class Clients{
public static void main(String[] args) {
Animal a=new Animal();
Animal b=new Dog();
Animal c=new Cat();
Execute execute=new Execute();
a.accetp(execute);
b.accetp(execute);
c.accetp(execute);
}
}
如上面的代码,Execute对象作为参数传递给Animal类型的a,b,c对象,这里的b和c对象的accetp方法是重写的,所以是一次动态分派,也就是执行实际类型中的方法,这时将this对象传递进去完成第二次分派,而传递的是当前的对象不是父类型的对象(对于b c来说),所以执行的是对应的实际类型的方法。最后输出三个不同的值。