第五章(继承)
继承:继承已存在的类就是复用这些类的方法和域。在此基础上,还可以添加一些新的方法和域,
说白了就是:孩子继承了父亲的家产,自己随意支配。
5.1类、超类和子类
5.1.1定义子类
01-需求:
- 普通员工:努力工作,只能获得薪水。
- 经理:除了能领取薪水外,还可以获得奖金。
- 另:经理和员工之间的关系是:is-a的关系,意思就是:每一个经理都是一个员工。
02-代码:
- 父类:Employee
- 子类:Manager
- extends:表示子类(新类)继承父类(超类)子类比父类拥有的功能更加丰富。
// 定义子类
public class Manager extends Employee {
// 这个块里面添加方法和域
}
Employee:
package com.eleven.extend;
import java.time.LocalDate;
public class Employee {
private String name; // 实例域
// 其中private double salary和private LocalDate
// hireday它们两个的实例域的本身就是对象。name域是String类对象,hireDay域是LocalDate类对象
private double salary;
private LocalDate hireday; // 雇佣
/**
* 如果有 1000 个 Employee 类的对象 , 则有 1000 个实例域 id 。 但是 , 只有一 个静态域 nextld 。
*/
// 实例域:Java定义类中的属性;静态域:在属性前面加上static关键字
private static int nextId = 1; // 静态域id
private int id; // 实例域id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public LocalDate getHireday() {
return hireday;
}
public void setHireday(LocalDate hireday) {
this.hireday = hireday;
}
@Override
public String toString() {
return "Employee [name=" + name + ", salary=" + salary + ", hireday=" + hireday + "]";
}
// 一个构造器和4个方法,其中构造器和类名要相同
public Employee(String n, double s, int year, int month, int day) {
super();
this.name = n;
this.salary = s;
this.hireday = LocalDate.of(year, month, day);
}
public Employee() {
super();
}
/**
* 提高工资的5%
*
* @param byPercent
*/
public void raiseSaraly(double byPercent) {
double raise = salary * byPercent / 100; // 提高后的薪水
salary += raise; // 原有的薪水 + 提高后的薪水
}
/**
* 比较两个员工的equals方法
*
* @param other
* @return
*/
public boolean equals(Employee other) {
return name.equals(other.name);
}
public void setId() {
id = nextId;
nextId++;
}
}
增加一个存储奖金信息的域,以及设置这个域的新方法。
public class Manager extends Employee {
// 添加方法和域
private double bonus; // 存储奖金信息的域(bonus)
// 设置这个域(bonus)的新方法
public void setBonus(double b) {
this.bonus = b;
}
}
5.1.2覆盖方法
01-需求:
Manager类中的getSalary方法应该返回薪水和奖金的总和。
02-代码:
// 返回薪水和奖金的总和
public double getSalary() {
double baseSalary = super.getSalary(); // 表示调用Employee类中的getSalary()方法
return baseSalary + bonus;
}
5.1.3子类构造器
01-需求:
给Manager类中创建一个构造器。
由于 Manager 类的构造器不能访问 Employee 类的私有域 , 所以必须利用 Employee 类的构造器对这部分私有域进行初始化, 我们可以通过 super 实现对超类构造器的调用 。
02-代码:
// 子类构造器
public Manager(String n, double s, int year, int month, int day) {
super(n,s,year,month,day); // 表示调用超类Employee中含有这些参数的构造方法。
bonus = 0;
}
03-以上代码整合
package com.eleven.extend;
/**
* 定义子类:
* 父类:EmployeeTest
* 子类:Manager
*extends:表示子类(新类)继承父类(超类)子类比父类拥有的功能更加丰富。
*super:它只是一个指示编译器调用超类方法的特殊关键字。
*1.调用超类的方法。
*2.调用超类的构造器。
* @author sywangu
*
*/
public class Manager extends Employee {
// 添加方法和域
private double bonus; // 存储奖金信息的域(bonus)
// 设置这个域(bonus)的新方法
public void getSalary(double bonus) {
this.bonus = bonus;
}
// 返回薪水和奖金的总和
public double getSalary() {
double baseSalary = super.getSalary(); // 表示调用Employee类中的getSalary()方法
return baseSalary + bonus;
}
// 修改奖金
public void setBonus(double b) {
bonus = b;
}
// 子类构造器
public Manager(String n, double s, int year, int month, int day) {
super(n,s,year,month,day); // 表示调用超类Employee中含有这些参数的构造方法。
bonus = 0;
}
}
04-测试
package com.eleven.extend;
/**
* 创建一个新经理,并设置他的奖金
* 为什么结果只有boss加了奖金,其它人没有加?
* 是因为:bosss对应的是Manager对象,它的getSalary方法将奖金和薪水加在了一起。
* @author sywangu
*
*/
public class ManagerTest {
public static void main(String[] args) {
// 1.构造一个数组,填入三个雇员对象
Manager boss = new Manager("伊莱文", 3000.0, 1989, 12, 15); // 定义经理的属性
boss.setBonus(5000); // 奖金设置为5000
Employee[] staff = new Employee[3]; // 创建一个数组
staff[0] = boss;
staff[1] = new Employee("Eleven", 4000.0, 1987, 10, 21);
staff[2] = new Employee("Keep", 5000.0, 1980, 11, 21);
// 3.打印出每个雇员的信息
for (Employee e : staff) {
System.out.println("员工" + "姓名:" + e.getName() + "工资:" + e.getSalary() + "薪水:" + e.getHireday());
}
}
}
输出打印:
为什么结果只有boss加了奖金,其它人没有加?
是因为:bosss对应的是Manager对象,它的getSalary方法将奖金和薪水加在了一起。
员工姓名:伊莱文工资:8000.0薪水:1989-12-15
员工姓名:Eleven工资:4000.0薪水:1987-10-21
员工姓名:Keep工资:5000.0薪水:1980-11-21
5.1.4继承层次
01-定义:
继承层次:由一个公共超类派生出来的所有类的集合称为继承层次。
一个祖先类可以拥有多个子孙继承链。
例如,可以由 Employee 类派生出子类 Programmer 或 Secretary , 它 们 与Manager 类没有任何关系 ( 有可能它们彼此之间也没有任何关系 )。 必要的话 , 可以将这个过程一直延续下去。