Menu
CoddyTech

Ẩn thông tin

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 28 trên 65.

Ẩn thông tin tiến thêm một bước so với biến riêng tư: code sử dụng một lớp chỉ phụ thuộc vào hoạt động của các phương thức công khai, chứ không bao giờ phụ thuộc vào cách lớp lưu trữ dữ liệu. Nhờ đó, bạn có thể thay đổi cách lưu trữ mà không cần chỉnh sửa code đó.

# inventory.gd
class_name Inventory
extends RefCounted

var _counts: Dictionary = {}

func add(item: String, amount: int) -> void:
	_counts[item] = _counts.get(item, 0) + amount

func count(item: String) -> int:
	return _counts.get(item, 0)

func remove(item: String, amount: int) -> bool:
	if count(item) < amount:
		return false
	_counts[item] -= amount
	return true

main.gd gọi add(), count() và remove(), đồng thời không bao giờ thấy từ điển. Nếu sau này Inventory lưu một mảng các ô thay vào đó, chỉ inventory.gd thay đổi.

Hãy cẩn thận với các phương thức getter trả về mảng hoặc từ điển. GDScript truyền các giá trị này bằng tham chiếu: bên gọi nhận chính mảng của đối tượng, không phải bản sao, và có thể thay đổi mảng mà không cần gọi các phương thức của lớp:

# quest_log.gd
var _quests: Array[String] = ["Find the key"]

func get_quests() -> Array[String]:
	return _quests
# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]

Thay vào đó, hãy trả về một bản sao. duplicate() tạo một Array mới với các phần tử giống như bản gốc, vì vậy những thay đổi trên bản sao sẽ không ảnh hưởng đến đối tượng:

func get_quests() -> Array[String]:
	return _quests.duplicate()

Với từ điển hoặc mảng chứa các mảng khác, hãy dùng duplicate(true): thao tác này cũng sao chép các mảng và từ điển bên trong.

challenge icon

Thử thách

Dễ

Viết lớp Playlist trong playlist.gd. Lớp này lưu tiêu đề bài hát trong mảng riêng tư _songs, và code khác chỉ dùng các phương thức sau:

  • add(title) thêm tiêu đề vào cuối danh sách và trả về true. Nếu tiêu đề đã có trong danh sách phát, phương thức không thay đổi gì và trả về false.
  • remove(title) xóa tiêu đề và trả về true, hoặc trả về false nếu tiêu đề không có trong danh sách.
  • count() trả về số bài hát.
  • get_titles() trả về một bản sao các tiêu đề theo thứ tự chúng được thêm vào.

Code được cung cấp đọc số lượng lệnh, sau đó đọc từng lệnh trên một dòng (add Blue Sky hoặc remove Blue Sky) rồi in kết quả. Cuối cùng, code lấy mảng từ get_titles(), thêm Intruder vào cuối rồi đảo ngược mảng, sau đó in số lượng bài hát và các tiêu đề. Danh sách phát của bạn không được bị ảnh hưởng bởi những thay đổi đó. Với các lệnh add Blue Sky, add Rain và add Blue Sky, chương trình in ra:

Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, Rain

Viết code của bạn trong playlist.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ó sẵn: giữ nguyên
	var playlist := Playlist.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ", true, 1)
		var title := parts[1]
		if parts[0] == "add":
			if playlist.add(title):
				print("Added: " + title)
			else:
				print("Already in the playlist: " + title)
		elif playlist.remove(title):
			print("Removed: " + title)
		else:
			print("Not found: " + title)
	# Đoạn code thử thay đổi danh sách nhận về
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
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