Abstract class và pure virtual: hợp đồng chung cho nhiều implementation
Tiên quyết
Sau bài này bạn sẽ
- Dùng abstract base làm kiểu handle mà không tạo trực tiếp
- Triển khai pure virtual function với signature thống nhất
- Kiểm các implementation khác nhau qua cùng base API
Hợp đồng có thể tồn tại trước implementation
Một checker muốn áp Rule mà không cần biết đó là cộng bias hay giới hạn ngưỡng. Abstract base mô tả API bắt buộc; implementation cụ thể chịu trách nhiệm cho công thức. Nó không tự cung cấp một hành vi đúng cho mọi derived class.
Virtual class dùng làm base, không làm object trực tiếp
Rule khai báo virtual class. Main có array handle kiểu Rule nhưng chỉ tạo AddRule và ClampRule rồi gán vào array. Đừng nhầm khai báo handle với gọi new trực tiếp cho abstract class; hai thao tác có mục đích khác nhau.
Pure virtual chỉ khai prototype
pure virtual function int apply(int value); kết thúc ở dấu chấm phẩy, không có body/endfunction của implementation. Các derived class cung cấp function int apply với cùng formal value. API thống nhất giúp caller dùng một kiểu handle chung.
Hai implementation có miền kiểm rõ
AddRule trả value+3. ClampRule giới hạn phía trên 4 trong miền input 0..7; nó không phải clamp hai phía hoặc parser kiểm input. Main không thử số âm hay overflow, nên bài không suy contract rộng hơn từ tám input này.
Array base handles giữ runtime type riêng
Rules[0] trỏ AddRule, rules[1] trỏ ClampRule. Call apply qua hai base handles phải dùng đúng implementation. Abstract base không làm hai object biến thành cùng công thức hoặc tự clone khi đưa vào array.
Tính tổng từ bảng expected
Add cho 3..10 nên tổng 52. Clamp cho 0/1/2/3/4/4/4/4 nên tổng 22; cộng hai nhóm 74. TB kiểm từng output bằng công thức theo n rồi cộng kết quả để bắt cả lỗi điểm đơn và lỗi accounting.
Compile-time contract cần negative probe riêng
Probe cố tạo Rule trực tiếp phải bị parser từ chối; đó là kiểm constraint của abstract class, khác với simulation pass của hai implementation. Mutation AddRule cộng 4 thay 3 bị runtime symptom pure virtual contract bắt; không đổi expected theo implementation mới.
Hai implementation trên tám input
Expected trước chạy: 8 input,16 kết quả tích luỹ, add_sum52/clamp_sum22/total 74. TB giữ output từng call trong biến để kiểm và cộng tổng, nên count 16 khớp số invocation. Không claim interface class/multiple inheritance hoặc synthesis.
Tự kiểm tra
Ghi API tối thiểu rồi kiểm từng implementation
Abstract base có ích khi caller thật sự cần nhiều implementation của cùng contract. Kiểm signature ở compiler và behavior bằng oracle. Một derived class compile được chưa chứng minh công thức của nó đúng.
Nguồn và mức độ đối chiếu
- SystemVerilog Abstract Class — bản chụp resources.zip, Nguồn đào tạo đã đọc. Trích dẫn; nguồn đã đọc các mục liên quan.
- Thí nghiệm nguyên bản ex.b5.abstract, Bằng chứng thực nghiệm. Trích dẫn; nguồn đã đọc toàn văn.
- IEEE 1800-2023 SystemVerilog LRM, Class handles, inheritance, virtual methods, access and parameterization. Chưa đối chiếu với văn bản nguồn (chưa mở).
- Thí nghiệm nguyên bản ex.b5.abstract, Source, self-checks, verification.json và mutation/capability probes. Trích dẫn; nguồn đã đọc toàn văn.
- SystemVerilog Abstract Class — bản chụp resources.zip, Syntax; Pure Virtual Methods; Pure Method Example. Trích dẫn; nguồn đã đọc các mục liên quan.