Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الفئات المجردة

جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 43 من 110.

تُعد الفئة المجردة (abstract class) فئة لا يمكن إنشاء كائن منها بشكل مباشر. فهي تعمل كمخطط للفئات الأخرى، حيث تحدد بنية مشتركة يجب على الفئات الفرعية اتباعها. يمكنك إنشاء واحدة باستخدام الكلمة المفتاحية abstract.

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // خطأ! لا يمكن إنشاء كائن من فئة مجردة
  var circle = Circle('blue', 5.0);
  circle.describe();  // شكل أزرق
}

تُعد الفئات المجردة (Abstract classes) مفيدة عندما يكون لديك مفهوم عام جداً بحيث لا يمكن أن يوجد بمفرده. فكلمة "Shape" (شكل) هي فكرة، ولكن لا يمكنك رسم شكل دون معرفة ما إذا كان دائرة أو مستطيلاً أو مثلثاً. تُحدد الفئة المجردة ما تشترك فيه جميع الأشكال، بينما توفر الفئات الفرعية الملموسة (concrete subclasses) التفاصيل المحددة.

لاحظ أن الفئات المجردة (abstract classes) لا يزال بإمكانها امتلاك دوال عادية مع تنفيذات (مثل describe()) ومنشئات (constructors). ترث الفئات الفرعية هذه العناصر تماماً كما هو الحال في الوراثة العادية. الفرق الجوهري هو ببساطة أنه لا يمكنك إنشاء مثيل (instance) من الفئة المجردة نفسها - بل يجب عليك استخدام فئة فرعية ملموسة (concrete subclass).

challenge icon

التحدي

سهل

لنقم ببناء نظام مركبات يوضح كيف تعمل الأصناف المجردة (abstract classes) كمخططات لأنواع أكثر تحديداً. ستقوم بإنشاء صنف أساسي مجرد يحدد الخصائص المشتركة لجميع المركبات، ثم تقوم بتوسعته بأنواع مركبات ملموسة.

ستقوم بتنظيم الكود الخاص بك في ملفين:

  • vehicle.dart: حدد هيكلية المركبات الخاصة بك هنا:
    • abstract class Vehicle مع خاصية String brand و int year. قم بتضمين منشئ (constructor) يأخذ كلتا القيمتين ودالة displayInfo() تطبع [brand] ([year])
    • صنف Car يرث من Vehicle ويضيف خاصية int doors. قم بتضمين دالة honk() تطبع Beep beep!
    • صنف Motorcycle يرث من Vehicle ويضيف خاصية bool hasSidecar. قم بتضمين دالة revEngine() تطبع Vroom!
  • main.dart: استورد ملف المركبات ووضح كيف تعمل الأصناف المجردة:
    • أنشئ Car بماركة 'Toyota'، وسنة 2022، وأبواب 4
    • استدعِ دالة displayInfo() الخاصة بها (الموروثة من Vehicle)
    • اطبع Doors: [doors]
    • استدعِ دالة honk() الخاصة بها
    • اطبع سطراً فارغاً
    • أنشئ Motorcycle بماركة 'Harley'، وسنة 2021، و hasSidecar بقيمة false
    • استدعِ دالة displayInfo() الخاصة بها
    • اطبع Has sidecar: [hasSidecar]
    • استدعِ دالة revEngine() الخاصة بها

تذكر أنه لا يمكنك إنشاء كائن (instance) من Vehicle مباشرة لأنه مجرد (abstract) - يجب عليك استخدام أحد الأصناف الفرعية الملموسة. يرث كل من Car و Motorcycle دالة displayInfo() من الصنف الأب المجرد.

المخرجات المتوقعة:

Toyota (2022)
Doors: 4
Beep beep!

Harley (2021)
Has sidecar: false
Vroom!

ورقة مرجعية

الفئة المجردة (abstract class) هي فئة لا يمكن إنشاء كائن منها مباشرة. وهي تعمل كمخطط للفئات الأخرى، حيث تحدد هيكلاً مشتركاً يجب على الفئات الفرعية اتباعه. قم بإنشاء واحدة باستخدام الكلمة المفتاحية abstract:

abstract class Shape {
  String color;
  
  Shape(this.color);
  
  void describe() {
    print('A $color shape');
  }
}

class Circle extends Shape {
  double radius;
  
  Circle(String color, this.radius) : super(color);
}

void main() {
  // Shape s = Shape('red');  // خطأ! لا يمكن إنشاء كائن من فئة مجردة
  var circle = Circle('blue', 5.0);
  circle.describe();  // A blue shape
}

يمكن أن تحتوي الفئات المجردة على:

  • دوال عادية مع تنفيذات (implementations)
  • منشئات (Constructors)
  • خصائص (Properties)

ترث الفئات الفرعية هذه الأعضاء تماماً كما هو الحال في الوراثة العادية. الفرق الرئيسي هو أنه لا يمكنك إنشاء كائن من الفئة المجردة نفسها - يجب عليك استخدام فئة فرعية ملموسة (concrete subclass).

جرّب بنفسك

import 'vehicle.dart';

void main() {
  // TODO: قم بإنشاء سيارة (Car) بماركة 'Toyota'، وسنة 2022، وعدد أبواب 4
  
  // TODO: استدعِ displayInfo() على السيارة
  
  // TODO: اطبع "Doors: [doors]"
  
  // TODO: استدعِ honk() على السيارة
  
  // TODO: اطبع سطراً فارغاً
  
  // TODO: قم بإنشاء دراجة نارية (Motorcycle) بماركة 'Harley'، وسنة 2021، و hasSidecar false
  
  // TODO: استدعِ displayInfo() على الدراجة النارية
  
  // TODO: اطبع "Has sidecar: [hasSidecar]"
  
  // TODO: استدعِ revEngine() على الدراجة النارية
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming