类的继承
面向对象程序设计语言,具有的特性:继承性、封装性、多态性。
在Java语言中,继承的基本思想,就是从已有的类,派生出新的类来。
不同的类可能会有一些共同的特征和行为,可以将这些共同的特征和行为统一放在一个类中,使它们可以被其他类所共享。
1. 类继承的实现
格式:
[public] class SubClass extends SuperClass{
}
class 父类{}
class 子类 extends 父类{}
例1:设计一个“人”的类;
class Person{
public String name;
public int age;
public Person(){
}
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public void speak(){
System.out.println("my name is " + name);
}
}
Person per = new Person();
例2:定义一个“员工”类,使得“员工类”具有人的所有特征和行为。另外还有自己的特征:员工工资,计算工资的操作等。
class Employee extends Person{
public double salary;
//public Employee();
public Employee(double salary){
this.salary = salary;
}
public Employee(String name,int age,double salary){
super(name,age);
this.salary = salary;
}
public double computeSalary(int hours,double rate){
double salary = hours * rate ;
return this.salary + salary ;
}
}
类继承的说明:
(1) 子类继承父类中非private的成员变量和成员方法。protected
(2) 定义类时若缺省extends关键字,则定义的类为java.lang.Object类的直接子类。所有的类都是Object的子类。
(3) Java仅支持单重继承,一个类至多只有一个直接父类(超类)。若实现多重继承,可通过接口实现。
例3. 验证子类Employee及其对象使用相应的方法。
public class EmployeeTest{
public static void main(String[] args){
Employee emp = new Employee("小明",30,5000);
System.out.println("姓名 = " + emp.name);
System.out.println("年龄 = " + emp.age);
emp.speak();
System.out.println(emp.computeSalary(10,50.0));
}
}
注意:父类中定义的private成员变量和方法不能被子类继承,因此在子类中不能直接使用。如果父类中定义了公共的访问方法和修改方法(getter() setter()),子类可以通过这些方法来访问或修改它们。
2. 方法覆盖
在子类中可以定义与父类中的名字、参数列表、返回值类型都相同的方法,这时子类的方法就叫做覆盖(overriding)或重写了父类的方法。
例4. 在Employee类中定义与其父类Person相同的speak()方法,用它来输出员工信息。
public void speak(){
System.out.println("Hello, I am "+ name );
System.out.println(" I am " + age );
System.out.println("My salary is " + salary );
}
此方法便是对Person类中speak()方法的覆盖,如果子类覆盖了父类的方法,在调用相同的方法时,调用的是子类的方法。
为了避免在覆盖方法时写错方法头,可以使用@Override注解语法,即在要覆盖的方法前面添加@Override。
例5. Object类中有一个toString()的方法,在Employee类中覆盖其方法。
@Override
public String toString(){
return "姓名:" + name + "年龄:" + age ;
}
注意:@Override注解表示其后的方法必须是覆盖父类的一个方法。如果具有该注解的方法没有覆盖父类的方法,则编译器将会报告一个错误。
关于方法覆盖,有两点需要注意:
(1) private方法 不能覆盖。如果在子类中定义了一个方法在父类中是private的,则这两个方法无关。
(2) 父类中的static方法可以被继承,但不能被覆盖。如果子类中定义了与父类中的static方法完全一样的方法,那么父类中的方法被隐藏。父类中被隐藏的static方法仍然可以用“类名.方法名()”形式调用。
关于方法的重载与方法的覆盖的不同:
方法重载是在一个类中定义了多个名称相同,但是参数列表不同的方法。
方法覆盖是在子类中 为父类中的同名方法提供一个不同的实现。
要在子类中定义一个覆盖的方法,方法的参数列表及返回值都必须和父类的方法相同。
super关键字
在子类中可以使用super关键字,用来引用当前对象的父类对象,一般用在三种情况:
(1)在子类中调用父类中被覆盖的方法,格式:
super.methodName()
(2) 在子类中调用父类的构造方法,格式:
super()
(3)在子类中访问父类中被隐藏的成员变量,格式:
super.variableName
4.调用父类的构造方法
子类不能继承父类的构造方法
super(paramlist)===>父类
super.super()===>爷爷类 不合法
在子类构造方法中,若没有使用super调用父类的构造方法,则编译器将在子类的构造方法的第一句自动加上super(),调用的父类的无参数的构造方法。