הסתרת מידע
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 truemain.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 הפנימיים.
אתגר
קלכתבו את המחלקה 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()))
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח selfמתודותמאפייניםבנאי (_init)חזרה – מחשבון פשוט2מאפייני מחלקה
משתני מופע לעומת משתנים סטטייםפונקציות סטטיותקובעי מאפייניםמאחזרי מאפייניםפרטיים לפי מוסכמהסיכום – מנהל חשבון בנק5כימוס
איברים ציבוריים ופרטייםאימות באמצעות Settersהסתרת מידעמאפיינים לקריאה בלבדסיכום – מערכת לניהול רשומות תלמידיםתרגלו בעצמכם: קומפיילר GDScript אונליין