Menu
CoddyTech

Ôn tập: hồ sơ học sinh

Thuộc phần Lập trình hướng đối tượng trong hành trình GO của Coddy. Bài học 51 trên 107.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống hồ sơ sinh viên minh họa cách đóng gói đúng cách. Bạn sẽ tạo một cấu trúc quản lý sinh viên, trong đó dữ liệu học tập nhạy cảm được bảo vệ nhưng vẫn cho phép truy cập có kiểm soát thông qua các phương thức được thiết kế hợp lý.

Bạn sẽ sắp xếp code trong hai tệp:

  • student.go: Tạo một cấu trúc Student bảo vệ thông tin nhạy cảm nhưng vẫn hiển thị dữ liệu công khai an toàn. Name của sinh viên nên được xuất (có thể truy cập công khai), còn grade (float64) và studentID (string) nên không được xuất để bảo vệ thông tin nhạy cảm này.

    Triển khai những nội dung sau:

    • Một hàm khởi tạo NewStudent(name, id string, initialGrade float64) *Student tạo sinh viên. Chỉ đặt điểm ban đầu nếu điểm nằm trong khoảng từ 0 đến 100 (bao gồm cả hai giá trị); nếu không, mặc định là 0.
    • Một hàm truy xuất Grade() float64 trả về điểm hiện tại
    • Một hàm truy xuất StudentID() string trả về mã sinh viên
    • Một hàm thiết lập SetGrade(newGrade float64) bool chỉ cập nhật điểm nếu giá trị mới nằm trong khoảng từ 0 đến 100 (bao gồm cả hai giá trị). Trả về true nếu điểm được cập nhật, còn lại trả về false.
    • Một phương thức Summary() string trả về định dạng: [Name] (ID: [studentID]) - Grade: [grade]
  • main.go: Đọc thông tin sinh viên từ đầu vào, tạo sinh viên bằng hàm khởi tạo, sau đó thực hiện các thao tác với điểm. Hiển thị bản tóm tắt của sinh viên sau khi tạo và sau mỗi lần thử cập nhật điểm.

Đầu vào sẽ gồm những thông tin sau:

  • Dòng 1: Tên sinh viên
  • Dòng 2: Mã sinh viên
  • Dòng 3: Điểm ban đầu
  • Dòng 4: Điểm mới thứ nhất cần đặt
  • Dòng 5: Điểm mới thứ hai cần đặt

Sau khi tạo sinh viên, hãy in bản tóm tắt của họ. Sau đó, thử cập nhật từng điểm. Nếu cập nhật thành công, hãy in bản tóm tắt đã cập nhật; nếu bị từ chối, hãy in Invalid grade rejected. Định dạng tất cả giá trị điểm với hai chữ số thập phân.

Ví dụ, với Emma Wilson, STU001, 85.5, 92.0 và 150, đầu ra của bạn sẽ là:

Emma Wilson (ID: STU001) - Grade: 85.50
Emma Wilson (ID: STU001) - Grade: 92.00
Invalid grade rejected

Lần cập nhật cuối thất bại vì 150 nằm ngoài phạm vi hợp lệ. Phương thức thiết lập của bạn thực thi quy tắc này, giúp giữ cho dữ liệu của sinh viên luôn hợp lệ. Hãy chú ý rằng studentID và grade không bao giờ có thể được truy cập trực tiếp: code bên ngoài phải dùng các phương thức truy xuất và thiết lập của bạn để tương tác với dữ liệu được bảo vệ này.

Tự làm thử

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Đọc tên học sinh
	name, _ := reader.ReadString('\n')
	name = strings.TrimSpace(name)

	// Đọc mã số học sinh
	id, _ := reader.ReadString('\n')
	id = strings.TrimSpace(id)

	// Đọc điểm ban đầu
	initialGradeStr, _ := reader.ReadString('\n')
	initialGrade, _ := strconv.ParseFloat(strings.TrimSpace(initialGradeStr), 64)

	// Đọc điểm mới thứ nhất
	newGrade1Str, _ := reader.ReadString('\n')
	newGrade1, _ := strconv.ParseFloat(strings.TrimSpace(newGrade1Str), 64)

	// Đọc điểm mới thứ hai
	newGrade2Str, _ := reader.ReadString('\n')
	newGrade2, _ := strconv.ParseFloat(strings.TrimSpace(newGrade2Str), 64)

	// TODO: Tạo học sinh mới bằng hàm khởi tạo (constructor) NewStudent

	// TODO: In ra bản tóm tắt thông tin học sinh sau khi tạo

	// TODO: Thử cập nhật điểm lần thứ nhất
	// Nếu thành công, in ra bản tóm tắt đã cập nhật
	// Nếu bị từ chối, in ra "Invalid grade rejected"

	// TODO: Thử cập nhật điểm lần thứ hai
	// Nếu thành công, in ra bản tóm tắt đã cập nhật
	// Nếu bị từ chối, in ra "Invalid grade rejected"

	// Gợi ý: Dùng fmt.Sprintf với %.2f để định dạng điểm trong Summary()
	_ = newGrade1 // Xóa dòng này khi bạn dùng biến
	_ = newGrade2 // Xóa dòng này khi bạn dùng biến
}

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Go online