Menu
CoddyTech

الأصناف والدوال المجردة

جزء من قسم البرمجة كائنية التوجه في رحلة Python على Coddy. الدرس 25 من 64.

الفئات المجرّدة هي فئات لا يمكن إنشاء كائنات منها مباشرةً، وتحتوي على أساليب مجرّدة يجب أن تنفّذها الفئات الفرعية.

تخيّل الأمر كنموذج: الفئة المجرّدة أشبه بنموذج إلزامي، بعض حقوله مطلوبة (الأساليب المجرّدة) وبعضها اختياري (الأساليب الفعلية). لا يمكنك إرسال النموذج نفسه؛ بل يجب أن تملأ جميع الحقول المطلوبة أولًا. وبالمثل، لا يمكنك إنشاء كائنات من فئة مجرّدة حتى تُنفَّذ جميع الأساليب المجرّدة في فئة فرعية.

استورد وحدة abc لإنشاء فئات مجرّدة:

from abc import ABC, abstractmethod

أنشئ فئة مجرّدة تحتوي على أساليب مجرّدة:

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
    
    @abstractmethod
    def perimeter(self):
        pass
    
    def describe(self):
        return "This is a shape"  # دالة مُنفَّذة (لها تنفيذ)

تُحدِّد أداة التزيين @abstractmethod الطرق التي يجب أن تنفّذها الفئات الفرعية — فهذه هي «الحقول المطلوبة» في نموذجك. أما الطرق العادية مثل describe()، فيمكن أن يكون لها تنفيذ وتُورَث كما هي — فهذه هي «الحقول المعبأة مسبقًا».

لماذا نستخدم الأصناف المجرّدة؟ إنها تفرض عقدًا. إذا أنشأت صنفًا باسم Shape، فأنت تقول: «يجب أن يكون كل شكل قادرًا على حساب مساحته ومحيطه». وهذا يمنع الأخطاء التي قد تقع فيها إذا نسيت تنفيذ طرائق أساسية.

حاول إنشاء مثيل من الصنف المجرّد:

# سيؤدي هذا إلى حدوث خطأ:
# shape = Shape()  # TypeError: لا يمكن إنشاء مثيل من فئة مجردة

هذا الخطأ مقصود — إنه أشبه بمحاولة إرسال نموذج فارغ. تقول Python: «لم تملأ الحقول المطلوبة (طريقتَي المساحة والمحيط) بعد!»

أنشئ صنفًا فرعيًا ملموسًا ينفّذ جميع الأساليب المجرّدة:

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14 * self.radius ** 2
    
    def perimeter(self):
        return 2 * 3.14 * self.radius

الآن «أكملنا جميع الحقول المطلوبة» — لقد نفّذنا كلًا من area() وperimeter(). أصبح الصنف Circle الآن صنفًا ملموسًا مكتملًا يمكن إنشاء كائن منه.

والآن يمكنك إنشاء مثيلات من الفئة الملموسة:

circle = Circle(5)
print(circle.area())
print(circle.perimeter())
print(circle.describe())  # طريقة فعلية موروثة

أنشئ صنفًا فرعيًا ملموسًا آخر:

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width  self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

rectangle = Rectangle(4, 6)
print(rectangle.area())
print(rectangle.perimeter())

الناتج:

78.5
31.400000000000002
This is a shape
24
20

تحدّد الفئات المجرّدة عقدًا يجب أن تلتزم به الفئات الفرعية. استخدم ABC و@abstractmethod لإنشاء فئات مجرّدة. يجب على الفئات الفرعية تنفيذ جميع الأساليب المجرّدة، وإلا فستكون مجرّدة هي الأخرى. وهذا يضمن الاتساق ويمنع التطبيقات غير المكتملة.

challenge icon

التحدي

متوسط

في هذا التحدي، ستنفّذ نظامًا لمعالجة المدفوعات.

عليك إكمال التنفيذ في هذه الملفات:

  • paymentmethod.py - الفئة الأساسية المجرّدة مع منطق التحقق
  • creditcard.py - تنفيذ الدفع ببطاقة ائتمان
  • paypal.py - تنفيذ الدفع عبر PayPal

اتبع تعليقات TODO في كل ملف لتنفيذ الوظائف المطلوبة. سترشدك التعليقات خطوة بخطوة إلى إنشاء الأساليب المجرّدة، وتنفيذ الفئات الفرعية الملموسة، وإعداد علاقات الاستيراد المناسبة بين الملفات.

يحتوي الملف driver.py على حالات اختبار ستتحقق من عمل تنفيذك على النحو الصحيح، وذلك بمعالجة سيناريوهات دفع مختلفة وعرض التفاصيل المناسبة لكل طريقة دفع.

جرّب بنفسك

from creditcard import CreditCard
from paypal import PayPal

# اختبر التنفيذات - لا تعدّل رمز الاختبار هذا
cc = CreditCard("1234567890123456")
pp = PayPal("user@example.com")

# عالِج المدفوعات الصالحة
if cc.validate(100):
    print(cc.process_payment(100))
    print(cc.payment_details())

if pp.validate(200):
    print(pp.process_payment(200))
    print(pp.payment_details())

# جرّب مبلغًا غير صالح
if not pp.validate(0):
    print("Invalid payment amount")

# سيؤدي هذا إلى حدوث خطأ إذا أُزيلت عنه علامة التعليق:
# pm = PaymentMethod()  # لا يمكن إنشاء مثيل من فئة مجردة
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Python عبر الإنترنت