abstract 關鍵字可修飾類別與方法。抽象類**無法實例化**,旨在定義「契約」與「共享實作」,供子類繼承具體化。良好的抽象類設計遵循「模板方法模式」與「里氏替換原則」。
abstract 方法的類**必須**宣告為 abstract class。abstract class 可**無**抽象方法 (純作為不可實例化的基類)。abstract。private、final、static (JDK 8+ 可有 static 預設方法,但非抽象)。
import java.time.LocalDate;
import java.util.*;
// 抽象基類
abstract class Employee {
private final String name;
private final LocalDate hireDate;
protected Employee(String name, LocalDate hireDate) {
this.name = name;
this.hireDate = hireDate;
}
public String getName() { return name; }
public LocalDate getHireDate() { return hireDate; }
// 抽象方法:強制子類實作薪資計算邏輯
public abstract double monthlySalary();
// 具體方法:共享邏輯 (模板方法)
public final String salarySlip() {
return String.format("%s | 入職: %s | 月薪: %.2f", name, hireDate, monthlySalary());
}
}
// 具體子類:月薪制
class SalariedEmployee extends Employee {
private final double monthlyPay;
SalariedEmployee(String name, LocalDate hireDate, double monthlyPay) {
super(name, hireDate);
this.monthlyPay = monthlyPay;
}
@Override public double monthlySalary() { return monthlyPay; }
}
// 具體子類:時薪制
class HourlyEmployee extends Employee {
private final double hourlyRate;
private final int hoursPerMonth;
HourlyEmployee(String name, LocalDate hireDate, double rate, int hours) {
super(name, hireDate);
this.hourlyRate = rate; this.hoursPerMonth = hours;
}
@Override public double monthlySalary() { return hourlyRate * hoursPerMonth; }
}
// 測試
public class AbstractDemo {
public static void main(String[] args) {
List<Employee> staff = Arrays.asList(
new SalariedEmployee("Alice", LocalDate.of(2020, 3, 1), 80000),
new HourlyEmployee("Bob", LocalDate.of(2021, 7, 15), 300, 160)
);
for (Employee e : staff) {
System.out.println(e.salarySlip());
}
}
}
Alice | 入職: 2020-03-01 | 月薪: 80000.00
Bob | 入職: 2021-07-15 | 月薪: 48000.00
| 維度 | abstract class | interface |
|---|---|---|
| 狀態 (欄位) | 可有 instance fields | 僅 static final 常數 |
| 建構子 | 可有 | 無 |
| 方法實作 | 任意 | default/static (JDK 8+) |
| 多重實作 | 單一繼承 | 多重實作 |
| 演進相容性 | 新增非抽象方法不破壞子類 | 新增 default 方法不破壞實作類 |
| 適用場景 | 「是一種」關係、共享狀態/邏輯 | 「能做什麼」能力、多型契約 |
abstract class 作為骨架實作 (如 AbstractList, HttpServlet)。