חזרה על דריסת מתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GDScript של Coddy. שיעור 21 מתוך 65.
רב־צורתיות פירושה "צורות רבות": אותה קריאה למתודה עושה דברים שונים בהתאם למחלקה של האובייקט שמקבל אותה. דריסת מתודות היא מה שמאפשר זאת.
# animal.gd
class_name Animal
extends RefCounted
func speak() -> String:
return "..."# dog.gd
class_name Dog
extends Animal
func speak() -> String:
return "Woof!"# cat.gd
class_name Cat
extends Animal
func speak() -> String:
return "Meow!"מערך מסוג Array[Animal] יכול להכיל את כולם. הלולאה קוראת ל־speak() בלי לדעת לאיזו מחלקה שייך כל איבר, וכל אובייקט עונה בגרסה משלו:
var animals: Array[Animal] = [Dog.new(), Cat.new(), Animal.new()]
for animal in animals:
print(animal.speak())Woof!
Meow!
...פונקציה עם פרמטר מסוג Animal פועלת באותו אופן. היא מקבלת כל מחלקת־צאצא, כולל מחלקות שתוסיפו בהמשך, ללא שינוי:
func make_it_speak(animal: Animal) -> void:
print("It says ", animal.speak())make_it_speak(Cat.new())It says Meow!השווה זאת לבדיקה של המחלקות אחת־אחת. שרשרת של ענפי if animal is Dog: חייבת לגדול עם כל מחלקה חדשה. עם דריסה, כל מחלקה נושאת את ההתנהגות שלה, והקוד שקורא לה נשאר זהה.
אתגר
קלמוסך מטפל בכל כלי הרכב באמצעות Array[Vehicle] אחד. ב־vehicle.gd, הפונקציה wheels() מחזירה 0 והפונקציה sound() מחזירה ....
- כתבו את
describe()במחלקהVehicle. היא מחזירהBRAND: N wheels, SOUND, תוך קריאה ל־wheels()ול־sound(). Carדורס אתwheels()ומחזיר4, ואתsound()ומחזירVroom.Motorcycleדורס אותן ומחזיר2ו־Brrm.Truckכבר שומר את מספר ה־trailersשלו. הוא דורס אתwheels()ומחזיר6ועוד4לכל גרור, ואתsound()ומחזירHonk.
המחלקות היורשות אינן דורסות את describe(). הקוד שסופק קורא כמה כלי רכב מופיעים אחר כך, ואז שורה אחת לכל כלי רכב: car BRAND, motorcycle BRAND, truck BRAND TRAILERS או vehicle BRAND. הוא מדפיס את התוצאה של כל קריאה ל־describe() ואת הסכום הכולל של wheels(). עבור car Toyota ו־truck Volvo 2 הוא מדפיס:
Toyota: 4 wheels, Vroom
Volvo: 14 wheels, Honk
Total wheels: 18הקוד שלכם ייכתב בקבצים vehicle.gd, car.gd, motorcycle.gd ו־truck.gd. הקובץ main.gd מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.
נסו בעצמכם
extends Node
func _ready():
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var count := int(OS.read_string_from_stdin())
var vehicles: Array[Vehicle] = []
for i in count:
var p := OS.read_string_from_stdin().split(" ")
if p[0] == "car":
vehicles.append(Car.new(p[1]))
elif p[0] == "motorcycle":
vehicles.append(Motorcycle.new(p[1]))
elif p[0] == "truck":
vehicles.append(Truck.new(p[1], int(p[2])))
else:
vehicles.append(Vehicle.new(p[1]))
var total := 0
for v in vehicles:
print(v.describe())
total += v.wheels()
print("Total wheels: %d" % total)
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםמבוא ל-OOPמחלקות לעומת אובייקטיםמילת המפתח selfמתודותמאפייניםבנאי (_init)חזרה – מחשבון פשוט4פולימורפיזם
חזרה על דריסת מתודותטיפוס ברווזמחלקות ומתודות אבסטרקטיותתכנון ממשקיםסיכום - מחשבון צורות2מאפייני מחלקה
משתני מופע לעומת משתנים סטטייםפונקציות סטטיותקובעי מאפייניםמאחזרי מאפייניםפרטיים לפי מוסכמהסיכום – מנהל חשבון בנק5כימוס
איברים ציבוריים ופרטייםאימות באמצעות Settersהסתרת מידעמאפיינים לקריאה בלבדסיכום – מערכת לניהול רשומות תלמידיםתרגלו בעצמכם: קומפיילר GDScript אונליין