Menu
CoddyTech

הסתרת מידע

חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 28 מתוך 65.

הסתרת מידע הולכת צעד אחד מעבר למשתנים פרטיים: קוד שמשתמש במחלקה תלוי רק במה שהמתודות הציבוריות שלה עושות, ולעולם לא באופן שבו המחלקה מאחסנת את הנתונים שלה. כך אפשר לשנות את אופן האחסון בלי לגעת בקוד הזה.

# 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 קורא ל־add(), ל־count() ול־remove() ולעולם לא נחשף ל־Dictionary. אם בהמשך Inventory ישמור במקום זאת מערך של משבצות, רק inventory.gd ישתנה.

יש להיזהר עם getters שמחזירים מערך או מילון. ‏GDScript מוסרת את הערכים האלה בהפניה: הקוד שקורא לפונקציה מקבל את המערך של האובייקט עצמו, ולא עותק, ויכול לשנות אותו בלי להשתמש בשיטות של המחלקה:

# 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"]

החזר עותק במקום זאת. duplicate() יוצרת מערך חדש עם אותם איברים, כך שהשינויים בו נשארים מחוץ לאובייקט:

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

עבור Dictionary, או Array שמכיל Arrays אחרים, השתמשו ב־duplicate(true): הוא מעתיק גם את ה־Arrays וה־Dictionaries הפנימיים.

challenge icon

אתגר

קל

כתבו את המחלקה Playlist בקובץ playlist.gd. היא שומרת את כותרות השירים במערך הפרטי _songs, וקוד אחר משתמש רק בשיטות האלה:

  • add(title) מוסיפה את הכותרת ומחזירה true. אם הכותרת כבר נמצאת ברשימת ההשמעה, היא לא משנה דבר ומחזירה false.
  • remove(title) מסירה את הכותרת ומחזירה true, או מחזירה false אם היא לא נמצאת ברשימה.
  • count() מחזירה את מספר השירים.
  • get_titles() מחזירה עותק של הכותרות, לפי סדר הוספתן.

הקוד שסופק קורא את מספר הפקודות, ואז פקודה אחת בכל שורה (add Blue Sky או remove Blue Sky) ומדפיס את התוצאה. בסוף הוא לוקח את המערך מ־get_titles(), מוסיף אליו את Intruder והופך את סדר האיברים בו, ואז מדפיס את מספר השירים ואת הכותרות. אסור שרשימת ההשמעה שלך תושפע מהשינויים האלה. עבור הפקודות add Blue Sky, add Rain ו־add Blue Sky יודפס:

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

כתבו את הקוד שלכם בקובץ playlist.gd. הקובץ main.gd מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.

נסו בעצמכם

extends Node

func _ready():
	# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
	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)
	# קוד שמנסה לשנות את הרשימה שהוא מקבל בחזרה
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר GDScript אונליין