面向对象(继承)-->2
定义一个父类:
定义一个学生类(Student)继承该类(Role):
测试类:
继承的内存图原理及实现机制:
问题一:子类是否可以继承父类的构造器?
不能,因为类是自带构造器的,构造器的作用是生产对象,父类的构造器用于生产父类对象,子类构造器用于生产子类对象,两者互不干扰,没有半毛钱关系。
问题二:子类是否可以继承父类的私有成员?
这是一个有争议的知识点,个人看法:可以,但是不能直接访问。如下图所示的继承关系,比如我们虽然通过private修饰了父类的成员变量和成员方法,但我们可以对外提供public修饰的方法。这点类似于封装的思想。
问题三:子类是否可以继承父类的静态成员?
这也是一个有争议的知识点,个人看法:不可以,静态成员隶属于类,在程序运行时只会被加载一次,也就是说它只有一份,属于某一个类本身。但又因为静态成员是被共享访问的,所以子类可以访问父类的静态成员。
综上所述,能继承 != 能访问,能访问 != 继承。
Java只支持单继承,不支持多继承的原因(二义性问题):
继承后成员变量,成员方法的访问特点:
运行结果:
不难看出:在子类方法中访问成员变量和成员方法时,满足就近原则。查找过程:子类局部 --> 子类成员 --> 父类成员 (父类成员也没有则报错)!如果出现了重名的方法,会优先使用子类的,如果一定要在子类中访问父类成员,就需要借助 super 关键字(使用范围与 this 相同,即只能在方法中使用),格式:super.父类成员变量/方法。并且,当子类名与父类名同名时,使用子类的方法(则该方法称之为方法重写)。
方法重写:
继承后构造器的特点:
子类中所有的构造器都会先访问父类中无参的构造器,在执行自己,原因就是子类构造器的第一行会默认带上一行代码:super(),他会先调用父类的无参数构造器
至此,我们也可以解开这样的疑惑:在学习面向对象构造器的时候,为什么一个实体类有参数构造器可有可无,但无参数构造器就必须要有呢?,并且一旦提供了有参数构造器,就必须提供无参数构造器。
因为在正常情况下,一个类如果被其他类继承了,那么它就会成为一个父类,子类构造器里边会自动调用父类的无参数构造器[子类第一行的代码默认为:super()],如果父类不提供无参数构造器,则程序报错!
关键字 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
this | this.成员变量 | this.成员方法 | this(...) |
访问本类成员变量 | 访问本类成员方法 | 访问本类构造器 | |
super | super.成员变量 | super.成员方法 | super(...) |
访问父类成员变量 | 访问父类成员方法 | 访问父类构造器 |
补充:this访问本类构造器(兄弟构造器)
案例:在学生信息管理系统中,如果一个学生提供了姓名和国家,则使用该生提供的信息,如果没有提供则默认国家为中国。
那么问题来了,我们之前说过子类的构造器会在第一行使用super()自动调用父类的无参数构造器,图下的代码还会调用父类的无参数构造器吗?
答案是否定的,可以看到,当我们手动在该构造器里边的第一行加上super()时,程序报错了,原因是什么呢?
原因就是子类this会调用本类的其他构造器,而其他构造器会通过super()调用父类的构造器,也就是说,本类的其他构造器最终还是会调用父类的无参数构造器。
所以:this和super只能出现在构造器的第一行,二者不可放在同一个构造器中!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix