【Java】弄清方法重写,看这一篇就够了|由浅入深,保姆级讲解

news/2024/11/9 0:48:59/

在这里插入图片描述

  • 作者:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:算法、数据结构、Java等相关知识。
  • 博主主页: @是瑶瑶子啦
  • 所属专栏: Java岛冒险记【从小白到大佬之路】;该专栏专注于Java相关知识,持续更新,每一篇内容优质,浅显易懂,不失深度!
  • 近期目标:写好专栏的每一篇文章

在这里插入图片描述

前言:

在上一篇【Java】还不理解继承?一篇文章看懂继承|继承入门我们很好的了解、学习了继承的基础知识和细节。我们讲到继承的其中一个特性就是:子类继承父类,可以重写从父类继承过来的实例方法。
那么,到底什么是重写、又该如何重写、重写的细节、具体意义、功能等等,将在此篇着重展开.
【Tips】:重写是建立在继承基础之上。子类继承了父类的非static和static属性以及方法,但是只能重写从父类继承过来的实例方法。静态属性、静态方法和非静态的属性都可以被继承和隐藏(hide),而不能够被重写!(关于隐藏,我们后期再讲)

目录

  • 前言:
  • Part1:基本介绍
  • Part2:重写的意义/功能
    • 2.1:访问方法(动态绑定)
    • 2.2:直接意义:
  • Part3:重写的细节&注意事项
  • Part4:总结:重写&重载对比

Part1:基本介绍

方法重写(Override),又叫方法覆盖。是指子类继承了父类非private方法,若在子类中再次声明&定义一个方法名方法参数返回类型和父类一样的方法时,我们就称:子类重写/覆盖/覆写/Override了父类的这个方法。

eg:

public class Animal {private int age;private String name;public void eat() {System.out.println("吃东西ing");}//下面是两个属性的构造器public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
public class Cat extends Animal {@Overridepublic void eat() {System.out.println("吃小鱼儿ing");}public void climb(){System.out.println("猫咪爬树");
}

可以看到:Cat类有两个方法:

  • eat():此方法是在继承父类方法的基础上,重写父类的eat()方法
  • climb():此方法是Cat类自己单独声明&实现的,与父类无任何关系

重写好处

从子类的视角来看:重写可以满足在子类继承父类方法的同时,但又不受父类的方法实现的严格限制,同时拥有自己特有的方法实现!两全其美(比如eat都是吃,每个动物都有这个行为,但是吃的具体食物不同,所以实际的方法实现并不同)。

对重写的理解
更通俗来说,当子类继承父类时,你觉得父类的方法不能满足需求,就重写一下(当然你也可以不重写,这完全取决于子类.这点是和抽象类以及接口不同的地方)。

  • 官方解释:

在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。 如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。

Part2:重写的意义/功能

关于重写的好处、理解,我们心里都有数了。那么,重写给我们带来了什么呢?

2.1:访问方法(动态绑定)

提到重写,就肯定会提到动态绑定,它们两个是分不开的。

我们先来谈谈对重写动态绑定的理解:

  • 重写:方法重写,是Java在语法层次上的规则。
  • 动态绑定:方法重写这个语法规则的底层实现(动态绑定机制:调用对象方法,方法会与运行类型绑定,调用属性与编译类型有关)

总之,重写和动态绑定本质相同侧重点不同。这里我们着重谈谈语法层次上的重写(动态绑定会在后期讲解继承背后的原理中着重介绍)


首先,我们要清楚继承的本质是:查找关系。即:子类对象访问属性/方法时,会逐级向上查找,直到找到合适的属性/方法,则访问/调用。

当父类引用指向子类对象时,用父类引用去调用父类中方法时,是这样的流程:(这里还是以上面代码举例)

  • 类之间的关系:
Inheritance
Inheritance
Animal
-int age
-String name
+getAge() : int
+setAge() : void
+getName() : String
+setName() : void
Dog
Cat
+climb() : void
  • 父类引用指向子类对象,调用方法时的流程:
Animal animal01 = new Cat();
animal01.eat();
Yes
No
Start:animal01.eat
eat方法被实际运行类型/Cat重写了嘛?
调用子类Cat中eat方法
调用编译类型/Animal中的eat方法

【重写功能】:父类引用指向子类对象,父类引用调用方法时,若方法被重写,会优先调用子类重写方法!

综上可以看出多态+重写+继承(重写就是建立在继承之上的)的语法规则,带来了非常明显的一个好处:方便管理子类对象(只需要知道对象的父类型,不用一个个去搞清楚运行类型,再根据运行类型调用其方法)

为什么这么说呢:

public class Main {public static void main(String[] args) {Animal animal01 = new Cat();Animal animal02 = new Dog();Animal[] animals = {animal01, animal02};for (Animal animal : animals) {animal.eat();}}
}

在这里插入图片描述

2.2:直接意义:

增强类(指父类)的重用性、复用性、扩展性

Part3:重写的细节&注意事项

  • 子类方法重写父类,必须保证子类方法的权限大于父类的权限or和父类权限相同(private < 默认(不写)< protected < public),才可以覆盖
    理解:保证重写之后一定会优先调用到子类的方法,如果缩小访问权限继承就没有意义。(继承的本质就是查找关系,优先使用子类)
  • 不能用静态覆盖非静态,静态只能覆盖静态:如果父类中方法是不是static,那么子类覆盖父类时不能将被覆盖的方法写出static
  • 子类重写方法的返回值与父类完全一致或者是父类方法返回值的子类
  • 方法签名必须完全一致(方法签名=方法名+参数列表)
  • 子类异常不能大于父类异常

Part4:总结:重写&重载对比

关于重载,已在【Java】保姆级讲解|从0到1学会方法及方法重载 ( 入门,包懂)详细解释。这里我们将它们进行对比。

区别点重写(Override)重载(Overload)
概念方法名相同,参数列表不同(参数类型、参数个数)返回类型、方法名、参数列表相同
发生范围父子类(不一定是直接父类)本类
访问修饰符子类重写方法的访问权限必须大于or等于父类方法的权限无要求
本质利用栈结构,实现方法覆盖(后进,先出)同名方法,不同访问(由编译器指定,自动匹配

在这里插入图片描述

  • Java岛冒险记【从小白到大佬之路】
  • LeetCode每日一题–进击大厂
  • 算法

http://www.ppmy.cn/news/34592.html

相关文章

在 AI 上训练 AI:ChatGPT 上训练另一种机器学习模型

ChatGPT 可以像 Linux 终端一样运行&#xff0c;并在给出以下提示时返回执行结果。下面我来带大家操作起来。 文章目录终端操作训练机器学习模型镜像演示终端操作 输入&#xff1a;I want you to act as a Linux terminal. I will type commands and you will reply with what…

课设-机器学习课设-实现新闻分类

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;课设-机器学习 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;…

基于OpenCV的人脸识别

目录 &#x1f969; 前言 &#x1f356; 环境使用 &#x1f356; 模块使用 &#x1f356; 模块介绍 &#x1f356; 模块安装问题: &#x1f969; OpenCV 简介 &#x1f356; 安装 OpenCV 模块 &#x1f969; OpenCV 基本使用 &#x1f356; 读取图片 &#x1f357; 【…

MHA实现mysql数据库高可用

目录 MHA原理 MHA工具包 MHA实现mysql高可用实战 MHA原理 ①MHA利用 SELECT 1 As Value 指令判断master服务器的健康性,一旦master 宕机,MHA 从宕机崩溃的master保存二进制日志事件&#xff08;binlog events&#xff09; ②识别含有最新更新的slave ③应用差异的中继日志&…

【前缀和】

前缀和前缀和子矩阵的和结语前缀和 输入一个长度为 n的整数序列。 接下来再输入 m 个询问&#xff0c;每个询问输入一对 l,r 对于每个询问&#xff0c;输出原序列中从第 l 个数到第 r个数的和。 输入格式第一行包含两个整数 n和 m 第二行包含 n个整数&#xff0c;表示整数…

ES-笔记

1、索引 查看所有索引 GET /_cat/indices?v健康状况 GET _cluster/health GET _cluster/health?levelindices分词器 POST _analyze {"analyzer": "ik_max_word","text": "四川森森管理公司" }索引数据拷贝 POST _reindex {&quo…

java学习笔记——抽象类

2.1 概述 由来 父类中的方法&#xff0c;被他的子类们重写&#xff0c;子类各自的实现都不尽相同。那么父类的方法声明和方法主体&#xff0c;只有声明还有意义&#xff0c;而方法主体则没有存在的意义了。我们把没有主体的方法称为抽象方法。java语法规定&#xff0c;包含抽象…

Linux命令运行原理shell和bash

目录前言什么是shell,什么是bash?ls -l 执行过程前言 学习操作系统的过程中我们经常在自己的shell中执行一些Linux命令&#xff0c;那么当我们输入一个类似于 ls -a 这样的命令式&#xff0c;发生了什么&#xff1f; 换句话说&#xff0c;从我们在shell中输入ls -a 按下回车…