Tạo bởi Trần Văn Điêp|
C Sharp

[Video] Chương trình quản lý sách - Develop Book Project - Lập Trình C# - OOP trong C# - C Sharp - C2010G


Chương trình quản lý sách - Develop Book Project - Lập Trình C# - OOP trong C# - C Sharp

1. Tổng quan bài toán

Bạn cần xây dựng ứng dụng quản lý sách Aptech gồm hai loại đối tượng:

  • Book: lớp cơ bản mô tả một cuốn sách thông thường.

  • AptechBook: lớp kế thừa từ Book, thêm thông tin chuyên biệt cho sách lập trình Aptech như ngôn ngữ lập trình và kỳ học.

Chương trình có các chức năng:

  1. Nhập danh sách sách Aptech

  2. Hiển thị danh sách sách

  3. Sắp xếp theo năm xuất bản

  4. Tìm kiếm theo tên sách

  5. Tìm kiếm theo tên tác giả

  6. Lưu danh sách sách ra file books.txt

  7. Đọc danh sách sách từ file books.txt

  8. Thoát chương trình


2. Cấu trúc chương trình

Chương trình gồm 3 file:

BT1458/ │ ├── Book.cs ├── AptechBook.cs └── Program.cs

Mỗi file đảm nhiệm một vai trò riêng:

  • Book.cs: Định nghĩa lớp cha Book

  • AptechBook.cs: Kế thừa từ Book và mở rộng tính năng

  • Program.cs: Xử lý menu, nhập/xuất, tìm kiếm, lưu/đọc file


3. Phân tích từng lớp


🧩 Lớp Book

Chức năng:
Lưu trữ các thông tin cơ bản của một cuốn sách:

  • Tên sách

  • Tác giả

  • Nhà sản xuất

  • Năm xuất bản

  • Giá bán

Các thành phần chính:

✅ Thuộc tính

public string BookName { get; set; } public string BookAuthor { get; set; } public string Producer { get; set; } public string YearPublishing { get; set; } public int Price { get; set; }

Cách khai báo này sử dụng auto-properties của C#, giúp mã ngắn gọn mà vẫn đảm bảo tính đóng gói (Encapsulation).

✅ Constructors

public Book() { } public Book(string bookName, string bookAuthor, string producer, string yearPublishing, int price) { BookName = bookName; BookAuthor = bookAuthor; Producer = producer; YearPublishing = yearPublishing; Price = price; }

Gồm:

  • Constructor mặc định.

  • Constructor có tham số (để khởi tạo nhanh giá trị khi tạo đối tượng mới).

✅ Phương thức Input()

Nhập dữ liệu từ bàn phím:

public virtual void Input() { Console.WriteLine("Nhap ten sach: "); BookName = Console.ReadLine(); ... }

Dùng virtual để cho phép lớp con ghi đè (override) khi cần mở rộng logic nhập.

✅ Phương thức Display()ToString()

public void Display() => Console.WriteLine(this); public override string ToString() { return "Ten sach: " + BookName + ", ten tac gia: " + BookAuthor + ", NSX: " + Producer + ", nam xuat ban: " + YearPublishing + ", gia ban: " + Price; }

ToString() giúp hiển thị thông tin dễ đọc. Khi gọi Console.WriteLine(this);, C# tự động gọi ToString().

✅ Phương thức GetFileLine()

Dùng để chuyển một đối tượng Book thành chuỗi lưu vào file:

public virtual string GetFileLine() { return BookName + "," + BookAuthor + "," + Producer + "," + YearPublishing + "," + Price + "\n"; }

📚 Lớp AptechBook

Kế thừa từ: Book
Thêm thuộc tính riêng:

public string Language { get; set; } public string Semester { get; set; }

✅ Constructor kế thừa

public AptechBook(string language, string semester, string bookName, string bookAuthor, string producer, string yearPublishing, int price) : base(bookName, bookAuthor, producer, yearPublishing, price) { Language = language; Semester = semester; }

Từ khóa : base(...) giúp gọi constructor lớp cha để tránh lặp lại code.

✅ Ghi đè phương thức Input()

public override void Input() { base.Input(); Console.WriteLine("Nhap ngon ngu lap trinh: "); Language = Console.ReadLine(); Console.WriteLine("Nhap ky hoc: "); Semester = Console.ReadLine(); }

Dùng base.Input() để tái sử dụng phần nhập của lớp Book, sau đó nhập thêm phần riêng của AptechBook.

✅ Override ToString()GetFileLine()

public override string ToString() { return "Ngon ngu lap trinh: " + Language + ", ky hoc: " + Semester + ", " + base.ToString(); } public override string GetFileLine() { return Language + "," + Semester + "," + base.GetFileLine(); }

Giúp hiển thị và lưu file đầy đủ cả thông tin của lớp cha và lớp con.

✅ ParseFileLine()

Dùng để đọc dữ liệu từ file text và gán lại vào đối tượng:

public void ParseFileLine(string line) { string[] elements = line.Split(","); Language = elements[0]; Semester = elements[1]; BookName = elements[2]; BookAuthor = elements[3]; Producer = elements[4]; YearPublishing = elements[5]; Price = int.Parse(elements[6]); }

🧮 Lớp Program

Đây là lớp điều khiển chính (Main) chứa menu thao tác.

✅ Menu chính

static void ShowMenu() { Console.WriteLine("1. Nhap N sach"); Console.WriteLine("2. Hien thi"); Console.WriteLine("3. Sap xep theo nam xuat ban"); Console.WriteLine("4. Tim kiem theo ten sach"); Console.WriteLine("5. Tim kiem theo tac gia"); Console.WriteLine("6. Luu books.txt"); Console.WriteLine("7. Doc books.txt"); Console.WriteLine("8. Thoat"); Console.WriteLine("Chon: "); }

Chạy trong vòng lặp do...while để lặp lại cho đến khi người dùng chọn “8 – Thoát”.

✅ Chức năng 1 – Nhập sách

private static void Input() { Console.WriteLine("Nhap so sach can them N = "); int N = int.Parse(Console.ReadLine()); bookList = new AptechBook[N]; for (int i = 0; i < N; i++) { Console.WriteLine("Nhap thong tin sach thu {0}", i + 1); AptechBook aptechBook = new AptechBook(); aptechBook.Input(); bookList[i] = aptechBook; } }

✅ Chức năng 2 – Hiển thị danh sách

private static void Display() { Console.WriteLine("Thong tin sach: "); for (int i = 0; i < bookList.Length; i++) { bookList[i].Display(); } }

✅ Chức năng 3 – Sắp xếp theo năm xuất bản

Array.Sort<AptechBook>(bookList, (b1, b2) => { return b1.YearPublishing.CompareTo(b2.YearPublishing); });

Sử dụng Array.Sort() với lambda expression để sắp xếp theo YearPublishing.

✅ Chức năng 4 & 5 – Tìm kiếm

Tìm theo tên sách hoặc tác giả, duyệt mảng và so sánh chuỗi.

✅ Chức năng 6 – Lưu file

private static void SaveFile() { string content = ""; for (int i = 0; i < bookList.Length; i++) content += bookList[i].GetFileLine(); File.WriteAllText(@"books.txt", content); Console.WriteLine("Luu file thanh cong!!!"); }

Mỗi dòng trong file tương ứng một đối tượng AptechBook.

✅ Chức năng 7 – Đọc file

private static void ReadFile() { string content = File.ReadAllText(@"books.txt"); if (string.IsNullOrWhiteSpace(content)) return; string[] lines = content.Split("\n"); bookList = new AptechBook[lines.Length]; for (int i = 0; i < lines.Length; i++) { if (lines[i] == "") continue; AptechBook aptechBook = new AptechBook(); aptechBook.ParseFileLine(lines[i]); bookList[i] = aptechBook; } }

Đọc toàn bộ file, tách theo dòng, và tái tạo lại danh sách đối tượng.


4. Một số lưu ý & mẹo học OOP hiệu quả

  • Tính đóng gói (Encapsulation):
    Dùng get; set; để bảo vệ dữ liệu, không cho truy cập trực tiếp từ bên ngoài.

  • Tính kế thừa (Inheritance):
    Giúp tái sử dụng code, ví dụ AptechBook kế thừa toàn bộ Book.

  • Tính đa hình (Polymorphism):
    Sử dụng virtualoverride để phương thức có thể tùy biến theo từng lớp con.

  • Xử lý file:
    Sử dụng File.ReadAllText()File.WriteAllText() giúp thao tác nhanh gọn.


5. Kết luận

Qua bài tập này, bạn đã học được:

  • Cách định nghĩa và kế thừa lớp trong C#

  • Cách ghi đè phương thức (override)

  • Cách nhập, hiển thị, tìm kiếm, sắp xếp dữ liệu

  • Cách lưu trữ dữ liệu vào file và đọc lại từ file

🎯 Mục tiêu quan trọng:
Hiểu rõ cách tổ chức chương trình hướng đối tượng, làm nền tảng để phát triển các dự án thực tế lớn hơn (quản lý sinh viên, nhân viên, sản phẩm...).

💡 Gợi ý mở rộng:

  • Thêm chức năng xóa hoặc cập nhật thông tin sách.

  • Lưu dữ liệu ở định dạng JSON hoặc XML.

  • Xây dựng giao diện WinForms hoặc WPF để quản lý sách trực quan.


📘 Book.cs

using System; namespace BT1458 { public class Book { public string BookName { get; set; } public string BookAuthor { get; set; } public string Producer { get; set; } public string YearPublishing { get; set; } public int Price { get; set; } public Book() { } public Book(string bookName, string bookAuthor, string producer, string yearPublishing, int price) { BookName = bookName; BookAuthor = bookAuthor; Producer = producer; YearPublishing = yearPublishing; Price = price; } public virtual void Input() { Console.WriteLine("Nhập tên sách: "); BookName = Console.ReadLine(); Console.WriteLine("Nhập tên tác giả: "); BookAuthor = Console.ReadLine(); Console.WriteLine("Nhập nhà sản xuất: "); Producer = Console.ReadLine(); Console.WriteLine("Nhập năm xuất bản: "); YearPublishing = Console.ReadLine(); Console.WriteLine("Nhập giá bán: "); Price = int.Parse(Console.ReadLine()); } public virtual void Display() { Console.WriteLine(ToString()); } public override string ToString() { return $"Tên sách: {BookName}, Tác giả: {BookAuthor}, NSX: {Producer}, Năm XB: {YearPublishing}, Giá: {Price}"; } public virtual string GetFileLine() { return $"{BookName},{BookAuthor},{Producer},{YearPublishing},{Price}\n"; } } }

📗 AptechBook.cs

using System; namespace BT1458 { public class AptechBook : Book { public string Language { get; set; } public string Semester { get; set; } public AptechBook() { } public AptechBook(string language, string semester, string bookName, string bookAuthor, string producer, string yearPublishing, int price) : base(bookName, bookAuthor, producer, yearPublishing, price) { Language = language; Semester = semester; } public override void Input() { base.Input(); Console.WriteLine("Nhập ngôn ngữ lập trình: "); Language = Console.ReadLine(); Console.WriteLine("Nhập kỳ học: "); Semester = Console.ReadLine(); } public override void Display() { Console.WriteLine(ToString()); } public override string ToString() { return $"Ngôn ngữ: {Language}, Kỳ học: {Semester}, {base.ToString()}"; } public override string GetFileLine() { return $"{Language},{Semester},{base.GetFileLine()}"; } public void ParseFileLine(string line) { string[] elements = line.Split(","); if (elements.Length < 7) return; Language = elements[0]; Semester = elements[1]; BookName = elements[2]; BookAuthor = elements[3]; Producer = elements[4]; YearPublishing = elements[5]; Price = int.Parse(elements[6]); } } }

📙 Program.cs

using System; using System.IO; namespace BT1458 { class Program { static AptechBook[] bookList; static void Main(string[] args) { int choose; do { ShowMenu(); Console.Write("Chọn chức năng: "); choose = int.Parse(Console.ReadLine()); switch (choose) { case 1: InputBooks(); break; case 2: DisplayBooks(); break; case 3: SortByYearPublishing(); DisplayBooks(); break; case 4: SearchByBookName(); break; case 5: SearchByAuthor(); break; case 6: SaveToFile(); break; case 7: ReadFromFile(); DisplayBooks(); break; case 8: Console.WriteLine("Thoát chương trình!"); break; default: Console.WriteLine("Lựa chọn không hợp lệ, vui lòng thử lại!"); break; } Console.WriteLine("-------------------------------------------"); } while (choose != 8); } static void ShowMenu() { Console.WriteLine("========= MENU QUẢN LÝ SÁCH APTECH ========="); Console.WriteLine("1. Nhập N sách"); Console.WriteLine("2. Hiển thị danh sách sách"); Console.WriteLine("3. Sắp xếp theo năm xuất bản (giảm dần)"); Console.WriteLine("4. Tìm kiếm theo tên sách"); Console.WriteLine("5. Tìm kiếm theo tác giả"); Console.WriteLine("6. Lưu danh sách vào file (books.txt)"); Console.WriteLine("7. Đọc danh sách từ file (books.txt)"); Console.WriteLine("8. Thoát"); Console.WriteLine("============================================"); } static void InputBooks() { Console.Write("Nhập số lượng sách N = "); int N = int.Parse(Console.ReadLine()); bookList = new AptechBook[N]; for (int i = 0; i < N; i++) { Console.WriteLine($"\nNhập thông tin sách thứ {i + 1}:"); AptechBook book = new AptechBook(); book.Input(); bookList[i] = book; } } static void DisplayBooks() { if (bookList == null || bookList.Length == 0) { Console.WriteLine("Chưa có dữ liệu sách để hiển thị!"); return; } Console.WriteLine("\n=== DANH SÁCH SÁCH APTECH ==="); foreach (AptechBook book in bookList) { book.Display(); } } static void SortByYearPublishing() { if (bookList == null || bookList.Length == 0) { Console.WriteLine("Danh sách trống, không thể sắp xếp!"); return; } Array.Sort(bookList, (b1, b2) => { return b2.YearPublishing.CompareTo(b1.YearPublishing); }); Console.WriteLine("Đã sắp xếp danh sách theo năm xuất bản giảm dần!"); } static void SearchByBookName() { Console.Write("Nhập tên sách cần tìm: "); string name = Console.ReadLine(); bool found = false; foreach (AptechBook book in bookList) { if (book.BookName.Equals(name, StringComparison.OrdinalIgnoreCase)) { book.Display(); found = true; } } if (!found) Console.WriteLine("Không tìm thấy sách có tên này!"); } static void SearchByAuthor() { Console.Write("Nhập tên tác giả cần tìm: "); string author = Console.ReadLine(); bool found = false; foreach (AptechBook book in bookList) { if (book.BookAuthor.Equals(author, StringComparison.OrdinalIgnoreCase)) { book.Display(); found = true; } } if (!found) Console.WriteLine("Không tìm thấy sách của tác giả này!"); } static void SaveToFile() { if (bookList == null || bookList.Length == 0) { Console.WriteLine("Không có dữ liệu để lưu!"); return; } string content = ""; foreach (AptechBook book in bookList) { content += book.GetFileLine(); } File.WriteAllText(@"books.txt", content); Console.WriteLine("Đã lưu dữ liệu vào file books.txt thành công!"); } static void ReadFromFile() { string path = @"books.txt"; if (!File.Exists(path)) { Console.WriteLine("File không tồn tại!"); return; } string[] lines = File.ReadAllLines(path); if (lines.Length == 0) { Console.WriteLine("File rỗng!"); return; } bookList = new AptechBook[lines.Length]; for (int i = 0; i < lines.Length; i++) { if (string.IsNullOrWhiteSpace(lines[i])) continue; AptechBook book = new AptechBook(); book.ParseFileLine(lines[i]); bookList[i] = book; } Console.WriteLine("Đọc dữ liệu từ file thành công!"); } } }

Tính năng trong chương trình

  1. Nhập danh sách N sách Aptech.

  2. Hiển thị danh sách sách đã nhập.

  3. Sắp xếp danh sách theo năm xuất bản giảm dần.

  4. Tìm kiếm theo tên sách.

  5. Tìm kiếm theo tên tác giả.

  6. Lưu dữ liệu vào file books.txt.

  7. Đọc dữ liệu từ file books.txt.

  8. Thoát chương trình.

Phản hồi từ học viên

5

Tổng 0 đánh giá

Đăng nhập để làm bài kiểm tra

Chưa có kết quả nào trước đó