重写和重载涉及的 对象静态分派和动态分派,流程分析

对象的静态分派和动态分派

重写属于动态分派,重载属于静态分派

静态分派
public class Main {

    public static class Father{
    }
    public static class Man extends Father{
    }
    public static class Woman extends Father{
    }
    public void say(Father father){
        System.out.println("hello father");
    }
    public void say(Man man){
        System.out.println("hello man");
    }
    public void say(Woman woman){
        System.out.println("hello woman");
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.say(new Father()); //hello father
        main.say(new Man());  //hello man
        main.say(new Woman());//hello woman
        Father father = new Man();
        main.say(father); //hello father
        father = new Woman();
        main.say(father);//hello father
    }
}

上面是一个常规的类重载

 Father father = new Man();

实例化了一个子类Man()对象,并将其给其父类的引用。java多态的体现

Father 称为变量的静态类型,Man称为变量的实际类型

  • 静态类型在编译期就可知,而实际类型在运行期才能确定,编译器并不知道一个对象实际类型时什么,但能确定是方法在需要的是什么类型(编译时就确定)
  • “在重载时是通过静态类型而不是实际类型作为判定依据”–《深入理解java虚拟机》这样说到
  • 我理解成传参传的是静态类型,和实例化的对象(实际类型)是没关系的
Father father = new Man();
main.say(father); //hello father
main.say((Man) father ); //hello man

虽然编译器能确定方法的重载版本,但很多时候,重载的版本不是唯一的,则选取最合适的版本
如下代码,字符c依次向下匹配

  • char - int - long -double向右转换
  • 当都不存在,char自动装箱成Character
  • serializable是Character类实现的一个接口
  • 所有的类的父类都是object
 public static void say(char c){
        System.out.println("char"); //char
    }
    public static void say(int c){
        System.out.println("int"); //int
    }
    public static void say(long c){
        System.out.println("long" +c); //long97
    }
    public static void say(double c){
        System.out.println("double" +c) ;//double97.0
    }
    public static void say(Character c){
        System.out.println("Character" +c);//Charactera
    }
    public static void say(Serializable c){
        System.out.println("Serializable" +c);//Serializablea
    }public static void say(Object c){
        System.out.println("Object" +c);//Objecta
    }
    public static void main(String[] args) {
        Test_1.say('a');
    }
动态分派

java的重写就是动态分派

public static class Father{
        public void say(){
            System.out.println("hello father");
        }
    }
    public static class Man extends Father{
        public void say(){
            System.out.println("hello Man");
        }
    }
    public static class Woman extends Father{
        public void say(){
            System.out.println("hello woman");
        }
    }

    public static void main(String[] args) {
        Father father = new Father();
        father.say(); //hello father
        father = new Man();
        father.say();//hello Man
        father = new Woman();
        father.say();//hello woman
    }

重写匹配方法流程原理

  1. 程序执行到改行,栈顶指向了实例化对象的实际类型,记作C
  2. 如果C中找到与常量中信息相匹配的方法,则进行访问权限校验,如果通过,直接引用,不通过返回IllegalAccessError异常
  3. 否则,按照继承关系从下到上会C的父类进行第二补操作
  4. 如果始终未找到,抛出AbstractMethodsError异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值