在Java编程语言中,有两个概念非常相近,很容易混淆。它们就是重写与重载。
这里先在类继承的话题上,继续来说说重写,也叫覆盖。
没有继承,就不可能有重写。这是子类对父类的一种特殊操作。这里先提一下,重载主要发生在同一个类中的操作,也可以发生在父类与子类之间。
当一个子类继承了一个父类时,它也同时继承了父类的属性和方法。我们可以直接使用父类的属性和方法,或者,如果父类的方法不能满足子类的需求,则可以在子类中对父类的方法进行“改造”,这个“改造”的过程在Java中称为“覆盖(override)”。
比如,假设我们在Person 类中定义了一个方法用于显示姓名,如下:
public String showName(){
return name;
}
那么,在子类Teacher中,就会继承这个父类的showName()方法,此时,即使Teacher类中没有定义showName()方法,也可以在它的实例(instance)中使用这个方法。
比如,我们实例化了一个Teacher的实例,这是就可以直接调用从Teacher的父类Person中继承的这个showName()方法。如下:
Teacher teacher = new Teacher();
teacher.showName();
但是,我们在Teacher类中,我们或许需要在姓名后面加上“老师”,比如,“张三”就显示为“张三老师”,那么,这个时候就需要在子类“Teacher”中对从父类中继承的showName()方法进行“改造”,也就是在子类Teacher中覆盖父类Person的方法showName():
public class Teacher extends Person{
… …
public String showName(){
return name+”老师”;
}
}
在子类Teacher中,覆盖了父类的showName方法,在覆盖的过程中,需要提供和父类中的被覆盖方法相同的方法名称、输入参数(此处为空)以及返回类型。
另外,在子类对父类的方法进行覆盖的过程中,不能使用比父类中的被覆盖方法更严格的访问权限。
比如,父类Person中的方法showName()的修饰符是public,那么,在子类Teacher中的覆盖方法showName()就不能用protected、默认(Default)或者private等来限制。
从前面的讨论可以看出,类的继承主要可以从两方面来看:
对父类的扩充。如,在子类中加入新的属性、新的方法。
对父类的改造。比如,对方法的覆盖。
首先定义一个父类:Person,它有三个属性,分别由各自的存取方法来存取。
public class Person {
private String name;
private int age;
private String sex;
public String showName() {
return name;
}
public void setName(String theName) {
name = theName;
}
public int getAge() {
return age;
}
public void setAge(int theAge) {
age = theAge;
}
public String getSex() {
return sex;
}
public void setSex(String theSex) {
sex = theSex;
}
}
在这边,我们将它的属性的访问控制定义为Default,是因为在子类中我们需要访问这些属性。
接着,我们定义一个类“Teacher”,它继承“Person”类。
public class Teacher extends Person {
// 扩充父类属性
private String department;
// 扩充父类方法
public void setDepartment(String theDept) {
department = theDept;
}
public String getDepartment() {
return department;
}
// 方法覆盖
public String showName() {
return name + "老师";
}
// 测试
public static void main(String[] args) {
Teacher t = new Teacher();
t.setName("Alex");
System.out.println(t.showName());
}
}
在这个子类中,继承了父类,新增了一个“部门”的属性:department,并新增了相应的存取方法。改写(覆盖)了父类中的showName()方法,在姓名后面加上“老师”后返回。
因为在同一个包中的子类中用到了父类的属性name,所以,父类Person中的name属性不能定义为private的。最后定义了一个main()方法用于测试。
执行这个程序,在控制台上将会输出如下信息:
Alex老师
在程序中加入一个main()方法用于测试一个类是不错的主意,无论这个类是否是一个Java应用程序(Java Application)。
你可以通过类的main()方法测试这个类的各个方法是否与你的设计相一致。