Interface
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
Đặt hàng xong, hệ thống gửi email cho khách. Tháng sau sếp muốn gửi thêm SMS. Nếu code đặt hàng gắn chặt với email thì phải sửa chính code đó. Interface giúp code đặt hàng chỉ cần biết "có ai đó gửi được thông báo", còn gửi bằng gì thì tuỳ.
Khái niệm
📜 Interface: danh sách method và property mà một class phải có, thường không kèm cách làm.
🤝 Implement: class ghi : TênInterface thì cam kết viết đủ mọi thành viên của interface đó, thiếu một cái là lỗi compile.
Ví dụ
var order = new PlaceOrder(new EmailNotifier());
order.Run();
interface INotifier
{
void Send(string message);
}
class EmailNotifier : INotifier
{
public void Send(string message) =>
Console.WriteLine($"Email: {message}");
}
class PlaceOrder
{
private readonly INotifier _notifier;
public PlaceOrder(INotifier notifier)
{
_notifier = notifier;
}
public void Run() => _notifier.Send("Đã đặt hàng");
}interface INotifierchỉ khai báoSend, không có thân. Tên interface bắt đầu bằng chữI.EmailNotifier : INotifierimplement interface, nên phải có methodSendvà đểpublic.PlaceOrderchỉ biếtINotifier, không biết email. Nó nhận notifier qua constructor.readonlynghĩa là field chỉ gán được lúc khai báo hoặc trong constructor, sau đó không đổi (giống property{ get; }ở bài Property và constructor). Fieldprivatetheo quy ước .NET bắt đầu bằng_.- Không
new INotifier()được, nhưng biến kiểuINotifierthì giữ được bất kỳ class nào implement nó. - Một class implement được nhiều interface:
class Shop : INotifier, IPrinter.
Thử ngay
Chép ví dụ trên vào Program.cs. Thêm class dưới đây vào cuối file, rồi thay
hai dòng đầu bằng đoạn gọi mới:
class SmsNotifier : INotifier
{
public void Send(string message) =>
Console.WriteLine($"SMS: {message}");
}new PlaceOrder(new EmailNotifier()).Run();
new PlaceOrder(new SmsNotifier()).Run();Đoán trước khi chạy: dòng thứ hai in ra gì?
Xem kết quả
Email: Đã đặt hàng
SMS: Đã đặt hàngDòng thứ hai là SMS: Đã đặt hàng. PlaceOrder gọi Send của object được
truyền vào. Thêm cách gửi
mới chỉ cần viết class mới, không sửa PlaceOrder.
Lỗi hay gặp
Implement thiếu thành viên. Class đã ghi : INotifier thì phải viết đủ.
// SAI — lỗi compile: thiếu method Send
class PushNotifier : INotifier
{
}// ĐÚNG
class PushNotifier : INotifier
{
public void Send(string message) =>
Console.WriteLine($"Push: {message}");
}Tạo object từ interface. Interface không có code để chạy.
// SAI — lỗi compile: không new được interface
INotifier notifier = new INotifier();// ĐÚNG — new một class implement interface đó
INotifier notifier = new EmailNotifier();Tóm tắt
- Interface liệt kê method và property mà class phải có, không kèm cách làm.
- Class
: TênInterfacephải implement đủ mọi thành viên, đểpublic. - Code chỉ phụ thuộc vào interface thì đổi được cách làm mà không phải sửa code đó.
- Không
newđược interface. Một class implement được nhiều interface. - Từ C# 8, method trong interface có thể kèm thân sẵn (default method), class không bắt buộc viết lại method đó.
Tự kiểm tra
0/3 câuinterface IPrinter { void Print(string text); } Class nào implement IPrinter đúng?
Class ReportService nhận IExporter qua constructor. Muốn xuất thêm định dạng Excel, cần làm gì?
Dòng nào KHÔNG biên dịch được, biết EmailNotifier implement INotifier?