تصميم الواجهات
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 24 من 65.
الواجهة هي قائمة بالطرائق التي يتعهد صنف بامتلاكها، من دون أي شيفرة وراءها. تحتوي Java وC# على كلمة مفتاحية interface؛ أما GDScript فلا تحتوي عليها. يمكنك إنشاء الشيء نفسه باستخدام صنف مجرّد تكون جميع طرائقه مجرّدة:
# drawable.gd
@abstract
class_name Drawable
extends RefCounted
@abstract func draw() -> String
@abstract func resize(factor: int) -> voidلا يحتوي على متغيرات أو أجسام دوال. يصف ما يمكن لشيء قابل للرسم فعله، وتقرر كل فئة كيفية ذلك:
# banner.gd
class_name Banner
extends Drawable
var text: String
var size := 1
func _init(t: String) -> void:
text = t
func draw() -> String:
return "Banner '%s' at size %d" % [text, size]
func resize(factor: int) -> void:
size *= factorيمكن لـ Circle أن يوسّع Drawable أيضًا، مع radius وdraw() وresize() الخاصتين به. تعتمد الشيفرة التي تستخدم الواجهة عليها فقط، لذا فهي تعمل مع كل صنف يوسّع Drawable، بما في ذلك الأصناف التي ستُكتب لاحقًا:
func render_all(items: Array[Drawable]) -> void:
for item in items:
item.resize(2)
print(item.draw())var items: Array[Drawable] = [Banner.new("Sale"), Circle.new(3)]
render_all(items)Banner 'Sale' at size 2
Circle with radius 6للصنف أصل واحد، لذا يمكنه تنفيذ واجهة واحدة فقط. عندما يؤدي الصنف دورًا ثانيًا، مثل حفظه في ملف، نفّذ الواجهة الرئيسية وتحقّق من الدور الثاني باستخدام has_method():
if item.has_method("save"):
item.save()اجعل كل واجهة صغيرة: بضع طرائق تنتمي إلى دور واحد. عندها لا تكتب الفئة التي توسّعها إلا الطرائق التي تحتاج إليها.
التحدي
سهلأنشئ مشغّل وسائط حول واجهة.
- في
playable.gd، اجعلPlayableواجهة: صنفًا مجرّدًا يحتوي على الطريقتين المجرّدتينplay() -> Stringوduration() -> int(بالثواني). - يرث
SongمنPlayable. تُرجعplay()القيمةPlaying song: TITLE by ARTIST، وتُرجعduration()عدد الثواني الخاص بها. - يرث
VideoمنPlayable. تُرجعplay()القيمةPlaying video: TITLE in RESOLUTIONp(على سبيل المثالin 1080p)، وتُرجعduration()عدد الثواني الخاص بها. - لا تعرف
PlaylistسوىPlayable. تطبعplay_all()ناتجplay()لكل عنصر، وتُرجعtotal_time()مجموع المدد بتنسيقM:SS(الثواني برقمين، على سبيل المثال4:05).
كُتبت بواني Song وVideo. يقرأ الكود المزوّد عدد العناصر التي تليه، ثم سطرًا واحدًا لكل عنصر: song TITLE ARTIST SECONDS أو video TITLE RESOLUTION SECONDS. ويستدعي play_all() ويطبع الوقت الإجمالي. بالنسبة إلى song Imagine Lennon 183 وvideo Trailer 1080 95، يطبع:
Playing song: Imagine by Lennon
Playing video: Trailer in 1080p
Total time: 4:38ضع الكود الخاص بك في playable.gd وsong.gd وvideo.gd وplaylist.gd. يحتوي main.gd على كود الإدخال/الإخراج المزوّد ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال والإخراج المرفق: اتركه كما هو
var count := int(OS.read_string_from_stdin())
var playlist := Playlist.new()
for i in count:
var p := OS.read_string_from_stdin().split(" ")
if p[0] == "song":
playlist.add(Song.new(p[1], p[2], int(p[3])))
else:
playlist.add(Video.new(p[1], int(p[2]), int(p[3])))
playlist.play_all()
print("Total time: " + playlist.total_time())
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت