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

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

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

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

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

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

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

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

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

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

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

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

challenge icon

التحدي

سهل

لنبنِ نظامًا للعمال يوضّح متى نستخدم extends بدلًا من implements. ستنشئ فئة عامل أساسية، ثم تعرض النهجين معًا: فئة تُعدّ حقًا "is a" عاملًا وترث السلوك، وفئة أخرى "can do" ما يفعله العامل، ولكن بمنطق custom بالكامل.

ستنظّم الكود في ملفين:

  • worker.dart: عرّف تسلسل فئات العمال هنا:
    • فئة Worker تحتوي على خاصية String name ومنشئ. أضف طريقة work() تطبع [name] is working... وطريقة takeBreak() تطبع [name] takes a coffee break
    • فئة OfficeWorker التي extends الفئة Worker. أضف خاصية String department. أعد تعريف work() لتطبع [name] is typing reports in [department]، مع الإبقاء على سلوك takeBreak() الموروث
    • فئة RobotWorker التي implements الفئة Worker. أضف خاصية String model. بما أن الروبوتات ليست عمالًا فعليًا، لكنها تستطيع القيام بما يفعله العمال، فوفّر implementations custom بالكامل: يجب أن تطبع 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() automatically لأنها تمتد من Worker — فهي "is a" عامل حقًا. في المقابل، يجب على RobotWorker توفير implementation خاص به لكل شيء لأنه يطبّق الواجهة فقط — فهو "can do" ما يفعله العامل، ولكن بطريقته الروبوتية الخاصة.

الناتج المتوقع:

Alice is typing reports in Marketing
Alice takes a coffee break

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

جرّب بنفسك

import 'worker.dart';

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

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

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

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