Java基础之(八)方法覆盖
子类从父类中继承方法,有时子类需要修改父类中定义的方法的实现,这称作方法覆盖。比如下面这个例子:
class Person {
String name;
int age;
void introduce(){
System.out.println("我的姓名是:" + name+",我的年龄是"+ age);
}
}
class Student extends Person {
String address;
void introduce(){
System.out.println("我的姓名是"+ name + ",我的年龄是"+ age);
System.out.println("我的家在"+ address);
}
}
class Test{
public static void main(String args[]){
Student s = new Student();
s.name = "张三";
s.age = 20;
s.address = "北京";
s.introduce();
}
}
introduce()方法在Person类中定义,在Student类中修改。并且这两个方法定义(返回值类型、方法名、参数列表)相同,只不过方法体不一样,这样的两个方法的关系我们称之为方法覆盖,有的书上也称之为方法重写/复写。
1.语法特征
- 在具有父子关系的两个类中
- 父类和子类中各有一个函数,这两个函数的定义完全相同
输出结果:
我的姓名是张三,我的年龄是20
我的家在北京
2.super调用成员方法
在上面的代码中我们能够发现重复代码:
System.out.println("我的姓名是"+ name + ",我的年龄是"+ age);
怎么解决这个问题,这时候可以用super关键字:
void introduce(){
super.introduce();
System.out.println("我的家在"+ address);
}
}
3.覆盖的注意事项
- 仅当方法是可访问时,它才能被覆盖。这样,因为私有方法在它的类本身以外是不能访问的,所以它不能被覆盖。如果子类中定义的方法在父类中是私有的,那么这两个方法完全没有关系。比如:
public class Person {
public void introduce() {…}
}
public class Student extends Person {
private void introduce() {…} //编译错误,子类方法缩小了父类方法的访问权限
}
- 与实例方法一样,静态方法也能被继承。但是,静态方法不能被覆盖。如果父类中定义的静态方法在子类中被重新定义,那么定义在父类中的静态方法将被隐藏。可以使用语法:父类名.静态方法名调用隐藏的静态方法。比如:
public class Person {
public static void introduce() { }
}
public class Student extends Person {
public void introduce() { } //编译出错
}
Super调用成员变量
如果子类定义了和父类同名的成员变量,则会发生子类变量隐藏父类变量的情形。在正常情况下,子类中定义的方法直接访问该变量默认会访问到子类中定义的变量,无法访问到父类中被隐藏的变量。
在子类定义的实例方法中可以通过super来调用父类中被隐藏的变量,如下代码所示:
class BaseClass{
public int a = 5;
}
public class SubClass extends BaseClass{
public int a = 7;
public void accessOwner(){
System.out.println(a);
}
public void accessBase(){
//通过super来限定访问从父类继承得到的a变量
System.out.println(super.a);
}
public static void main(String[] args){
SubClass sc = new SubClass();
//输出7
sc.accessOwner();
//输出5
sc.accessBase();
}
}