JavaSE面向对象_继承之方法的重写(覆盖)

什么是方法的重写

当父子类中出现同名成员方法时,再创建子类对象,调用该同名成员方法,结果体现出子类中方法的行为。而且通过在父类中写一个同名方法的Getter方法,调用后仍然体现出子类中方法的行为,这种子类对象只能访问子类行为的现象,称之为“方法的覆盖/重写”(override)。

方法在JVM内存中,不过是一段二进制的指令合集,虽然创建子类对象,由于方法覆盖无法再直接调用父类中的同名方法了,但这个覆盖不是物理意义上的覆盖,而是由于“对象名.成员方法”访问机制的原因,才体现出方法的覆盖。这个父类中的同名方法仍然可以使用super关键字访问到。

 

“对象名.成员方法”的访问和调用机制

实际开发中,相比“对象名.成员变量”的使用方式,使用“对象名.成员方法”来实现操作更加常见。

创建对象的三种方式:

  1. 子类引用指向子类对象
  2. 父类引用指向父类对象
  3. 父类引用指向子类对象

从以下两个角度阐述“对象名.成员方法”的访问机制:

访问的范围

“对象名.成员方法”的访问范围仍然是一个编译上的概念,和“对象名.成员变量”一样,只需要看引用的数据类型即可。在《属性隐藏》的文中已有说明,此处不再赘述。
《继承之属性的隐藏》文章链接

 

调用的结果

  1. 子类引用指向子类对象

    结果体现子类中方法的行为。

  2. 父类引用指向父类对象

    结果体现父类中方法的行为。

  3. 父类引用指向子类对象

    调用父子类同名成员方法,结果体现子类中方法的行为。

小结:“对象名.成员方法”的调用结果,需要根据对象的具体类型来确定。

  • 如果对象是一个子类类型,则不需要考虑引用,一律体现出子类的行为。
  • 如果对象是一个父类类型,那么一定体现出父类的行为。

 

总结

“对象名.成员方法”访问成员方法,访问范围由引用的数据类型来决定,但是方法调用的结果,则是由对象的具体数据类型来决定,是何种对象,就体现出它的行为。

 

“对象名.成员方法”机制的注意事项

  1. 父子类中一旦存在父子类同名的成员方法,那么只要创建子类对象,在任何位置都无法再直接访问到父类成员方法了,这就是继承中的方法的覆盖。
  2. 方法的调用之所以体现为覆盖,这是因为方法的调用结果是根据对象的实际类型决定的,和引用没有任何关系。
  3. 方法的覆盖不是物理意义上的覆盖,只是方法的访问机制决定的,这个父类中的同名方法,仍然可以在有访问权限的前提下使用super关键字访问到。

 

注解 @Override

该注解写在子类重写父类方法的上面,用来标记这个方法是重写自父类的方法。如果该注解和方法的语法都没有报错,说明这个方法是重写自父类的。

所以,在写代码时要求:只要是该方法重写自父类,就一定要加注解,不写注解就重写方法,是错误的做法。

写注解的原因(好处)

  1. 注解标记后不报错,该方法就能够认定是重写自父类的,避免错误的认知。
  2. 增加代码可读型。

 

方法重写的语法

首先,方法的重写(覆盖)是针对以下这种普通成员方法的

[访问权限修饰符] 返回值类型 方法名(形参列表){
    // 方法体
}

注:成员方法没有static修饰。

 

开发中重写父类方法的两种方式

  1. 如果明确知道父类中方法的方法名,可以在子类类体中直接写这个方法名,IDEA会给出补全提示,然后默认第一个回车即可。
  2. 如果不知道要重写父类哪个方法,需要先查看父类方法再决定,可以使用快捷键“alt+insert”,选择重写方法的选项,就可以查看所有父类(直接或间接)中可被重写的方法,选择之后会快速生成方法重写的结构。

 

方法重写语法

[访问权限修饰符] 返回值类型 方法名(形参列表){
    // 方法体
}

语法解释(子类重写父类方法):

  1. 访问权限修饰符是可以修改的,但是只能往更宽松的访问权限去改,子类重写分方法不能比父类方法的访问权限更严格,当然保持一致也可以。
  2. 返回值类型实际上是可以修改的,但是这个修改不是任意改的。
  3. 方法名必须严格保持一致,不能改。
  4. 形参列表必须严格保持一致,不能改。
  5. 子类重写的方法体没有要求,随便写。

 

方法重写的注意事项

这些方法不能被重写:

  1. 私有方法:私有方法虽然能继承,但是没有访问权限。
  2. 静态方法:静态成员属于类,不能被继承,更不能重写。如果子类没有,就共用父类的,如果子类中有同名的,则父子各用各的。
  3. 构造方法:构造方法不能被继承,同样不能被重写。

 

辨析方法重载(overload)和方法重写(override)

不同点:

  1. 发生的类

    方法重载:必须发生在同一个类中。

    方法重写:必须发生在继承中的父子类中,必须要有两个类。

  2. 访问权限修饰符

    方法重载:不关心访问权限修饰符。

    方法重写:子类中重写父类方法,访问权限修饰符必须更宽松或保持一致,不能更严格。

  3. 返回值类型

    方法重载:不关心返回值类型。

    方法重写:有要求。

  4. 形参列表

    方法重载:要求形参列表必须不一致。(方法名相同,形参列表不同,是构造方法重载的唯一条件)

    方法重写:要求形参列表必须一致。
     

相同点:

  1. 方法名:都要求方法名相同。
  2. 方法体:都不做要求,随便写。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值