java基础巩固-宇宙第一AiYWM:为了维持生计,JavaSE基础【多态(静态分派、动态分派)】整起

本文讲解了面向对象的三大特征——封装、继承和多态,并通过实例展示了Java中的静态分派(依赖于编译时类型)和动态分派(依赖于运行时类型)在方法重载中的应用。通过静态分派的StaticDispatch和动态分派的DynamicDispatcher类,对比了两者在方法调用时的不同行为。
摘要由CSDN通过智能技术生成

面试官:来说说,啥叫个面向对象的三大特征:
我:封装、继承、多态

面试官:完了?
我:完了

害怕不,害怕就要提前多看看多学学喽

/**
 * Copyright (c) 2013-Now http://AIminminAI.com All rights reserved.
 */

/**
 * 方法静态分派演示
 * @author HHB
 * @version 2022年4月15日
 */
public class StaticDispatch {
	/**
	 * 定义一个静态内部抽象类
	 * 
	 * @author HHB
	 * @version 2022年4月15日
	 */
	static abstract class Apple {

	}

	static class BigApple extends Apple {

	}

	static class SmallApple extends Apple {

	}

	/**
	 * 三个重载的方法
	 * @param apple
	 * @author HHB
	 */
	public void eatApple(Apple apple) {
		System.out.println("eat apple");
	}

	public void eatApple(BigApple apple) {
		System.out.println("eat bigApple");
	}

	public void eatApple(SmallApple apple) {
		System.out.println("eat smallApple");
	}

	public static void main(String[] args) {
		Apple bigApple = new BigApple();
		Apple samllApple = new SmallApple();
		StaticDispatch staticDispatch = new StaticDispatch();
		staticDispatch.eatApple(bigApple);
		staticDispatch.eatApple(samllApple);
	}
}

运行结果,咋是这呢?对我这种菜鸟来说,为啥嘞
在这里插入图片描述
挖一挖呗:
在这里插入图片描述
首先说,啥叫静态类型发生变化或者动态类型发生变化呢:在这里插入图片描述
虚拟机(准确说是编译器)在重载时是通过传进来的参数的静态类型(静态类型是编译器可知的)而不是实际类型作为判定依据的,也就是说Javac编译器会根据参数的静态类型决定使用哪个重载版本,这里静态类型的重载版本不就只有打印eat apple那一个嘛,所以选了这个eatApple(Apple apple)进行调用并把这个方法的符号引用写到main()方法中的两条invokevirtual指令的参数中

  • 静态分派:上面这种依靠静态类型来定位方法执行版本的分派动作叫做静态分派。静态分派发生在编译阶段(啥东西,从哪里蹦出来一个分派,分派和解析是在不同层次上去筛选、确定目标方法的过程~解析看这一篇
    • 静态分派的典型应用就是方法重载
/**
 * Copyright (c) 2013-Now http://AIminminAI.com All rights reserved.
 */

/**
 * 
 * @author HHB
 * @version 2022年4月15日
 */
public class DynamicDispatcher {
	static abstract class Apple{
		protected abstract void eatApple();
	}
	
	static class BigApple extends Apple{
		@Override
		protected void eatApple() {
			System.out.println("eat bigApple");
		}
	}
	
	static class SmallApple extends Apple{
		@Override
		protected void eatApple() {
			System.out.println("eat samllApple");
		}
	}
	
	public static void main(String[] args) {
		Apple bigApple = new BigApple();
		Apple smallApple = new SmallApple();
		bigApple.eatApple();
		smallApple.eatApple();
		bigApple = new SmallApple();
		bigApple.eatApple();
	}
}

这个运行结果就很和善了嘛
在这里插入图片描述
那咱们和上面静态分派一样,可不得再看看到底调用的是哪个方法呢?上面咱们静态分派时传入的两个实际类型不一样,那这个呢?
在这里插入图片描述

  • 动态分派:这里其实是两次方法调用中的invokevirtual指令**把常量池中的类方法符号引用解析到了不同的直接引用(也就是句柄嘛,对象的直接引用哦)上,这也是Java中方法重写的本质~直接引用看这里。咱们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分配**

巨人的肩膀:
深入理解Java虚拟机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值