[JAVA] 重写以及@Override标签
以前JAVA看的少,最近做项目,对@Override的调用顺序有点疑惑,故查了一些资料。既然查资料了,那就把能看到的知识点整理一下,以供日后学习。
原文地址请保留http://www.cnblogs.com/rossoneri/p/3977038.html
关于重写
当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。通常,派生类继承基类的方法,因此,在调用对象继承方法的时候,调用和执行的是基类的实现.但是,有时需要对派生类中的继承方法有不同的实现.
例如,假设动物类存在"跑"的方法,从中派生出马和狗,马和狗的跑得形态是各不相同的,因此同样方法需要两种不同的实现,这就需要"重新编写"基类中的方法。"重写"基类方法就是修改它的实现或者说在派生类中重新编写。
重写是子类与父类的一种多态性体现。
重写允许子类改变父类的一些行为,当父类不满足子类的一些要求时我们就需要子类对父类的一些行为进行重写。
重写示例
例如:某公司里的员工的电话号码不允许对外公开,而销售人员(员工)的电话号码则需要对外公开。
public class Employee {
private String mobile;
public Employee(String mobile) {
this.mobile = mobile;
}
protected String showMess(){
return "电话号码:"+mobile;
}
}
员工类的showMess方法是protected的,所以位于其他包的对象是访问不到的。
然后定义一个销售人员的类(Sales),并继承Employee类
public class Sales extends Employee{
//子类除了具有父类的一些属性,也可以有自己的一些属性
private String msn;
public Sales(String mobile,String msn) {
super(mobile);
this.msn = msn;
}
@Override
public String showMess() {
return super.showMess()+"==msn:"+this.msn;
}
}
注意这时被覆盖的showMess方法的访问级别是public,可以被任何其他对象访问到。
关键点
1.被覆盖方法的访问控制级别可以不一样。
例如上例父类的showMess方法的访问级别为protected的,而子类覆盖的showMess方法访问级别则为public的。
但子类的访问级别必须要高于父类被覆盖方法的访问级别,如果父类是public的而子类是protected的则是错误的。
2.方法被定义为private或static或final的则不能被覆盖。
3.方法的返回类型。
前面说了,重写的方法名称,参数及类型必须一致,但没有提返回类型。这里,返回类型可以不一样,但类型有限制。
子类的返回类型可以是更具体的对象,例如可以将Employee类的返回类型改为Object也正确。而倒过来则错误。
4.在方法调用时先会在子类中找覆盖的方法,如果子类中没有则会在父类中去找。
调用顺序示例
public class Parent {
private int num(int i,int j){
return i+j;
}
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.num(1, 2));
}
}
class Child extends Parent{
public int num(int x,int y){
return x-y;
}
}
这段代码的执行结果为什么呢?如果你回答-1则错了,正确答案是3。
为什么呢?因为父类的num方法是private的,所以不能被覆盖,所以子类的num方法不是一种Override,因此在子类找不到被覆盖的num方法就会执行父类的num方法。所以结果输出为3.如果把private改为protected或者public结果就是-1了
public class Parent {
public int test(){
//执行子类的num方法
return num(1,2);
}
protected int num(int i,int j){
return i+j;
}
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.test());
}
}
class Child extends Parent{
public int num(int x,int y){
return x-y;
}
}
那么这段代码的执行结果是-1,因为父类test方法调用的是子类的num方法。
再看下一个例子,先写一个基类:
package tttttest;
public class Fruit {
public void show_name(int num) {
System.out.println("Fruit: " + num);
}
public static void main(String[] args) {
// TODO code application logic here
Fruit apple = new Apple();
apple.show_name(2);
}
}
之后我们编写一个Apple子类,继承这个基类。并且复写基类中的show_name()方法。
package tttttest;
public class Apple extends Fruit{
@Override
public void show_name(int num) {
// TODO Auto-generated method stub
System.out.println("Apple: " + num);
}
}
输出结果就是Apple: 2
关于@Override标签
@Override是伪代码,表示重写
一来可以当作注释来看
二来增加代码的可读性,看到标签就知道这是从父类重写的方法
三来,就是IDE会根据这个标签来检查你的代码。如果你写代码的时候不太注意重写规范,犯了上面写的4个关键点的错误还没发现,你若加上这个标签,IDE便会帮你标记错误。
怎么让IDE自动加@Override标签
我用Eclipse的添加方法是:在editor中单击鼠标右键->Source->Override/Implement Methods
在列表中选择需要重写的方法即可。
参考资料
分享一下@Override标签背后的小秘密---记录java的思行合一
[JAVA] 重写以及@Override标签的更多相关文章
- java中的@Override标签
@Override标签的作用: @Override是伪代码,表示方法重写. @Override标签的好处: 1.作为注释,帮助自己检查是否正确的复写了父类中已有的方法 2.便于别人理解代码 3.编译器 ...
- java中的@Override标签,小细节大作用
转载:http://www.cnblogs.com/octobershiner/archive/2012/03/09/2388370.html 一般用途 ...
- Java - 21 Java 重写(Override)与重载(Overload)
Java 重写(Override)与重载(Overload) 重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变.即外壳不变,核心重写! 重写的好 ...
- java中重载(overload)与重写(override)的区别
方法重载(overload): 方法重载就是在一个类中可以创建多个方法,它们具有相同的名字,但是具有不同的参数和不同的定义,调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,这就 ...
- “全栈2019”Java第四十八章:重写方法Override
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- JAVA重写不需要@override
一,如下代码, package com.boot.enable.bootenable; import org.springframework.scheduling.annotation.Async; ...
- java 中重载(Overload)和重写(Override)的区别
首先重载和重写是应用于两个不同场景下面的两种不同的手段: 两者各自的特征: 重载(Overload):首先是位于一个类之中或者其子类中,具有相同的方法名,但是方法的参数不同,返回值类型可以相同也可以不 ...
- Java重写toString和泛型的使用
一.在一个类中重写toString方法 public class Person { private String name; private int age; public Person() { } ...
- Java overload和override的区别分析
Java overload和override的区别分析 方法的重写(Overriding)和重载(Overloading)是Java多态性的不同表现.重写(Overriding)是父类与子类之间多态性 ...
随机推荐
- 线程中消费者生产者的实例代码(使用Lock类)
http://www.cnblogs.com/DreamDrive/p/6192685.html 这个是用synchronized关键字实现的. Lock可以替换synchronized. 上面用来做 ...
- C# 获取所有对象的字符串表示一ToString方法
应用程序开发过程中经常需要获取对象的字符串表示.Object类中定义了一个ToString的虚方法.所以在任何类型的实例上都能调用该方法. C#中几乎所有的类型都派生自Object,所以如果当前类型没 ...
- tensorflow进阶篇-4(损失函数3)
Softmax交叉熵损失函数(Softmax cross-entropy loss)是作用于非归一化的输出结果只针对单个目标分类的计算损失.通过softmax函数将输出结果转化成概率分布,然后计算真值 ...
- [Python 从入门到放弃] 3. BIF(内建函数)
BIF (built-in functions) Python中提供了70多个内建函数,具备大量的现成功能. BIF不需要专门导入,可以直接使用,拿来就用 1.print() # 在屏幕上打印输出 如 ...
- linux buff/cache释放
手动释放cache # > /proc/sys/vm/drop_caches
- Java中的八大基本数据类型
Java中的基本类型主要包括整数.浮点数.字符和布尔类型. 整数: 整数类型主要包括byte.short.int.long四种类型,所占大小分别为1byte.2byte.4byte和8byte: 浮点 ...
- 浅谈移动应用的跨平台开发工具(Xamarin和React Native)
谈移动应用的跨平台开发不能不提HTML5,PhoneGap和Sencha等平台一直致力于使用HTML5技术来开发跨平台的移动应用,现在看来这个方向基本算是失败的,基于HTML5的移动应用在用户体验上与 ...
- Unix/Linux系统管理技术手册学习笔记——shell
创建日期:2016/02/29 更新日期:2016/02/29 shell变量赋值时不能在等号两边留空白,否则shell会把变量名误认为是命令名 双引号括起来的变量可以进行替换(用*和?这样的文件名匹 ...
- Mac添加命令别名
1. 切换到用户主目录 $ cd 2. 编辑或新建.bash_profile文件 3. 添加别名 命令别名设置语法: alias [别名]='[指令名称]' 注意:等号两边均无空格,指令名称中如有空格 ...
- [转]【mysql监控】查看mysql库大小,表大小,索引大小
本文转自:http://blog.sina.com.cn/s/blog_4c197d420101fbl9.html 查看所有库的大小 mysql> use information_schema; ...