以前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
在列表中选择需要重写的方法即可。
参考资料