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

التنفيذ مقابل التوسيع

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

الآن بعد أن فهمت كلاً من extends و implements، دعنا نوضح متى نستخدم كل منهما.

استخدم extends عندما تريد وراثة السلوك. تحصل الفئة الفرعية (subclass) الخاصة بك على جميع أكواد الفئة الأب مجانًا ويمكنها البناء عليها:

class Animal {
  void breathe() {
    print('Breathing...');
  }
}

class Dog extends Animal {
  void bark() {
    print('Woof!');
  }
}

void main() {
  var dog = Dog();
  dog.breathe();  // موروثة - تعمل تلقائيًا
  dog.bark();
}

استخدم implements عندما تريد ضمان هيكلية معينة دون وراثة الكود. يجب عليك كتابة كل دالة بنفسك:

class Robot implements Animal {
  @override
  void breathe() {
    print('Ventilating circuits...');  // تنفيذ مخصص بالكامل
  }
}

الفرق الجوهري: extends يقول "أنا نوع من هذا" بينما implements يقول "يمكنني القيام بما يفعله هذا." الـ Dog هو Animal ويتنفس بنفس الطريقة. الـ Robot ليس حيواناً، ولكنه يمكنه الوفاء بنفس العقد بمنطقه الخاص.

تذكر: يمكنك توسيع فئة واحدة فقط، ولكن يمكنك تنفيذ العديد من الواجهات. اختر extends لعلاقات الوراثة الحقيقية، و implements عندما تحتاج إلى المرونة أو ترغب في فرض عقد دون مشاركة تفاصيل التنفيذ.

challenge icon

التحدي

سهل

لنقم ببناء نظام عمال يوضح متى نستخدم extends مقابل implements. ستقوم بإنشاء فئة أساسية للعامل ثم توضح كلا النهجين: فئة واحدة "هي" عامل حقاً وترث السلوك، وأخرى ببساطة "يمكنها القيام" بما يفعله العامل ولكن بمنطق مخصص تماماً.

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

  • worker.dart: حدد التسلسل الهرمي للعمال هنا:
    • فئة Worker مع خاصية String name ومنشئ (constructor). قم بتضمين تابع work() يطبع [name] is working... وتابع takeBreak() يطبع [name] takes a coffee break
    • فئة OfficeWorker التي ترث (extends) من Worker. أضف خاصية String department. قم بإعادة تعريف (Override) لـ work() ليطبع [name] is typing reports in [department] مع الاحتفاظ بسلوك takeBreak() الموروث
    • فئة RobotWorker التي تطبق (implements) واجهة Worker. أضف خاصية String model. بما أن الروبوتات ليست عمالاً حقاً ولكن يمكنها القيام بما يفعله العمال، فقم بتوفير تطبيقات مخصصة تماماً: يجب أن يطبع work() النص Robot [model] is assembling parts ويجب أن يطبع takeBreak() النص Robot [model] is recharging
  • main.dart: استورد ملف العامل وقم باستعراض كلا النهجين:
    • أنشئ OfficeWorker باسم 'Alice' في قسم 'Marketing'
    • أنشئ RobotWorker بطراز 'RX-7'
    • بالنسبة لموظف المكتب، استدعِ work() ثم takeBreak()
    • اطبع سطراً فارغاً
    • بالنسبة للعامل الروبوت، استدعِ work() ثم takeBreak()

لاحظ كيف يرث OfficeWorker التابع takeBreak() تلقائياً لأنه يمتد من Worker - فهو "عامل" حقاً. وفي الوقت نفسه، يجب على RobotWorker توفير تطبيقه الخاص لكل شيء لأنه يطبق الواجهة فقط - فهو "يمكنه القيام" بما يفعله العامل، ولكن بطريقته الروبوتية الخاصة.

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

Alice is typing reports in Marketing
Alice takes a coffee break

Robot RX-7 is assembling parts
Robot RX-7 is recharging

ورقة مرجعية

استخدم extends لوراثة السلوك من فئة أب (parent class). تحصل الفئة الفرعية (subclass) تلقائياً على جميع دوال الأب ويمكنها تجاوزها (override):

class Animal {
  void breathe() {
    print('Breathing...');
  }
}

class Dog extends Animal {
  void bark() {
    print('Woof!');
  }
}

void main() {
  var dog = Dog();
  dog.breathe();  // Inherited automatically
  dog.bark();
}

استخدم implements لضمان هيكلية معينة دون وراثة الكود. يجب عليك تقديم التنفيذ الخاص بك (implementation) لكل دالة:

class Robot implements Animal {
  @override
  void breathe() {
    print('Ventilating circuits...');
  }
}

الاختلافات الرئيسية:

  • extends: "أنا نوع من هذا" - وراثة حقيقية مع كود مشترك
  • implements: "يمكنني القيام بما يفعله هذا" - يفرض عقداً (contract) بمنطق مخصص
  • يمكنك تمديد (extend) فئة واحدة فقط، ولكن يمكنك تنفيذ (implement) واجهات متعددة

اختر extends لعلاقات الأب والابن الحقيقية حيث يجب وراثة السلوك. اختر implements عندما تحتاج إلى المرونة أو تريد فرض عقد دون مشاركة التنفيذ.

جرّب بنفسك

import 'worker.dart';

void main() {
  // TODO: 'Marketing' في قسم 'Alice' باسم OfficeWorker أنشئ
  
  // TODO: 'RX-7' بطراز RobotWorker أنشئ
  
  // TODO: ثم استدعِ ()takeBreak وبعدها ()work استدعِ ،OfficeWorker بالنسبة لـ
  
  // TODO: اطبع سطرًا فارغًا
  
  // TODO: ثم استدعِ ()takeBreak وبعدها ()work استدعِ ،RobotWorker بالنسبة لـ
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming