كتابة الأنواع بأسلوب البطة
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 22 من 65.
يهتم التنميط بأسلوب البطة بما يستطيع الكائن فعله، لا بالفئة التي ينتمي إليها. إذا كان لديه الأسلوب الذي تستدعيه، فسيعمل الاستدعاء. يأتي الاسم من المقولة: "إذا كان يسبح مثل البطة ويُصدر صوتًا مثل البطة، فهو بطة".
لا تشترك هاتان الفئتان في فئة أب خاصة بهما، لكن كلتيهما تحتويان على swim() وquack():
# duck.gd
class_name Duck
extends RefCounted
func swim() -> String:
return "Duck swimming"
func quack() -> String:
return "Quack!"# robot.gd
class_name Robot
extends RefCounted
func swim() -> String:
return "Robot swimming with propellers"
func quack() -> String:
return "Robot sound: BEEP BEEP!"تقبل المعلمة التي لا تملك نوعًا محددًا أي كائن. تستدعي الدالة الأساليب، وينفّذ كل كائن أساليبه الخاصة:
func make_it_swim_and_quack(thing) -> void:
print(thing.swim())
print(thing.quack())make_it_swim_and_quack(Duck.new())
make_it_swim_and_quack(Robot.new())Duck swimming
Quack!
Robot swimming with propellers
Robot sound: BEEP BEEP!تتطلب إعادة التعريف وجود فئة أب مشتركة؛ أما الكتابة بأسلوب البط فهي لا تتطلب ذلك. عند تحديد نوع المعامل على أنه thing: Duck، فإن تمرير Robot سيؤدي إلى خطأ في التحليل.
عندما يفتقر كائن إلى الطريقة، يوقف الاستدعاء الدالة ويُظهر خطأً مثل Invalid call. Nonexistent function 'quack'. تحقّق أولًا باستخدام has_method()، التي تأخذ اسم الطريقة كسلسلة نصية:
var things := [Duck.new(), Rock.new()]
for thing in things:
if thing.has_method("quack"):
print(thing.quack())
else:
print("This one cannot quack")Quack!
This one cannot quackالثمن: مع الأنواع، يكتشف Godot اسم الطريقة الخاطئ قبل تشغيل البرنامج؛ أما مع الكتابة بطريقة البط، فلا تكتشف ذلك إلا عند تنفيذ السطر. استخدمها مع كائنات من أصناف غير مترابطة تشترك في بعض الطرق.
التحدي
سهليتسبب الانفجار في إلحاق الضرر بكل شيء قريب يمكنه تلقي الضرر. لا تشترك الكائنات في فئة أب. الملفان player.gd وrock.gd مكتملان: لدى Player الدالتان take_damage(amount) وstatus()، بينما لدى Rock الدالة status() فقط.
- في
crate.gd، أضف إلىCrateمتغيرًا اسمهbrokenتكون قيمته الابتدائيةfalse، ودالةtake_damage(amount)تكسر الصندوق عندما تكون القيمة 10 أو أكثر، ودالةstatus()تعيدCrate: brokenأوCrate: intact. - في
explosion.gd، اكتب الدالة statichit_all(things, amount). تستدعي الدالةtake_damage(amount)لكل كائن في المصفوفة Array لديه هذه الدالة، وتعيد عدد الكائنات التي أصابتها.
تقرأ الشيفرة المقدمة سطرًا من أسماء الكائنات (player أو crate أو rock)، ثم عدد الانفجارات التي ستحدث ومقدار الضرر الذي يسببه كل منها. وتطبع عدد الكائنات التي أصابها كل انفجار، ثم حالة كل كائن. عند إدخال player crate rock وانفجارين يسببان ضررًا بقيمتي 5 و20، تكون المخرجات:
Explosion 1 hit 2 objects
Explosion 2 hit 2 objects
Player: 75 HP
Crate: broken
Rock: solidضع شيفرتك في crate.gd وexplosion.gd. يحتوي main.gd على شيفرة الإدخال/الإخراج المقدمة، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال/الإخراج المقدَّم: اتركه كما هو
var things := []
for word in OS.read_string_from_stdin().split(" "):
if word == "player":
things.append(Player.new())
elif word == "crate":
things.append(Crate.new())
else:
things.append(Rock.new())
var count := int(OS.read_string_from_stdin())
for i in count:
var hits := Explosion.hit_all(things, int(OS.read_string_from_stdin()))
print("Explosion %d hit %d objects" % [i + 1, hits])
for thing in things:
print(thing.status())
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت