一、前置知识:继承
- 面向对象的三大特征之一:继承
2.继承的作用:
- 基本作用:代码复用
- 重要作用:有了继承,才有
方法覆盖
和多态机制
二、方法重载(overload)
- 什么时候时候使用方法重载?
- 在一个类中,如果功能相似,可以考虑使用方法重载。
- 目的是:代码美观、方便编程。
- 当满足什么条件的时候构成方法重载?
- 条件1:在同一个类中
- 条件2:相同的方法名
- 条件3:不同的参数列表(类型、格式、顺序)。
- 方法重载属于编译阶段的功能。(方法重载机制是给编译器看的)。
三、方法重写(方法覆盖/override)
IDEA快捷键:ctrl + o
- 什么时候使用方法重写?
- 当从父类继承到的方法无法满足子类的业务需求时。(有继承才有重写)
- 当满足什么条件的时候构成方法重写?
- 条件1:方法重写发生在具有继承关系的父子类之间。
- 条件2:具有完全相同的方法名、形参列表、返回值类型。
- 关于返回值类型:如果父类的返回值类型是引用数据类型,那么子类重写时的返回类型可以是原类型的子类型。
-
- 关于方法覆盖的细节
- 当子类将父类方法覆盖后,将来子类调用方法的时候,一定会执行重写之后的方法。
- 在Java语言中,有一个注解
@Override
,可以在编译阶段用来检查这个方法是否是重写了父类的方法。如果不是重写加上@Override编译器会报错。 - 子类继承的父类属性和方法访问权限不能变低,但可以变高(protected -> public 可以)
- 抛出异常不能变多可以变少
- 私有方法以及构造方法不能继承,因此不存在方法重写(方法覆盖)
- 静态方法不存在方法重写(方法覆盖),静态方法在编译时已经静态绑定。
- 方法覆盖针对的是实例方法,和实例变量无关。
- 静态方法和实例变量都是编译时绑定的哪个类,运行时的值就是哪个类的。(编译和运行的多态详见该链接)
四、代码实例
- 定义父类
Animal
类
public class Animal {
private String name;
public void move(){
System.out.println("动物在移动");
}
public Object sleep(int minutes) {
System.out.println(this.getName() + "睡" + minutes + "分钟");
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 子类
Bird
类继承Animal
类
public class Bird extends Animal {
// 重写父类的move方法,加上@Override不报错
@Override
public void move(){
System.out.println("鸟在飞");
}
// 虽然名字一样,但是参数列表不一样
// 因此不属于方法重写,属于方法重载。加@Override会报错
public void move(int i){
System.out.println("飞" + i + "米");
}
// 方法重写时:返回类型是原类型的子类型可以
// 如:重写Animal类的 public Object sleep()方法
@Override
public String sleep(int minutes) {
return "重写父类方法,返回值为父类原方法Object类的子类String类";
}
}