JAVA的分派

概念

我们都知道,在一个类或者父子类中,方法是可以同名的,而根据对象的类型,去选择方法具体的执行行为,就叫做分派;

分类

  • 静态分派:静态分派发生在编译器,即根据对象的静态类型选择执行的方法
  • 动态分派:动态分派发生在运行期,即根据对象的动态类型(实际类型)来选择执行的方法

这里就不得不说一下关于对象的类型:

        对象的类型可以分为静态类型和动态类型(实际类型)

        例如 :

Map<String, Object> map = new HashMap<>()

        这里很明显运用了java的父类引用指向子类对象(向上转型),而Map就是这个对象的静态类型,HashMap则是这个对象的动态类型(运行期才实际去执行newInstance方法)

动态分派

首先创建一个父类

public class Pet {

    /**
     * 重写方法
     */
    public void howl(){
        System.out.println("宠物饿了");
    }

}

再创建两个子类重写父类方法

public class Dog extends Pet{

    @Override
    public void howl() {
        System.out.println("汪");
    }
}

public class Cat extends Pet{

    @Override
    public void howl() {
        System.out.println("喵");
    }
}

利用多态实现动态分派

public class DynamicAssignment {

    public static void main(String[] args) {
        Pet dog = new Dog();
        Pet cat = new Cat();
        Pet pet = new Pet();
        dog.howl();
        cat.howl();
        pet.howl();
    }

}

这里可以看到控制台打印的结果

由此可见,同名方法在父子类重写中,执行的分派是动态分派,即根据对象的实际类型(动态类型)来决定执行的是哪个同名方法

静态分派

首先创建执行器

public class Executor {
    public void howl(Pet pet){
        System.out.println("宠物饿了");
    }
    public void howl(Dog dog){
        System.out.println("汪");
    }
    public void howl(Cat cat){
        System.out.println("喵");
    }
}

演示静态分派

public class StaticAssignment {

    public static void main(String[] args) {
        Pet dog = new Dog();
        Pet cat = new Cat();
        Pet pet = new Pet();
        Executor executor = new Executor();
        executor.howl(dog);
        executor.howl(cat);
        executor.howl(pet);
    }

}

这里可以看到控制台打印的结果

由此可见,同一个类中方法的重载,即一个对象在做为入参时去判断对象类型,实际是以这个对象的静态类型为判断依据

 双分派

创建父类

public class Dog extends Pet{

    /**
     * 重写方法
     */
    public void howl(Executor executor){
       executor.howl(this);
    }

}

创建子类

public class Cat extends Pet{

    /**
     * 重写方法
     */
    public void howl(Executor executor){
       executor.howl(this);
    }

}

public class Dog extends Pet{

    /**
     * 重写方法
     */
    public void howl(Executor executor){
       executor.howl(this);
    }

}

创建执行器

public class Executor {
    public void howl(Pet pet){
        System.out.println("宠物饿了");
    }
    public void howl(Dog dog){
        System.out.println("汪");
    }
    public void howl(Cat cat){
        System.out.println("喵");
    }
}

测试双分派

public class DoubleAssignment {
    public static void main(String[] args) {
        Pet pet = new Pet();
        Pet dog = new Cat();
        Pet cat = new Dog();
        Executor executor = new Executor();
        pet.howl(executor);
        dog.howl(executor);
        cat.howl(executor);
    }
}

控制台打印结果

这里其实执行了两次分派,第一次是

pet.howl(executor);
dog.howl(executor);
cat.howl(executor)

这里执行的是动态分派,即根据对象的动态类型选择执行的方法,根据之前的结论,此时动态分派到子类的实现方法中,以cat为例,则执行的是以下代码 

executor.howl(cat);

此时传入的对象类型是实际类型,而不是父类类型,进行第二次分派(静态分派)则执行以下代码

 public void howl(Cat cat){
        System.out.println("喵");
 }

 故控制台打印结果"喵"

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值