Menu
CoddyTech

שרשראות ירושה

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

מחלקת ילד יכולה בעצמה להיות מחלקת אב. כל extends מוסיף רמה אחת לשרשרת הירושה:

# vehicle.gd
class_name Vehicle
extends RefCounted

var wheels: int

func _init(w: int) -> void:
	wheels = w

func describe() -> String:
	return "%d wheels" % wheels
# car.gd
class_name Car
extends Vehicle

func _init() -> void:
	super(4)

func describe() -> String:
	return "Car with " + super()
# race_car.gd
class_name RaceCar
extends Car

var top_speed: int

func _init(speed: int) -> void:
	super()
	top_speed = speed

func describe() -> String:
	return super() + ", top speed %d" % top_speed

ל־RaceCar יש את כל מה שיש ב־Car וב־Vehicle. כל קריאה ל־super() עולה רמה אחת, כך שקריאה אחת מריצה את כל שלוש הגרסאות של describe():

print(RaceCar.new(300).describe())
Car with 4 wheels, top speed 300

כשקוראים למתודה או קוראים את הערך של משתנה, Godot מחפש תחילה במחלקה של האובייקט עצמו, אחר כך במחלקת האב שלו, ואז במחלקת האב של מחלקת האב, ומשתמש בראשון שהוא מוצא. RaceCar.new(300).wheels נמצא ב-Vehicle, שתי רמות למעלה.

לכל מחלקה יש בדיוק מחלקת אב אחת. extends מקבלת מחלקה אחת, ורישום של שתיים הוא שגיאת ניתוח:

class_name FlyingCar
extends Car, Plane
Parse Error: Expected end of statement after superclass, found "," instead.

ל-GDScript אין ירושה מרובה. כשמחלקה זקוקה לתכונות של שתי מחלקות, הציבו אותן באותה שרשרת, או תנו לה אובייקט מהמחלקה האחרת לעבוד איתו (פרק מאוחר יותר עוסק בכך).

challenge icon

אתגר

קל

character.gd מכיל את המחלקה המוגמרת Character: שם, hp, הפונקציה describe() שמחזירה NAME (HP HP) והפונקציה attack() שמחזירה 1. בנו עליו עוד שתי רמות:

  • Warrior יורשת מ־Character ומוסיפה את strength. הבנאי שלה מעביר את השם ואת hp אל super(). הפונקציה describe() מוסיפה , strength S לטקסט של מחלקת האב, והפונקציה attack() מחזירה את הכוח.
  • Knight יורשת מ־Warrior ומוסיפה את armor. הבנאי שלה מעביר את השם, את hp ואת הכוח אל super(). הפונקציה describe() מוסיפה , armor A לטקסט של Warrior, והפונקציה attack() מחזירה את ההתקפה של Warrior ועוד 5.

הקוד שסופק קורא כמה דמויות יופיעו, ולאחר מכן שורה אחת לכל דמות: character NAME HP,‏ warrior NAME HP STRENGTH או knight NAME HP STRENGTH ARMOR. הוא מדפיס את describe() ואת ההתקפה. עבור knight Arthur 120 15 8 הוא מדפיס:

Arthur (120 HP), strength 15, armor 8
Attack: 20

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

נסו בעצמכם

extends Node

func _ready():
	# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		var c: Character
		if p[0] == "knight":
			c = Knight.new(p[1], int(p[2]), int(p[3]), int(p[4]))
		elif p[0] == "warrior":
			c = Warrior.new(p[1], int(p[2]), int(p[3]))
		else:
			c = Character.new(p[1], int(p[2]))
		print(c.describe())
		print("Attack: %d" % c.attack())
quiz iconבחנו את עצמכם

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

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

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