Abstract class
Nội dung bài · 5 mục
- 1.Khái niệm
- 2.Ví dụ
- 3.Thử ngay
- 4.Lỗi hay gặp
- 5.Tóm tắt
Cửa hàng nhận tiền mặt và thẻ: hình thức nào cũng có số tiền và in biên lai giống nhau, nhưng cách trả tiền thì mỗi loại một kiểu. Một object "thanh toán" chung chung, không rõ là tiền mặt hay thẻ, thì không có nghĩa. Abstract class diễn tả đúng tình huống này.
Khái niệm
🧩 Trừu tượng (abstraction): chỉ đưa ra những gì nơi dùng cần biết, giấu đi chi tiết cách làm.
📐 Abstract class: class không tạo object trực tiếp được, chỉ dùng làm class cha cho các class khác.
✏️ Abstract method: method chỉ có khai báo, không có thân, mọi class con bắt buộc phải override.
Ví dụ
var payments = new List<Payment>
{
new CashPayment { Amount = 50000m },
new CardPayment { Amount = 120000m },
};
foreach (Payment p in payments)
{
Console.WriteLine(p.Receipt());
}
abstract class Payment
{
public decimal Amount { get; set; }
public abstract string Pay();
public string Receipt() => $"{Pay()} - {Amount}đ";
}
class CashPayment : Payment
{
public override string Pay() => "Tiền mặt";
}
class CardPayment : Payment
{
public override string Pay() => "Quẹt thẻ";
}Tiền mặt - 50000đ
Quẹt thẻ - 120000đabstract class Payment: không viết đượcnew Payment().public abstract string Pay();không có thân. Mỗi class con tự viết cách trả tiền.Receipt()là method bình thường, viết một lần ở class cha và dùng chung.- Vòng lặp chỉ biết
Payment. Đó là trừu tượng: nơi dùng không cần biết là tiền mặt hay thẻ.
So với virtual ở bài trước:
virtual |
abstract |
|
|---|---|---|
| Có thân ở class cha | có | không |
| Class con phải override | không bắt buộc | bắt buộc |
Thử ngay
Chép ví dụ trên vào Program.cs. Thêm class dưới đây vào cuối file, và thêm
new WalletPayment { Amount = 80000m }, vào list:
class WalletPayment : Payment
{
public override string Pay() => "Ví điện tử";
}Đoán trước khi chạy: dòng biên lai thứ ba in ra gì?
Xem kết quả
Tiền mặt - 50000đ
Quẹt thẻ - 120000đ
Ví điện tử - 80000đDòng thứ ba là Ví điện tử - 80000đ. WalletPayment kế thừa Receipt() và
tự viết Pay(), nên vòng lặp không phải sửa gì.
Lỗi hay gặp
Tạo object từ abstract class. Compiler chặn ngay.
// SAI — lỗi compile: Payment là abstract
var p = new Payment();// ĐÚNG — tạo từ class con cụ thể
Payment p = new CashPayment();Class con quên viết abstract method. Mọi abstract method đều phải được
override.
// SAI — lỗi compile: thiếu override Pay()
class BankTransfer : Payment
{
}// ĐÚNG
class BankTransfer : Payment
{
public override string Pay() => "Chuyển khoản";
}Tóm tắt
- Abstract class là class cha không tạo object trực tiếp được.
- Abstract method không có thân, class con bắt buộc
override. - Abstract class vẫn chứa được property và method bình thường để dùng chung.
- Trừu tượng: nơi dùng chỉ làm việc với class cha, không cần biết chi tiết từng loại.
Tự kiểm tra
0/3 câuabstract class Shape { public abstract double Area(); } Dòng var s = new Shape(); thì sao?
Khi nào dùng abstract method thay vì virtual method?
abstract class Report có abstract method Build() và method thường Print(). Class SalesReport : Report cần viết gì tối thiểu?