Khái niệm interface
Thuộc phần Lập trình hướng đối tượng trong hành trình C của Coddy. Bài học 40 trên 61.
Đến giờ, các struct của chúng ta đã kết hợp dữ liệu và hành vi với nhau, chẳng hạn như một tên cùng với một con trỏ hàm. Nhưng nếu một struct chỉ chứa các con trỏ hàm thì sao? Điều này tạo ra một thứ rất mạnh mẽ: một giao diện.
Giao diện định nghĩa những thao tác nào có sẵn mà không chỉ rõ chúng hoạt động như thế nào. Đây là một hợp đồng quy định rằng “mọi đối tượng triển khai giao diện này đều phải cung cấp các hàm (function) này”.
typedef void (*LogFunc)(const char* message);
typedef struct {
LogFunc log;
} ILogger;Cấu trúc ILogger chỉ chứa một con trỏ hàm. Nó không có dữ liệu riêng. Cấu trúc này chỉ mô tả hành vi. Tiền tố "I" là quy ước phổ biến để chỉ đây là một giao diện.
Bất kỳ đoạn code nào nhận ILogger đều không quan tâm thông báo nhật ký sẽ được gửi đi đâu. Nó có thể in ra màn hình console, ghi vào tệp hoặc gửi dữ liệu qua mạng. Bên gọi chỉ cần biết rằng nó có thể gọi log:
void process(ILogger* logger, const char* msg) {
logger->log(msg); // Chúng ta không biết nó ghi nhật ký NHƯ THẾ NÀO
}Sự tách biệt này là cốt lõi của tính đa hình. Hàm process hoạt động với mọi cách triển khai bộ ghi nhật ký. Bạn có thể thay đổi hành vi mà không cần sửa code của hàm. Trong bài học tiếp theo, bạn sẽ tạo các cách triển khai cụ thể đáp ứng hợp đồng giao diện này.
Thử thách
DễHãy tạo một giao diện ICalculator: một struct chỉ chứa các con trỏ hàm, xác định những phép toán mà mọi máy tính cần hỗ trợ mà không chỉ định cách thực hiện chúng.
Bạn sẽ tạo hai tệp để sắp xếp code:
calculator.h: Định nghĩa giao diện tại đây. Tạo một kiểu con trỏ hàm tên làBinaryOp, nhận hai tham sốintvà trả về mộtint. Sau đó, định nghĩa một structICalculatorchỉ chứa hai con trỏ hàm:operate(có kiểuBinaryOp) vàdescribe(một con trỏ hàm không nhận tham số và không trả về giá trị nào). Struct này chỉ là một giao diện. Nó không chứa dữ liệu, chỉ có hành vi.main.c: Đưa tệp header vào và triển khai các hàm cụ thể có thể đáp ứng giao diện:add: trả về tổng của hai số nguyênmultiply: trả về tích của hai số nguyêndescribe_add: in raAdditiondescribe_multiply: in raMultiplication
ICalculator, gán các hàm phù hợp dựa trên đầu vào và dùng nó để thực hiện phép tính.
Chương trình của bạn sẽ nhận ba đầu vào: hai số nguyên và một mã phép toán (1 để cộng, 2 để nhân).
Dựa trên mã phép toán, gán cặp hàm phù hợp cho ICalculator. Sau đó, gọi describe thông qua giao diện để in tên phép toán, rồi gọi operate để tính và in kết quả.
Đầu ra ví dụ khi đầu vào là 5, 3 và 1:
Addition
8Đầu ra ví dụ khi đầu vào là 4, 7 và 2:
Multiplication
28Điểm mấu chốt là struct ICalculator định nghĩa một hợp đồng: mọi code sử dụng nó đều biết rằng có thể gọi describe và operate mà không cần biết những hàm cụ thể nào được gán vào. Nhớ dùng include guard trong tệp header.
Tự làm thử
#include <stdio.h>
#include "calculator.h"
// TODO: Triển khai hàm add
// Trả về tổng của hai số nguyên
// TODO: Triển khai hàm multiply
// Trả về tích của hai số nguyên
// TODO: Triển khai hàm describe_add
// In ra "Addition"
// TODO: Triển khai hàm describe_multiply
// In ra "Multiplication"
int main() {
int num1, num2, op_code;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &op_code);
// TODO: Tạo một instance ICalculator
// TODO: Dựa vào op_code (1 là add, 2 là multiply),
// gán các hàm phù hợp cho máy tính
// TODO: Gọi describe thông qua giao diện
// TODO: Gọi operate qua giao diện và in ra kết quả
return 0;
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình mô-đun
Tệp tiêu đềInclude guardTệp mã nguồnHàm staticÔn tập: Máy tính mô-đun4Tính đóng gói
Khái niệm con trỏ mờĐịnh nghĩa struct mờHàm truy xuất và hàm gánKiểm tra tính hợp lệ trong hàm gánÔn tập: Hộp bí mật2Đối tượng và phương thức
Struct dưới dạng đối tượngCon trỏ 'Self'Tính đúng đắn của constCon trỏ và giá trịPhương thức hỗ trợÔn tập: trình quản lý Point5Dự án: Tài khoản ngân hàng đơn giản
Thiết lập dự ánTriển khai tài khoản8Đa hình
Con trỏ hàm trong structMô phỏng phương thứcKhái niệm interfaceTriển khai interfaceLặp đa hìnhÔn tập: Greeter3Vòng đời đối tượng
Mẫu hàm khởi tạoMẫu hàm hủyKhởi tạo trên ngăn xếpSao chép sâuÔn tập: lớp bao bọc chuỗi6Kế thừa bằng cách kết hợp
Nhúng structQuy tắc thành viên đầu tiênTruy cập thành viên lớp chaUpcastingÔn tập: hệ phân cấp hình dạngTự luyện tập: Trình biên dịch C online