Java多态调用机制理解

首先上难以理解的结论:
* 成员方法(非静态)(运行看子类, 编译看父类):
* 编译时, 如果父类没有, 则编译失败.
* 运行时, 多态调用的方法用的是子类的方法, 如果子类没有则找父类的.
* 成员变量(运行编译看父类):
* 编译时, 如果父类没有, 则编译失败.
* 运行时, 多态调用的成员变量用的是父类的.

再上演示代码:
父类

 public class Person {
        @Override
        public String toString(){
            return "I'm a person.";
        }
        public void eat(){
            System.out.println("Person eat");
        }
        public void speak(){
            System.out.println("Person speak");
        }

    }

子类1: 男孩

public class Boy extends Person{
        @Override
        public String toString(){
            return "I'm a boy";
        }
        @Override
        public void speak(){
            System.out.println("Boy speak");
        }
        public void fight(){
            System.out.println("Boy fight");
        }
    }

子类2: 女孩

public class Girl extends Person{
        @Override
        public String toString(){
            return "I'm a girl";
        }
        @Override
        public void speak(){
            System.out.println("Girl speak");
        }
        public void sing(){
            System.out.println("Girl sing");
        }
    }

测试代码块

public static void main(String[] args) {
    Person boy = new Boy();
    Person girl = new Girl();
    System.out.println(boy);  //==> I'm a boy
    boy.eat(); //==>Person eat
    boy.speak(); //==>Boy speak
    //boy.fight();
    System.out.println(girl);  //==>I'm a girl
    girl.eat();  //==>Person eat
    girl.speak(); //==>Girl speak
    //girl.sing();
}

运行结果
Alt text

理解了上面的代码, 接下来看下上述代码相关的内存模型
Alt text
个人觉得这张图非常清晰.

要深入理解多态, 首先应该有下面相关概念:
1. 我认为Java能够实现多态的重要原因是有方法的动态绑定. 这也就是为什么成员变量没有多态调用一说, 方法却有. 实现动态绑定主要是基于下面说的方法表.
2. 方法表, 简单理解就是方法的列表, 每个类都有对应的方法表, 对于父子类同名方法在方法表中具有相同的索引号(专业点说, 就是具有相同签名的方法,在父类、子类的方法表中具有相同的索引号).
3. 多态调用方法的大致过程: java编译器将java源代码编译成class文件,在编译过程中,会根据静态类型将调用的符号引用写到class文件中。在执行时,JVM根据class文件找到调用方法的符号引用,然后在静态类型的方法表中找到偏移量(我的理解就是索引号),然后根据this指针确定对象的实际类型1,使用实际类型的方法表,偏移量跟静态类型中方法表的偏移量一样,如果在实际类型的方法表中找到该方法,则直接调用,否则,按照继承关系从下往上搜索。

看到这里应该基本对多态调用的机制有了一个大概的认识了, 我这里主要为了做笔记, 如果想进一步深入了解, 请参考下面的博客:
http://www.2cto.com/kf/201603/496508.html


  1. this指针起了关键作用, 它相当于使得子类即使披着父类的妆容, 也不忘自身到底是谁.
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值