重写(Override)
重写是指:所创建的子类可以定义一个与父类具有相同名称、相同参数列表、相同返回类型的方法。并且这个方法会将父类的方法给覆盖掉,也就是说,子类在调用方法时,就不会调用成父类的方法了。即外壳不变,核心重写。
- 在子类的方法中不允许抛出新的检查异常,或者比被重写的方法更宽泛的检查异常
- 在面向对象原则中,重写意味着可以重写任何方法
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
}
}
如上,父类Animal,子类Dog,在测试类中,b虽然是Animal类,但是可以运行子类的方法。这并不意味着父类的类型,创建了子类的对象后,就能够执行子类的全部方法。这里只是因为,父类中有一个和子类名称一样的方法,编译能够成功,然后运行的时候是执行特定的子类方法。
比如再看下面这个:
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
此时的运行结果是:
TestDog.java:30: cannot find symbol
symbol : method bark()
location: class Animal
b.bark();
^
同样是使用Animal类型,创建了一个Dog对象,然后去调用父类的方法,结果就是报错提示,没有这个方法。
方法的重写规则
- 重写方法的权限不能比被重写方法的权限更低
- 重写的参数列表必须和被重写方法的参数列表完全一致
- 重写方法的返回类型可以与被重写方法不同,但是必须是父类返回值的派生类
- 被声明为final的方法不能被重写
- 被声明为static的方法不能被重写,但是可以被声明
- 不能继承一个类,不能重写该类的方法
- 父类的构造方法不能被重写
Super关键字的使用
在子类中调用父类的方法时,需要使用
class Dog extends Animal{
public void move(){
super.move(); // 应用super类的方法
System.out.println("狗可以跑和走");
}
}
重载(Overload)
重载是指两个方法名称相同,但是参数列表不同,返回值类型可以不同
方法的重载规则
- 可以改变访问类型修饰符
- 必须改变参数列表
- 可以改变返回值类型
- 可以声明新的或者更宽泛的检查异常
- 重载方法不能使用返回类型来区分
- 可以在一个类中或者子类中被重载
重写与重载的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可以修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以修改 | 一定不能做更严格的限制(可以降低限制) |
在这里要注意一个点,参数列表的顺序,同样也可以区分两个不同的方法:
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
//!!!以下两个参数类型顺序不同
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
总结
重写和重载是Java多态性的不同表现,重写是子类与父类的多态性表现,而重载是多态性的具体表现形式。
- 重载是在一个类中,定义了方法名称相同,但参数列表不同,或者参数顺序不同
- 重写是父类和子类中出现了名称相同,并且参数列表也相同的方法
- 重载是一个类的多态性表现,而重写是父类和子类的多态性表现