Skip to content

Chương 9

Luyện dịch UML thành chương trình

Chương này không có lý thuyết. Sáu bài, mỗi bài chỉ cho bạn một sơ đồ UML và một khối kết quả mong đợi — không mô tả bằng lời. Nhiệm vụ luôn giống nhau: viết ra chương trình chạy đúng.

Cách luyện

1. Bấm giờ. Con số “mục tiêu” là thời gian một sinh viên đã quen tay cần dùng. Lần đầu chậm hơn là bình thường; điều quan trọng là lần thứ ba phải nhanh hơn lần đầu.

2. Đóng sách, chỉ để lại trang có sơ đồ. Không mở chương trước, không mở lời giải.

3. Xong thì so output từng dòng. Khớp tuyệt đối mới tính là xong.

4. Chỉ mở lời giải sau khi đã hết giờ. Lời giải nằm ở giaotrinh/vi_du/luyen_uml/baiN/.

5. Làm lại bài đã sai sau một tuần. Làm một bài ba lần cách quãng có ích hơn làm ba bài một lần.

Sáu bài tăng dần đúng theo thứ tự các chương: một lớp → đóng gói → kế thừa → ba tầng → trừu tượng và đa hình → đủ cả ngoại lệ. Bài 5 và bài 6 đã ở đúng mức của đề thi thật.

Bài 1 — Một lớp (mục tiêu: 8 phút)

Mục tiêu 8 phút08:00Chưa bắt đầu
Hình 9.1 — Bài 1: lớp Student.Hình 9.1 — Bài 1: lớp Student.
Hình 9.1 — Bài 1: lớp Student.

Trong main(): tạo một sinh viên bằng constructor đầy đủ, một sinh viên bằng constructor mặc định, gọi display() cho cả hai. Constructor mặc định đặt "???", "Chua co ten", 0.0.

Kết quả mong đợi:

text
[SV] 23130007 | Tran Thi Binh | GPA 3.4
[SV] ??? | Chua co ten | GPA 0

Đạt yêu cầu: 3 file, biên dịch một lệnh, output khớp.

Lời giải bài 1

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bài 2 — Đóng gói và kiểm tra dữ liệu (mục tiêu: 12 phút)

Mục tiêu 12 phút12:00Chưa bắt đầu
Hình 9.2 — Bài 2: lớp BankAccount.Hình 9.2 — Bài 2: lớp BankAccount.
Hình 9.2 — Bài 2: lớp BankAccount.

Luật nghiệp vụ (phần sơ đồ không nói được, đề bài phải nói):

  • deposit: số tiền ≤ 0 thì in ! So tien nap phai duong. Bo qua. và không đổi số dư.
  • withdraw: số tiền ≤ 0 thì từ chối; lớn hơn số dư thì in ! So du khong du. Hien co <so du> và trả false.
  • Constructor: số dư âm thì đặt về 0.

Trong main(): tài khoản 500000 → in → nạp 200000 → nạp −50000 → rút 1000000 → rút 300000 → in.

Kết quả mong đợi:

text
[TK] 0123456789 | Nguyen Van An | So du 500000
  Da nap 200000, so du 700000
  ! So tien nap phai duong. Bo qua.
  ! So du khong du. Hien co 700000
  Da rut 300000, so du 400000
[TK] 0123456789 | Nguyen Van An | So du 400000
Lời giải bài 2

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bài 3 — Kế thừa đơn (mục tiêu: 15 phút)

Mục tiêu 15 phút15:00Chưa bắt đầu
Hình 9.3 — Bài 3: Employee và lớp con Manager.Hình 9.3 — Bài 3: Employee và lớp con Manager.
Hình 9.3 — Bài 3: Employee và lớp con Manager.

totalPay() = lương + thưởng. Trong main(): một nhân viên, một quản lý, gọi display() cho cả hai.

Kết quả mong đợi:

text
[NV] NV001 | Tran Thi Binh | Luong 12000000
[QL] QL001 | Le Minh Cuong | Phong Ky thuat | Luong 25000000 + thuong 8000000 = 33000000

Hai chỗ bài này kiểm tra

Dấu # trên sơ đồ → protected, để Manager::display() dùng được namesalary.

Constructor của Manager phải gọi : Employee(id, name, salary) ở danh sách khởi tạo. Quên là không biên dịch được.

Lời giải bài 3

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bài 4 — Kế thừa ba tầng và đa hình (mục tiêu: 20 phút)

Mục tiêu 20 phút20:00Chưa bắt đầu
Hình 9.4 — Bài 4: chuỗi Person → Teacher → HeadTeacher.Hình 9.4 — Bài 4: chuỗi Person → Teacher → HeadTeacher.
Hình 9.4 — Bài 4: chuỗi Person → Teacher → HeadTeacher.

Trong main(): mảng Person* ds[3] chứa một Person, một Teacher, một HeadTeacher; duyệt và gọi ds[i]->show(); cuối cùng delete cả ba.

Kết quả mong đợi:

text
[NGUOI] Nguyen Van An, 40 tuoi
[GV] Tran Thi Binh, 35 tuoi, day Vat ly
[TRUONG BO MON] Le Minh Cuong, 50 tuoi, day Toan, phu trach Khoa hoc co ban

Tự kiểm: nếu ba dòng in ra giống hệt nhau và đều bắt đầu bằng [NGUOI] thì bạn quên virtual. Đó chính là lỗi đáng 2 điểm ở mọi đề thi.

Lời giải bài 4

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bài 5 — Lớp trừu tượng — mức đề thi (mục tiêu: 30 phút)

Mục tiêu 30 phút30:00Chưa bắt đầu
Hình 9.5 — Bài 5: lớp trừu tượng Shape và ba hình.Hình 9.5 — Bài 5: lớp trừu tượng Shape và ba hình.
Hình 9.5 — Bài 5: lớp trừu tượng Shape và ba hình.
  • Diện tích: hình tròn 3.14159 * r * r; chữ nhật w * h; tam giác base * height / 2.
  • Shape::display() có thân hàm sẵn ở lớp cha, in dạng [<typeName>] <name> | Dien tich: <area> — lưu ý nó gọi hai hàm thuần ảo của chính lớp con.
  • Trong main(): vector<Shape*> chứa ba hình, duyệt gọi display(), cộng dồn tổng diện tích, rồi delete hết.

Kết quả mong đợi (Circle 2.0; Rectangle 3.0 × 4.0; Triangle 6.0 × 5.0):

text
[HINH TRON] C1 | Dien tich: 12.5664
[HINH CHU NHAT] R1 | Dien tich: 12
[HINH TAM GIAC] T1 | Dien tich: 15
Tong dien tich: 39.5664

Bài này đáng mấy điểm nếu là đề thi

Tính trừu tượng 1 · Thiết kế lớp trừu tượng và kế thừa 2 · Đa hình qua con trỏ 1 · Đóng gói 1 · Chạy đúng 3 · Chia file 2 · UML bonus 2.

Làm được bài này trong 30 phút nghĩa là bạn xong một đề thi thật trong 30 phút, còn dư 30 phút để dò lại.

Lời giải bài 5

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bài 6 — Trừu tượng + giao diện + ngoại lệ — mức đề thi khó (mục tiêu: 45 phút)

Mục tiêu 45 phút45:00Chưa bắt đầu
Hình 9.6 — Bài 6: Payment, giao diện Refundable và ngoại lệ NotRefundable.Hình 9.6 — Bài 6: Payment, giao diện Refundable và ngoại lệ NotRefundable.
Hình 9.6 — Bài 6: Payment, giao diện Refundable và ngoại lệ NotRefundable.
  • Constructor Payment: số tiền ≤ 0 thì ném invalid_argument("So tien khong hop le: <amount>").
  • CashPayment: method() = "TIEN MAT", phí 0. Không ký giao diện.
  • CardPayment: method() = "THE", phí 1% số tiền, display() in thêm tên ngân hàng. Hoàn quá số còn lại thì ném NotRefundable(code).
  • Trong main(): tạo 3 giao dịch (giao dịch thứ ba số tiền âm), in danh sách, rồi với mỗi giao dịch dùng dynamic_cast<Refundable*> để thử hoàn 500000 rồi hoàn tiếp 5000000.

Kết quả mong đợi:

text
--- TAO GIAO DICH ---
  [Du lieu sai] So tien khong hop le: -1000
--- DANH SACH ---
[TIEN MAT] GD001 | So tien: 500000 | Phi: 0
[THE] GD002 | Ngan hang Vietcombank | So tien: 2000000 | Phi: 20000
--- HOAN TIEN ---
  GD001: khong hoan tien duoc.
    Da hoan 500000, con hoan duoc 1500000
  [Khong hoan] Giao dich khong hoan tien duoc: GD002
Chuong trinh ket thuc binh thuong.

Bài khó nhất trong sách

Nó gộp cả bảy chương: đóng gói, kế thừa, đa hình, lớp trừu tượng, giao diện, ngoại lệ tự định nghĩa, và dynamic_cast. Làm được bài này trong 45 phút thì không đề thi nào của môn làm khó được bạn.

Chú ý một chi tiết dễ bỏ sót: giao dịch thứ ba ném ngoại lệ ngay trong constructor, nên nó không bao giờ được đưa vào danh sách — vì vậy phần “DANH SACH” chỉ có hai dòng.

Lời giải bài 6

Lời giải tự mở khi đồng hồ ở đầu bài hết giờ, hoặc khi bạn bấm Tôi đã làm xong. Đọc lời giải trước khi tự viết là bỏ qua đúng thứ bài này luyện: nhìn sơ đồ và viết ra được chương trình.

Bảng theo dõi

Chép bảng này ra một file text và ghi lại sau mỗi lần làm. Cột thời gian mới là thứ cho biết bạn đã sẵn sàng thi hay chưa — không phải cảm giác “bài này mình hiểu rồi”.

BàiMục tiêuLần 1Lần 2Lần 3Output khớp?
1 — Student8 phút
2 — BankAccount12 phút
3 — Employee/Manager15 phút
4 — Person 3 tầng20 phút
5 — Shape trừu tượng30 phút
6 — Payment đầy đủ45 phút

Mốc sẵn sàng thi: bài 5 không quá 30 phút, bài 6 không quá 45 phút, output khớp từng ký tự.

Bấm “Tôi đã làm xong” ở đồng hồ đầu mỗi bài, số phút sẽ tự điền vào ô trống đầu tiên. Số liệu chỉ lưu trong trình duyệt này.

Khi nào thì coi là sẵn sàng thi

Làm được bài 5 dưới 30 phút và bài 6 dưới 45 phút, với output khớp từng ký tự, không mở tài liệu.

Nếu chưa đạt, đừng đọc lại lý thuyết — hãy làm lại chính bài đó. Khoảng cách giữa “hiểu” và “viết ra được” chỉ đóng lại bằng cách gõ.

Đọc xong và tự làm hết phần “Tự kiểm tra” rồi hãy đánh dấu.

© 2026 Ngan V.T. Nguyen · Nội dung theo giấy phép CC BY-NC-SA 4.0 · Code ví dụ theo giấy phép MIT · Ảnh của bên thứ ba giữ giấy phép riêng, ghi ở Phụ lục E

Nội dung theo giấy phép CC BY-NC-SA 4.0 · Code ví dụ theo giấy phép MIT · Ảnh của bên thứ ba giữ giấy phép riêng, ghi ở Phụ lục E