Nền tảng học trực tuyến
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 84 trên 87.
Chào mừng bạn đến với chương thử thách cuối cùng! Các thử thách này giúp kiểm tra mức độ thành thạo của bạn về tất cả các khái niệm lập trình hướng đối tượng (OOP) đã học trong khóa học này.
Trong thử thách này, bạn sẽ xây dựng một hệ thống Nền tảng học trực tuyến, kết hợp tính kế thừa, giao diện, tính đa hình, tính đóng gói và các mẫu thiết kế thành một ứng dụng thống nhất.
Nền tảng của bạn nên mô hình hóa mối quan hệ giữa các khóa học, học viên và giảng viên. Hãy nghĩ về cách lớp cơ sở User có thể được mở rộng thành các lớp Student và Instructor, cách các khóa học chứa bài học và cách theo dõi việc đăng ký giữa học viên với khóa học.
Hãy xem xét những nguyên lý OOP nào phù hợp: dùng tính đóng gói để bảo vệ dữ liệu người dùng, tính kế thừa để chia sẻ hành vi chung, giao diện để định nghĩa các hợp đồng như Enrollable hoặc Completable, và tính đa hình để xử lý thống nhất các kiểu người dùng khác nhau.
Chúc bạn vận dụng tốt mọi điều đã học!
Thử thách
DễHãy cùng xây dựng một nền tảng học trực tuyến, kết hợp tất cả các khái niệm OOP bạn đã nắm vững trong khóa học này! Bạn sẽ tạo một hệ thống mô hình hóa mối quan hệ giữa khóa học, học viên và giảng viên bằng cách sử dụng kế thừa (inheritance), giao diện, đa hình và tính đóng gói.
Bạn sẽ sắp xếp code trong sáu tệp:
Enrollable.java: Tạo một giao diện xác định hợp đồng cho các thao tác đăng ký. Giao diện này cần khai báo phương thứcenroll(Student student)trả về giá trị boolean và phương thứcgetEnrolledCount()trả về giá trị int.User.java: Tạo một lớp cơ sở trừu tượng đại diện cho mọi người dùng trên nền tảng. Thêm các trường riêng tư choid(String) vàname(String), một hàm khởi tạo khởi tạo cả hai trường, các hàm getter phù hợp và một phương thức trừu tượnggetRole()trả về chuỗi mô tả vai trò của người dùng.Student.java: Tạo một lớp kế thừaUser. Thêm một ArrayList riêng tư để theo dõi ID các khóa học đã đăng ký. Tạo hàm khởi tạo gọi hàm khởi tạo của lớp cha, triển khaigetRole()để trả về"Student", rồi thêm các phương thứcaddCourse(String courseId)vàgetEnrolledCourseCount(). Ghi đètoString()để trả về"Student: [name] ([enrolledCount] courses)".Instructor.java: Tạo một lớp kế thừaUser. Thêm một trường riêng tư chospecialty(String). Tạo hàm khởi tạo nhận id, name và specialty, triển khaigetRole()để trả về"Instructor", thêm hàm getter cho specialty và ghi đètoString()để trả về"Instructor: [name] - [specialty]".Course.java: Tạo một lớp triển khaiEnrollable. Thêm các trường riêng tư chocourseId(String),title(String),instructor(Instructor) và một ArrayList chứa các học viên đã đăng ký. Hàm khởi tạo nhận courseId, title và instructor. Triển khaienroll(Student student)để thêm học viên vào danh sách, gọi phương thứcaddCourse()của học viên với ID của khóa học này, rồi trả về true. Triển khaigetEnrolledCount(). Thêm phương thứcgetDetails()trả về ID khóa học nằm trong dấu ngoặc vuông, tiếp theo là tiêu đề và tên giảng viên, theo cấu trúc"[" + courseId + "] " + title + " by " + instructorName.Main.java: Xây dựng nền tảng của bạn! Bạn sẽ nhận một chuỗi lệnh phân tách bằng dấu phẩy:ADD_INSTRUCTOR:id:name:specialtyADD_STUDENT:id:nameADD_COURSE:courseId:title:instructorIdENROLL:studentId:courseIdINFO:userId
Quản lý các tập hợp giảng viên, học viên và khóa học. Xử lý từng lệnh rồi in ra:
- ADD_INSTRUCTOR:
Instructor added: [name] - ADD_STUDENT:
Student added: [name] - ADD_COURSE:
Course added: [title] - ENROLL:
[studentName] enrolled in [courseTitle] - INFO: In đầu ra
toString()của người dùng
Sau khi xử lý tất cả lệnh, in
--- Platform Summary ---, tiếp theo là thông tin chi tiết và số lượt đăng ký của từng khóa học theo định dạng[courseDetails] - [count] student(s).
Bạn sẽ nhận một đầu vào: chuỗi lệnh được phân tách bằng dấu phẩy.
Ví dụ, với đầu vào ADD_INSTRUCTOR:I001:Dr. Smith:Java,ADD_STUDENT:S001:Alice,ADD_STUDENT:S002:Bob,ADD_COURSE:C001:OOP Fundamentals:I001,ENROLL:S001:C001,ENROLL:S002:C001,INFO:S001,INFO:I001, đầu ra sẽ là:
Instructor added: Dr. Smith
Student added: Alice
Student added: Bob
Course added: OOP Fundamentals
Alice enrolled in OOP Fundamentals
Bob enrolled in OOP Fundamentals
Student: Alice (1 courses)
Instructor: Dr. Smith - Java
--- Platform Summary ---
[C001] OOP Fundamentals by Dr. Smith - 2 student(s)Thử thách này kết hợp kế thừa (hệ thống phân cấp User), giao diện (Enrollable), tính đa hình (các kiểu người dùng khác nhau với cách triển khai toString riêng) và tính đóng gói (các trường riêng tư với quyền truy cập được kiểm soát) thành một hệ thống thống nhất!
Tự làm thử
import java.util.Scanner;
import java.util.HashMap;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Tạo các tập hợp để lưu giảng viên, học viên và khóa học (course)
// Gợi ý: Dùng HashMap với id làm khóa (key) để dễ tra cứu
// TODO: Tách đầu vào (input) bằng dấu phẩy để lấy từng lệnh (command)
// TODO: Xử lý từng lệnh:
// - ADD_INSTRUCTOR:id:name:specialty -> Tạo giảng viên, thêm vào tập hợp, in ra (print) "Instructor added: [name]"
// - ADD_STUDENT:id:name -> Tạo học viên, thêm vào tập hợp, in ra "Student added: [name]"
// - ADD_COURSE:courseId:title:instructorId -> Tạo khóa học có giảng viên, thêm vào tập hợp, in ra "Course added: [title]"
// - ENROLL:studentId:courseId -> Ghi danh học viên vào khóa học, in ra "[studentName] enrolled in [courseTitle]"
// - INFO:userId -> Tìm người dùng (học viên hoặc giảng viên) và in ra kết quả từ toString()
// TODO: Sau khi xử lý tất cả lệnh, in ra "--- Platform Summary ---"
// TODO: Với mỗi khóa học, in ra "[courseDetails] - [count] student(s)"
}
}
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 hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)11Mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếMẫu SingletonMẫu FactoryMẫu BuilderMẫu ObserverMẫu Strategy14Thử thách cuối cùng
Nền tảng học trực tuyếnHệ thống ngân hàngPhát triển nhân vật trò chơiDịch vụ cho thuê phương tiện3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online