面向对象(继承)-->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只能出现在构造器的第一行,二者不可放在同一个构造器中!

 

posted @ 2022-04-21 17:42  羽梦齐飞  阅读(170)  评论(0编辑  收藏  举报