关于多态的内存理解
-
对于new的理解,本质就是在堆区创建内存,然后返回地址,这就是最重要的一步
-
然后在java中的引用数据类型,本质就是指针,接收地址的变量定义为引用数据类型,这是学到现在的理解,未来不知道会不会有新的理解
-
new一个Student之后,在堆区创建了一个空间,首先创建子类就必须先创建父类
-
而且new student只创建一个对象,不过这个子类对象包括父类对象的完整内容+子类自己的内容,然后给各自的属性初始化,执行父类的构造器,然后执行子类的构造器,最后把堆地址赋值给栈里的引用变量
-
Person s = new Student();专业的词汇叫做父类的引用指向了子类,感觉很难理解,但是就是Student这个对象中的Peron的那部分的权限开放,不开放Student中的权限,但是地址一样而已,因为只有一个对象
-
接下来讲解一个
- 叫做虚方法表的东西,虚方法表属于类,存在方法区,每个类一张,独立分开
- 对象存在堆,只存变量和一个指向虚方法表的指针
- 父类和子类的方法去数据完全分离
-
讲讲方法区和栈和堆,栈存局部变量,堆存new出来的所有对象,方法去存类的信息,虚方法表,堆里的对象通过对象头指针指向方法区里的类信息+虚方法表,栈里面保存堆里的地址,指向堆对象
-
对于Person p = new Student(); 运行p.run();是这么调用方法的呢,方法调用运行流程如下,首先通过p找到堆对象,然后读取对象头指针,找到虚方法表的Student类的表
-
为什么是Student的虚方法表,因为关键是看谁new的,谁new就是实例化哪个类的对象,new Student();就是实例化Student这个类,数据存放在Student的堆区,对象是什么,就用谁的虚方法表,Person p = new Student();本质理解Person只是一个类型,怎么去看示例化的Student的对象的一个视角而已,类似数据类型而已。
-
关键问题,为什么p.run();这是父类本来有点方法,然后用new Student()之后,如果Student子类里面,重写了这个方法就会改变原有的run的实际内容,因为如果没有重写,子类有父类全部方法,显现出来就是保持不变,如果重写了,那么在Student的虚方法表的run()就不是父类的那个run了,调用的时候调用的也是子类的虚方法表,所以改变了,至此基本理解多态的内存理解了
-
总结,子类基于父类是继承和发展出新的样式,即为多态,更为多的形式和状态,高级机器语言对人类世界的建模也许就是如此,子类总是有变化,基于此而多态