Java学习18-- Override方法重写【★】

重点:super类 & 方法重写

★看不明白多看几遍,记住static优先级>>高于override

重写Override methods★

重写Override:child class可以覆盖father class中的method,即子类child class和父类father class有相同名称、相同参数列表和相同返回类型的方法method。当子类对象调用这个方法method时,会执行子类中的具体语句,而不是父类中的具体语句。

必须有继承关系,一般是“子类"重写"父类"的method(同名称,内芯不同)。重写是子类对父类那些允许访问的method实现过程进行重新编写(private method不行), 返回值和形参都不能改变。即外壳不变,核心重写!
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以尽量用大的,但不能进一步写小了 Public > Protected > Default > Private
4.抛出的异常: 范围,可以被缩小,但不能扩大:比如ClassNotFoundException(类找不到错误,范围相对小) --> Exception(范围相对大)

重写,子类的method名和父类method名必须要一致,方法体内部可以不同

为什么要重写
1.父类的功能,子类不一定全需要,或者不一定满足!
在IDEA里面,可以用快捷键Alt + Insert: 选择override,快速让系统帮你在子类里面抓出父类的一个功能进行override即重新覆盖写,一般写好之后系统在子类的代码里会加进一个@Override标志
类似这样

@Override
public void test() {super();//然后用户自行删除或者更改这一句的内容}
}

@Override是伪代码,表示重写(当然不写这个标志也可以),不过写上有如下好处:
1、可以当注释用,方便阅读;
2、编译器可以给你验证@Override下面的方法名是否是父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的method方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的method方法。

举例:在重写父类的onCreate时,在方法前面加上@Override 系统可以帮你检查method方法的正确性。

@Override
public void onCreate(Bundle savedInstanceState){…….}

以上这种写法是正确的,如果你写成下面这样:

@Override
public void oncreate(Bundle savedInstanceState)
{…….}

编译器会报如下错误:
The method oncreate(Bundle) of type HelloWorld must override or implement a supertype method,以确保你正确的重写onCreate方法(注意oncreate大小写写错了,应该为onCreate)。而如果你不加@Override,则编译器将不会检测出错误,而是会认为你为子类定义了一个新方法叫做小写的oncreate

思考:同样是父类子类调用重名的method,method定义时候加了static和没加static,在结果上有什么区别?
小tips: static优先级>>高于Override

//注意: method定义没有加static关键字(可以考虑Override)
//比如fatherclass F= new childclass ()这样的语句,需要读完整句,到右侧才算结束
//符合Override,所以第一种fatherclass A = new childclass ();最后用的是childclass
//符合Override,第二种childclass B = new childclass ();最后用的是childclass父类名 a = new 子类名 ();
a.non-method1();子类名 b = new 子类名 ();
b.non-method1();public class 父类名 {
public void non-method1(){do sth non static method1};
}public class 子类名 {
public void non-method1(){do sth Override non static method1};
}

运行结果:

do sth Override non static method1
do sth Override non static method1
//注意:  method定义有static关键字(因为static优先级高,肯定不会Override了)
//第一种fatherclass A = new childclass ();A直接用左侧fatherclass
//第二种childclass B = new childclass ();B直接用左侧childclass父类名 a = new 子类名 ();
a.method3();子类名 b = new 子类名 ();
b.method3();public class 父类名 {
public static void sti_method3(){do sth method3};
}@Override
public class 子类名 {
public static void sti_method3(){do sth Override method3};
}

运行结果

do sth method3
do sth Override method3

运行分析:
如果程序写了public static void method,加了static关键字,由于JAVA内存中static和class部分会一起先加载且仅加载一次,static优先级高于Override,不用考虑重写的问题,父类名 a = new 子类名 ();这样的语句a直接取父类名。

而如果method没有static关键字,那么考虑Override,这时候属于子类重写了父类的方法,对于语句F_class A = new C_class ()这种定义的A就主要随右侧子类C_class ()的结构了。

助记:为什么static优先级高?
JVM中存储时候,除了第一部分stack先加载
第二部分method area里面有class structure和static存储区,他们在程序开始时候只加载一次,如果有method定义时候写了static,它在程序开始时候就加载了,优先级自然是高于子类重写父类的Override。
在这里插入图片描述

实例举例,思考下例输出的结果是什么?


public class testjan05{
public static void main(String args[]) {kids ki = new kids();ki.call();//non static, follow kids()(right) class, calling kidski.read_book();//static, follow kids(left) baby is reading baby bookshuman hu = new kids();
hu.call();//non static, follow new kids()(right) calling kids
hu.read_book();//non static, follow human(left) human is reading books
}
}

public class kids extends human{
//class kids是从class human那里继承的
//在主程序里 new 一个kids的时候 kids是子类
//子类kids可以指向父类human,就是父类human的引用指向了子类kidspublic void call() {System.out.println("non static calling kids");}public static void read_book(){System.out.println("baby is reading baby books");}
}

public class human {public void call() {System.out.println("non static calling human");}//public static void eat(){System.out.println("human is eating");}public static void read_book(){System.out.println("human is reading books");}
}

运行结果

non static calling kids
baby is reading baby books
non static calling kids
human is reading books

简化版举例,classA是classB的子类,他们内部都有一个叫做test的method,先在在主程序分别调用这两个classA.test和ClassB.test并观察他们的输出结果。注意,在建立new object的时候,右侧都是写的子类。

public class testjan05 {public static void main(String[] args) {A x= new A();x.sta_test();//调用的是静态的方法,那么x应该跟随左侧A class,输出为static A=>test()x.non_test();//调用的是非静态的方法,那么x应该跟随右侧子类new A的class输出为 non-static A=>test()B y=new A();//父类B的引用 可以指向子类A//static优先级高于Override,如果见到static直接按B class父类走,不用再往句子右侧读了//如果调用的non-static的方法,需要走完全语句,Override之后程序object按照右侧new A()子类走y.sta_test();//调用的是静态的方法,输出应该就是左侧B class输出为static B=>test()y.non_test();调用的是非静态的方法,输出应该就是右侧子类new A()输出为non-static A=>test()}
}

public class A extends B{public static void sta_test() {System.out.println("static A=>test()");}public void non_test() {System.out.println("non-static A=>test()");}
}
//重写Override 子类重写父类的方法 只存在于non-static类的methodpublic class B {public static void sta_test(){System.out.println("static B=>test()");}public void non_test() {System.out.println("non-static B=>test()");}}

运行结果


static A=>test()
non-static A=>test()static B=>test()
non-static A=>test()

总结

  • 当有static时:不用管Override,对于语句ClassF x= new ClassC();x直接跟着父类ClassF走

例如
A子类 extends B父类

A x = new A();
x.test();
x就是和A有关的

B y = new A();
y.test();
y就是和B有关的

  • 当删掉static时,要考虑子类Override父类(子类重写父类的同名方法)
    例如
    A子类 extends B父类

A x = new A();
x.test();
x跟new A()有关

B y = new A();//考虑子类重写父类方法
y.test();
y和new A()有关

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/467180.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java程序设计】【C00252】基于Springboot的实习管理系统(有论文)

基于Springboot的实习管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的实习管理系统 本系统分为前台功能模块、管理员功能模块、教师功能模块、学生功能模块以及实习单位功能模块。 前台功能模块&#xf…

洛谷: [CSP-J 2023] 小苹果

题目描述 小 Y 的桌子上放着 n n n 个苹果从左到右排成一列,编号为从 1 1 1 到 n n n。 小苞是小 Y 的好朋友,每天她都会从中拿走一些苹果。 每天在拿的时候,小苞都是从左侧第 1 1 1 个苹果开始、每隔 2 2 2 个苹果拿走 1 1 1 个苹果…

MIT-Missing Semester_Topic 3:Editors (Vim) 练习题

文章目录 练习一练习二练习三练习四练习五练习六练习七练习八 本 Topic 的 MIT 讲解网页(练习题未给解答) 练习一 自行完成 vimtutor。vimtutor 是 Vim 本身附带的一个入门教程,在 shell 中直接输入 vimtutor 便能运行。注意该教程在 8024 大…

剑指offer——旋转数组的最小数字

目录 1. 题目描述2. 分析思路2.1 示例分析 3. 更完美的做法 1. 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3.4,5,1.2}为{1.2,3,4,5}的一个旋转&a…

idea中vue文件如何快捷打出html标签结构,不写<

例如写一个<button></button>标签&#xff1a;快捷键如下 先写一个button&#xff0c;然后再按tab键即可自动生成一对标签。 演示&#xff1a; 步骤一&#xff1a; 步骤二&#xff1a;

Linux进程创建,进程终止,进程等待,进程程序替换,简易shell代码

进程创建 fork函数初识 fork函数&#xff1a;从已存在进程中创建一个新进程。新进程为子进程&#xff0c;而原进程为父进程 #include <unistd.h> pid_t fork(void); 返回值&#xff1a;子进程中返回0&#xff0c;父进程返回子进程id&#xff0c;出错返回-1 进程调用 f…

linux应用 进程间通信之信号量(POSIX)

1、前言 1.1 定义 POSIX信号量是一种用于同步进程之间对共享资源访问的机制。它允许进程在访问共享资源之前进行互斥和同步操作&#xff0c;以确保数据的一致性和正确性。POSIX信号量通常由一个整数值表示&#xff0c;可以进行原子增减操作&#xff0c;以及等待和通知操作。 …

《A++ 敏捷开发》- 8 获取高层支持

我&#xff1a;对过程改进来说&#xff0c;最重要的成功要素是什么&#xff1f; 客户&#xff1a;最难的是如何得到高层的支持&#xff0c;这不仅仅是嘴巴说说而已&#xff0c;而是要切实地给人、给时间。高层往往不清楚什么是质量改进的重点&#xff0c;但他们对员工的人均收入…

数据工程工程师学习路线图

数据工程岗位要求 Skill Sets required: - Hands on experience enabling data via Adobe Analytics and/or Google Analytics - Understanding of how customer level data is captured and stitched with behavioural data - Experience working with Testing (QA) and D…

Matplotlib核心:掌握Figure与Axes

详细介绍Figure和Axes&#xff08;基于Matplotlib&#xff09; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333; 一、Figure&#xff08;图形&#xff09;&#x1f333;&#x1f341;1. 创建Figure&#x1f341;&#x1f341;2. 添加Axes&am…

多态

多态的基本语法 多态分为两类 静态多态: 函数重载 和 运算符重载属于静态多态&#xff0c;复用函数名动态多态: 派生类和虚函数实现运行时多态 静态多态和动态多态区别&#xff1a; 静态多态的函数地址早绑定 - 编译阶段确定函数地址动态多态的函数地址晚绑定 - 运行阶段确…

C++实现二分查找

目录 例1 例2 例3 例4 例5 例6 例1 704. 二分查找 注意&#xff1a; ①left < right,这里的号是最后一次通过下标mid来判断 ②在偶数的时候mid&#xff0c;左右无所谓&#xff0c;因为left和right都有1&#xff1b; 参考代码 class Solution { public:int search…