• Java 多态


    1. 无论向上转型还是向下转型,都需要有继承关系,否则编译器报错!

    向上转型:子类型转向父类(自动类型转换) 

    向下转型:父类型转向子类(强制类型转换,需要加强制类型转换符)

    2. 什么是多态?

    多态是同一个行为具有多个不同表现状态的能力。

    多种状态,编译时是一种状态,运行时是另一种状态。

    编译时,是静态绑定。编译器去找父类Animal中的move()方法,找到了,则编译通过,静态绑定成功;

    运行时,是动态绑定。由于实际在堆内存中创建的对象是Cat对象,所以实际执行时会动态执行Cat的move()方法。(动态绑定是Java的默认行为,相当于C++的虚函数

    上述过程,就是父类型引用指向子类型对象,向上转型,产生了多种形态(编译阶段绑定父类,运行阶段绑定子类)。

    注:如果调用的是子类独有的方法,比如catch(),则不会通过编译,因为无法在父类中找到该方法。

    3. 什么时候必须使用向下转型?

    想要调用的方法是子类特有的,则需要强制类型转换(向下转型)。

    向下转型有风险!如果失败,会抛出java.lang.ClassCastException

    比如堆内存中创建的是Bird对象,用父类Animal类型引用a1接收,此时执行向下转型到Cat,会出错。

    Animal a1=new Bird();
    Cat c1=(Cat)a1;//出错

    避免异常发生?使用instanceof来判断一个对象是不是属于该类型(运行阶段动态判断)

    if(a1 instanceof Cat){//返回true或false
        Cat c1=(Cat)a1;
    }

    所以每当向下转型时,都要用instanceof进行类型判断,来避免ClassCastException。

    4. JVM中多态运行情况

    当执行 invokevirtual 指令(JVM方法调用指令,用于调用对象的实例方法)时,

    (1) 先通过栈帧中的对象引用找到对象

    (2) 分析对象头,找到对象的实际 Class

    (3) Class 结构中有 vtable(标明这个类有几个方法),它在类加载的链接阶段就已经根据方法的重写规则生成好了

    (4) 查表得到方法的具体地址

    (5) 执行方法的字节码

     

  • 相关阅读:
    IBM Minus One(water)
    约瑟夫问题的循环链表实现
    双向链表(差不多)
    单向链表的建立,插入,删除(复习一下)
    找新朋友(欧拉函数)
    验证角谷猜想(hd1279)
    Wolf and Rabbit(gcd)
    Big Number(大数)
    字串数(高精度组合数)
    寻找素数对(hd1262)
  • 原文地址:https://www.cnblogs.com/Kinghao0319/p/14405806.html
Copyright © 2020-2023  润新知