إعادة النظر في تجاوز الأساليب
جزء من قسم البرمجة كائنية التوجّه في رحلة 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أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت