文章目录
什么是方法的重写
当父子类中出现同名成员方法时,再创建子类对象,调用该同名成员方法,结果体现出子类中方法的行为。而且通过在父类中写一个同名方法的Getter方法,调用后仍然体现出子类中方法的行为,这种子类对象只能访问子类行为的现象,称之为“方法的覆盖/重写”(override)。
方法在JVM内存中,不过是一段二进制的指令合集,虽然创建子类对象,由于方法覆盖无法再直接调用父类中的同名方法了,但这个覆盖不是物理意义上的覆盖,而是由于“对象名.成员方法”访问机制的原因,才体现出方法的覆盖。这个父类中的同名方法仍然可以使用super关键字访问到。
“对象名.成员方法”的访问和调用机制
实际开发中,相比“对象名.成员变量”的使用方式,使用“对象名.成员方法”来实现操作更加常见。
创建对象的三种方式:
- 子类引用指向子类对象
- 父类引用指向父类对象
- 父类引用指向子类对象
从以下两个角度阐述“对象名.成员方法”的访问机制:
访问的范围
“对象名.成员方法”的访问范围仍然是一个编译上的概念,和“对象名.成员变量”一样,只需要看引用的数据类型即可。在《属性隐藏》的文中已有说明,此处不再赘述。
《继承之属性的隐藏》文章链接
调用的结果
-
子类引用指向子类对象
结果体现子类中方法的行为。
-
父类引用指向父类对象
结果体现父类中方法的行为。
-
父类引用指向子类对象
调用父子类同名成员方法,结果体现子类中方法的行为。
小结:“对象名.成员方法”的调用结果,需要根据对象的具体类型来确定。
- 如果对象是一个子类类型,则不需要考虑引用,一律体现出子类的行为。
- 如果对象是一个父类类型,那么一定体现出父类的行为。
总结
“对象名.成员方法”访问成员方法,访问范围由引用的数据类型来决定,但是方法调用的结果,则是由对象的具体数据类型来决定,是何种对象,就体现出它的行为。
“对象名.成员方法”机制的注意事项
- 父子类中一旦存在父子类同名的成员方法,那么只要创建子类对象,在任何位置都无法再直接访问到父类成员方法了,这就是继承中的方法的覆盖。
- 方法的调用之所以体现为覆盖,这是因为方法的调用结果是根据对象的实际类型决定的,和引用没有任何关系。
- 方法的覆盖不是物理意义上的覆盖,只是方法的访问机制决定的,这个父类中的同名方法,仍然可以在有访问权限的前提下使用super关键字访问到。
注解 @Override
该注解写在子类重写父类方法的上面,用来标记这个方法是重写自父类的方法。如果该注解和方法的语法都没有报错,说明这个方法是重写自父类的。
所以,在写代码时要求:只要是该方法重写自父类,就一定要加注解,不写注解就重写方法,是错误的做法。
写注解的原因(好处)
- 注解标记后不报错,该方法就能够认定是重写自父类的,避免错误的认知。
- 增加代码可读型。
方法重写的语法
首先,方法的重写(覆盖)是针对以下这种普通成员方法的
[访问权限修饰符] 返回值类型 方法名(形参列表){
// 方法体
}
注:成员方法没有static修饰。
开发中重写父类方法的两种方式
- 如果明确知道父类中方法的方法名,可以在子类类体中直接写这个方法名,IDEA会给出补全提示,然后默认第一个回车即可。
- 如果不知道要重写父类哪个方法,需要先查看父类方法再决定,可以使用快捷键“alt+insert”,选择重写方法的选项,就可以查看所有父类(直接或间接)中可被重写的方法,选择之后会快速生成方法重写的结构。
方法重写语法
[访问权限修饰符] 返回值类型 方法名(形参列表){
// 方法体
}
语法解释(子类重写父类方法):
- 访问权限修饰符是可以修改的,但是只能往更宽松的访问权限去改,子类重写分方法不能比父类方法的访问权限更严格,当然保持一致也可以。
- 返回值类型实际上是可以修改的,但是这个修改不是任意改的。
- 方法名必须严格保持一致,不能改。
- 形参列表必须严格保持一致,不能改。
- 子类重写的方法体没有要求,随便写。
方法重写的注意事项
这些方法不能被重写:
- 私有方法:私有方法虽然能继承,但是没有访问权限。
- 静态方法:静态成员属于类,不能被继承,更不能重写。如果子类没有,就共用父类的,如果子类中有同名的,则父子各用各的。
- 构造方法:构造方法不能被继承,同样不能被重写。
辨析方法重载(overload)和方法重写(override)
不同点:
-
发生的类
方法重载:必须发生在同一个类中。
方法重写:必须发生在继承中的父子类中,必须要有两个类。
-
访问权限修饰符
方法重载:不关心访问权限修饰符。
方法重写:子类中重写父类方法,访问权限修饰符必须更宽松或保持一致,不能更严格。
-
返回值类型
方法重载:不关心返回值类型。
方法重写:有要求。
-
形参列表
方法重载:要求形参列表必须不一致。(方法名相同,形参列表不同,是构造方法重载的唯一条件)
方法重写:要求形参列表必须一致。
相同点:
- 方法名:都要求方法名相同。
- 方法体:都不做要求,随便写。