类,超类和子类

关键字extends表明正在构造的新类派生于一个已存在的类。已存在的类被称为超类,基类或父类;新类称为子类,派生类或孩子类。超类和子类是java程序员最常用的两个术语。

Employee 类:

import java.time.LocalDate;
import java.util.Objects;

public class Employee {
    private String name;
    private double salary;
    private LocalDate hireDay;

    public Employee(String name, double salary, int year, int month, int day) {
        this.name = name;
        this.salary = salary;
        hireDay = LocalDate.of(year, month, day);
    }

    public String getName() {return name;}

    public double getSalary() {return salary;}

    public LocalDate getHireDay() {return hireDay;}

    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent / 100;
        salary += raise;
    }
}

Manager 类:

public class Manager extends Employee {

    private double bonus;

    public Manager(String name, double salary, int year, int month, int day) {
        super(name, salary, year, month, day);
        bonus = 0;
    }


    public double getSalary() {
        double baseSalary = super.getSalary(); 
        return baseSalary + bonus;
    }

    public void setBonus(double b) {
        bonus = b;
    }
    
    
}

在Manager类中,增加了一个用于存储奖金信息的域,以及一个用于设置这个域的新方法:

public class Manager extends Employee {

    private double bonus;

     ......

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }
    
    
}

由于setBonus方法不是在Employee类中定义的,所以属于Employee类的对象不能使用它。

然而,尽管Manager类中没有显示定义getName和getHireDay等方法,但是属于Manager的对象却可以使用它们,这是因为Manager类自动继承了超类Employee中的这些方法。

尽管Employee类是一个超类,但并不是因为它优于子类或者拥有比子类更多的功能,实际上恰恰相反,子类比超类拥有的功能更加丰富。Manager类比Employee类封装了更多数据,拥有更多功能。

继承

继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

继承的作用:通过继承可以快速创建新的类,实现代码的重用,提高程序的可维护性,节省大量创建新类的时间,提高开发效率和开发质量。

形式如下


class 父类{
    ...       //成员变量、成员方法
}
class 子类 extends 父类{
    ...       //类体
}


继承的优点

1.继承过来的字段和方法,可以像任何其他字段和方法一样被直接使用;
2.在子类中可以声明一个与父类中同名的新字段或静态方法,从而“隐藏”父类中的字段或方法;
3.可以在子类中声明一个在父类中没有的新字段和方法;
4.可以在子类中编写一个父类当中具有相同名的新实例方法,这称为“方法重写”或“方法覆盖”;
5.可以在子类中编写一个调用父类构造方法的子类构造方法,既可以隐式地实现,也可以通过使用关键字super来实现。

覆盖方法

超类中的有些方法对子类Manager并不一定适用。比如Manager类中的getSalary方法应该返回薪水和奖金的总和。为此需要提供一个新方法来覆盖超类中的这个方法。

我们希望调用超类Employee中的getSalary方法,而不是当前这个类的这个方法,为此,可以使用特定的关键词super解决这个问题:


super.getSalary()


public double getSalary()
{
    double baseSalary = super.getSalary();
    return baseSalary + bonus;
}


在子类中可以增加域,增加方法或者覆盖超类的方法,然而绝对不能删除继承的任何域和方法。

使用super调用父类的无参数构造方法/有参数构造方法

子类不继承其父类的构造方法。

  • 当使用无参数的super()时,父类的无参数构造方法就会被调用;
  • 当使用带有参数的super()方法时,父类的有参数构造方法就会被调用。