Menu
CoddyTech

Lớp bên trong

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

Một lớp có thể khai báo một lớp khác bên trong bằng từ khóa class, một tên và phần thân được thụt lề. Lớp bên trong là một kiểu hỗ trợ thuộc về lớp bên ngoài:

# inventory.gd
class_name Inventory
extends RefCounted

const MAX_STACK := 5

class Slot:
	var item_name: String
	var count: int

	func _init(new_name: String, new_count: int) -> void:
		item_name = new_name
		count = mini(new_count, MAX_STACK)

	func _to_string() -> String:
		return "%s x%d" % [item_name, count]

var slots: Array[Slot] = []

func add(item_name: String, count: int) -> Slot:
	var slot := Slot.new(item_name, count)
	slots.append(slot)
	return slot

Bên trong inventory.gd, lớp bên trong có tên là Slot. Mọi tệp khác truy cập lớp này thông qua lớp bên ngoài: Inventory.Slot.

# main.gd
var bag := Inventory.new()
bag.add("Potion", 9)
var arrows: Inventory.Slot = bag.add("Arrow", 3)
print(bag.slots)    # [Potion x5, Arrow x3]
var gem := Inventory.Slot.new("Gem", 1)

Lớp bên trong không có extends sẽ kế thừa RefCounted, và có thể có biến, hàm khởi tạo và phương thức như mọi lớp khác. Lớp này có thể dùng các hằng số và enum của lớp bên ngoài (MAX_STACK ở trên), nhưng không thể dùng các biến thành viên của lớp đó: Slot không thể truy cập slots, vì một ô là một đối tượng riêng biệt. Hãy truyền mọi giá trị cần thiết vào hàm khởi tạo của nó.

Dùng một lớp bên trong cho kiểu dữ liệu nhỏ chỉ có ý nghĩa khi đi cùng lớp bên ngoài, chẳng hạn như một ô trong kho đồ hoặc một mục trong bảng điểm. Một kiểu dữ liệu mà các phần khác của trò chơi sử dụng độc lập thì nên có tệp riêng và class_name.

challenge icon

Thử thách

Dễ

Hãy tạo một Leaderboard có các mục là một lớp bên trong.

  • Khai báo lớp bên trong Entry trong Leaderboard, với player_name và score được thiết lập bằng hàm khởi tạo (constructor), còn _to_string() trả về Ada: 120.
  • entries là một mảng có kiểu Entry, theo thứ tự người chơi xuất hiện lần đầu.
  • submit(player, score) thêm một mục mới cho người chơi mới. Với người chơi đã có mục, hàm giữ lại điểm cao hơn trong hai điểm.
  • best() trả về mục có điểm cao nhất. Nếu hòa điểm, mục xuất hiện trước sẽ thắng.

Code được cung cấp đọc số điểm sắp được nhập (Ada 120), gửi các điểm đó, rồi in ra mọi mục và mục tốt nhất (luôn có ít nhất một điểm). Với Ada 120, Bo 90, Ada 80, Bo 150, Cy 150, chương trình in ra:

Ada: 120
Bo: 150
Cy: 150
Best: Bo: 150

Đặt code của bạn trong leaderboard.gd. main.gd chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

extends Node

func _ready():
	# Đoạn code đầu vào/đầu ra được cung cấp sẵn: giữ nguyên
	var board := Leaderboard.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		board.submit(parts[0], int(parts[1]))
	for entry in board.entries:
		print(entry)
	print("Best: ", board.best())
quiz iconTự kiểm tra

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

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