Java基础——面向对象进阶复习知识点4
一、继承
1.1 什么是继承
面向对象三大特征之一,之前已经学习完了封装。
有了封装之后,我们就可以把一些零散的数据还有一些行为封装成一个整体,这个整体就是我们所说的对象。有了封装之后,我们就可以直接通过set/get方法调用相应的行为,而不需要在独自一一创建方法,传入很多参数等复杂操作。
但是有新的问题:当JavaBean类越来越多的时候,同样的有许多相同的属性和行为方法。重复的代码就有很多,该如何解决这些重复的代码?
不难想到一种方法,将重复代码再次封装成一个类,把各自对象单独的方法和属性独自封装在各自的对象中。Java正是这么解决的,如图,根据实际的意义我们可以将此类名称之为person。
这种关系,我们就称之为继承。
1.2 继承学习什么要点
①如何自己设计
②如何使用别人的
1.2.1 自己设计
1.2.1.1 什么时候用到继承?
1.2.2 使用别人的继续
1.2.2.1 继承的特点
C++中是支持多继承的,为什么Java中不支持多继承?
在调用父类方法时,因为多个继承就不知道到底调用谁的方法。
所有的子类最终都是object的子类,如果你的类是由归属的父类那么虚拟机就不会给你自动调用包含于object,反之则会。
注意:子类1是不能调用父类2的!
1.2.2.2 子类到底能继承父类中的哪些内容?
内存角度:
父类中类的成员:构造方法、成员变量、成员方法。
对于构造方法来说:不管什么样的修饰符进行修饰,子类都是没有继承下来的。
对于成员变量来说:不管什么样的修饰符进行修饰,子类都是可以继续下来的。
继承:是子类中没有,父类中的数据拷贝一份拿过来,区别于调用。也就是说,我拿过来了,但是我调用不了。
对于成员方法来说:不同修饰符影响着是否可以继承。
关于构造方法是否可以被继承?
反过来推导,继承相当于拷贝一份构造方法到子类,但是会发现子类的方法名跟类名不一致,很明显的错误,所以是肯定不可以的。
关于成员变量是否可以被继承?
继承的内存图:
首先把相应的TestStudent.class字节码文件 加载到方法区,程序从main()方法进入,main()方法进入到栈内存;
开始执行第一行代码:Zi z = new Zi(); 该步会将Zi对应的字节码文件同样的加载到方法区,同时因为extends的关键字存在,会把父类Fu的字节码文件同样的加载到方法区。
在main()方法开辟的空间中会有一块只能被Zi类数据的变量名叫Z的空间,存储的是new()方法在堆内存中开辟空间的地址值001。
因为是继承,所以会有两块空间,分别存储对应的数据。同时会自动赋值默认初始值。
要是加上修饰符是怎么样的?
因为别private修饰,所以找到了成员变量但是赋值失败。代码报错。
关于成员方法是否可以被继续?
虚拟机会创建一个虚方法表,会把经常使用的方法存放到虚方法表中。
三个条件:①不能被private修饰;②不能被static修饰;③不能被final修饰。
只要满足以上三个要求,该方法称之为:虚方法。
这样做的目的:可以显著的提高性能,如果只能是一级一级从父类开始找相应的方法,当层级数太多时会非常影响虚拟机的性能。
这样的话,在我们调用虚方法时,从A类中只需要找虚方法表即可找到对应的类中的虚方法。其他的非虚方法还是只能层级查找。
结论:只有父类中的虚方法才能被子类继承。
内存图:
跟上述分析一直,区别在于多一个虚方法表的加载。
调用方法时,虚拟机会自动判断是否为虚方法。
声明:
以上均来源于B站@ITheima的教学内容!!!
本人跟着视频内容学习,整理知识引用