الفئات والأساليب المجرّدة
جزء من قسم البرمجة كائنية التوجّه في رحلة GDScript على Coddy. الدرس 23 من 65.
توجد بعض الفئات لغرض التوسيع فقط. لكل شكل مساحة، لكن لا يمكنك حسابها حتى تعرف ما إذا كان الشكل دائرة أم مستطيلًا. اجعل هذه الفئة @abstract، في السطر الذي يسبق class_name:
# shape.gd
@abstract
class_name Shape
extends RefCounted
@abstract func area() -> float
@abstract func perimeter() -> float
func describe() -> String:
return "Area %.1f, perimeter %.1f" % [area(), perimeter()]تحتوي @abstract func على توقيع ولا تحتوي على جسم: لا نقطتين ولا أي كود بعدها. وهذا يعني أن كل صنف ابن يجب أن يوفّر هذه الدالة. أما describe() فهي دالة عادية؛ ترثها الأصناف الابنة، ويمكنها بالفعل استدعاء الدوال المجرّدة.
لا يمكنك إنشاء كائن من فئة مجردة. Shape.new() يوقف البرنامج قبل أن يبدأ مع Parse Error: Cannot construct abstract class "Shape".
الصنف الابن الذي يكتب كل الأساليب المجرّدة هو صنف عادي:
# rectangle.gd
class_name Rectangle
extends Shape
var width: float
var height: float
func _init(w: float, h: float) -> void:
width = w
height = h
func area() -> float:
return width * height
func perimeter() -> float:
return 2 * (width + height)var rect := Rectangle.new(4.0, 6.0)
print(rect.describe())Area 24.0, perimeter 20.0إذا أغفل أحد الأبناء تنفيذ أحدها، فسيُبلغك Godot بذلك قبل التشغيل: Class "Square" must implement "Shape.perimeter()" and other inherited abstract methods or be marked as "@abstract". لذلك، يحتوي كل كائن يمكنك إنشاؤه على area() وperimeter().
يمكن أن يظل للفئة المجرّدة متغيرات و_init(). تستدعيها الفئات الفرعية باستخدام super() كالمعتاد.
التحدي
سهليقبل متجر طريقتين للدفع. لكل دفعة مبلغ وإيصال، لكن الرسوم والاسم يعتمدان على الطريقة.
- اجعل
PaymentMethodصنفًا مجردًا، وصرّح عن طريقتين مجردتين:fee() -> floatوmethod_name() -> String. اكتبreceipt()بحيث تُرجعNAME: paid AMOUNT, fee FEE, total TOTALمع منزلتين عشريتين لكل رقم (الإجمالي هو المبلغ مضافًا إليه الرسوم). CreditCard: الرسوم 3% من المبلغ (amount * 0.03)، والاسم هوCredit card.BankTransfer: الرسوم هي1.5، أو0.0عندما يكون المبلغ100أو أكثر، والاسم هوBank transfer.
تستخدم الأصناف الفرعية مُنشئ PaymentMethod. يقرأ الكود المرفق عدد الدفعات التالية، ثم سطرًا واحدًا لكل دفعة: card AMOUNT أو transfer AMOUNT. يطبع كل إيصال ومجموع الرسوم. بالنسبة إلى card 50 وtransfer 120، تكون المخرجات:
Credit card: paid 50.00, fee 1.50, total 51.50
Bank transfer: paid 120.00, fee 0.00, total 120.00
Total fees: 1.50ضع الكود في payment_method.gd وcredit_card.gd وbank_transfer.gd. يحتوي main.gd على كود الإدخال/الإخراج المرفق، ولا يمكن تعديله.
جرّب بنفسك
extends Node
func _ready():
# كود الإدخال/الإخراج المقدَّم: أبقه كما هو
var count := int(OS.read_string_from_stdin())
var total_fees := 0.0
for i in count:
var p := OS.read_string_from_stdin().split(" ")
var payment: PaymentMethod
if p[0] == "card":
payment = CreditCard.new(float(p[1]))
else:
payment = BankTransfer.new(float(p[1]))
print(payment.receipt())
total_fees += payment.fee()
print("Total fees: %.2f" % total_fees)
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجّه
1أساسيات البرمجة كائنية التوجه
الملفات الخارجيةمقدمة إلى البرمجة كائنية التوجهالفئات مقابل الكائناتالكلمة المفتاحية selfالأساليبالخصائصالمُنشئ (_init)مراجعة - آلة حاسبة بسيطة4تعدد الأشكال
إعادة النظر في تجاوز الأساليبكتابة الأنواع بأسلوب البطةالفئات والأساليب المجرّدةتصميم الواجهاتمراجعة - حاسبة الأشكال10أنماط التصميم، الجزء الثاني
نمط الأوامرنمط المحوّلنمط المُزيّننمط الطريقة القالبيةنمط الحالةالنمط المركّب2خصائص الأصناف
متغيرات الكائن مقابل المتغيرات الساكنةالدوال الساكنةمُعيِّنات الخصائصمُسترجِعات الخصائصخاص وفقًا للاتفاقيةمراجعة - مدير الحسابات البنكية5التغليف
الأعضاء العامة والخاصةالتحقق من الصحة باستخدام دوال الضبطإخفاء المعلوماتالخصائص للقراءة فقطمراجعة - نظام سجلات الطلاب8مفاهيم متقدمة في البرمجة كائنية التوجه
التركيب مقابل الوراثةالأصناف الداخليةالعُقد كمكوّناتRefCounted مقابل Nodeالتعدادات في الأصنافتدرّب بنفسك: مترجم GDScript عبر الإنترنت