第五章(繼承)
繼承:繼承已存在的類就是複用這些類的方法和域。在此基礎上,還可以添加一些新的方法和域,
說白了就是:孩子繼承了父親的家產,自己隨意支配。
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 類沒有任何關係 ( 有可能它們彼此之間也沒有任何關係 )。 必要的話 , 可以將這個過程一直延續下去。