多态的理解

3 阅读3分钟

关于多态的内存理解

  1. 对于new的理解,本质就是在堆区创建内存,然后返回地址,这就是最重要的一步

  2. 然后在java中的引用数据类型,本质就是指针,接收地址的变量定义为引用数据类型,这是学到现在的理解,未来不知道会不会有新的理解

  3. new一个Student之后,在堆区创建了一个空间,首先创建子类就必须先创建父类

  4. 而且new student只创建一个对象,不过这个子类对象包括父类对象的完整内容+子类自己的内容,然后给各自的属性初始化,执行父类的构造器,然后执行子类的构造器,最后把堆地址赋值给栈里的引用变量

  5. Person s = new Student();专业的词汇叫做父类的引用指向了子类,感觉很难理解,但是就是Student这个对象中的Peron的那部分的权限开放,不开放Student中的权限,但是地址一样而已,因为只有一个对象

  6. 接下来讲解一个

    1. 叫做虚方法表的东西,虚方法表属于类,存在方法区,每个类一张,独立分开
    2. 对象存在堆,只存变量和一个指向虚方法表的指针
    3. 父类和子类的方法去数据完全分离
  7. 讲讲方法区和栈和堆,栈存局部变量,堆存new出来的所有对象,方法去存类的信息,虚方法表,堆里的对象通过对象头指针指向方法区里的类信息+虚方法表,栈里面保存堆里的地址,指向堆对象

  8. 对于Person p = new Student(); 运行p.run();是这么调用方法的呢,方法调用运行流程如下,首先通过p找到堆对象,然后读取对象头指针,找到虚方法表的Student类的表

  9. 为什么是Student的虚方法表,因为关键是看谁new的,谁new就是实例化哪个类的对象,new Student();就是实例化Student这个类,数据存放在Student的堆区,对象是什么,就用谁的虚方法表,Person p = new Student();本质理解Person只是一个类型,怎么去看示例化的Student的对象的一个视角而已,类似数据类型而已。

  10. 关键问题,为什么p.run();这是父类本来有点方法,然后用new Student()之后,如果Student子类里面,重写了这个方法就会改变原有的run的实际内容,因为如果没有重写,子类有父类全部方法,显现出来就是保持不变,如果重写了,那么在Student的虚方法表的run()就不是父类的那个run了,调用的时候调用的也是子类的虚方法表,所以改变了,至此基本理解多态的内存理解了

  11. 总结,子类基于父类是继承发展出新的样式,即为多态,更为多的形式和状态,高级机器语言对人类世界的建模也许就是如此,子类总是有变化,基于此而多态