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

الواجهات في Dart

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

على عكس العديد من اللغات التي تحتوي على كلمة مفتاحية مخصصة لـ interface، تتبع Dart نهجاً مختلفاً. في Dart، كل class يحدد تلقائياً interface. تتكون هذه الـ interface من جميع الأعضاء العامين (methods و properties) التي يقوم الـ class بالتصريح عنها.

عندما تريد أن تلتزم فئة (class) بتقديم وظائف معينة دون وراثة التنفيذ، فإنك تستخدم الكلمة المفتاحية implements:

class Printer {
  void printDocument(String content) {
    print('Printing: $content');
  }
}

class Scanner {
  void scan() {
    print('Scanning document');
  }
}

// يجب على MultiFunctionDevice تنفيذ كافة الدوال من كلا الكلاسين
class MultiFunctionDevice implements Printer, Scanner {
  @override
  void printDocument(String content) {
    print('MFD printing: $content');
  }
  
  @override
  void scan() {
    print('MFD scanning');
  }
}

الفرق الجوهري عن extends هو أن implements لا يرث أي كود. يجب عليك تقديم التنفيذ الخاص بك لكل طريقة (method) وخاصية (property) محددة في الواجهة (interface). هذا بمثابة عقد - أنت تتعهد بأن فئتك (class) ستمتلك هذه القدرات، ولكنك تقرر بالضبط كيف تعمل.

هذا النهج يمنح Dart المرونة. يمكنك استخدام abstract classes عندما تريد تعريف interfaces بدون أي implementation، أو استخدام الفئات العادية كـ interfaces عندما يكون ذلك منطقياً. يستكشف الدرس التالي كيفية عمل مفهوم "implicit interface" هذا بمزيد من التفصيل.

challenge icon

التحدي

سهل

لنقم ببناء نظام مشغل وسائط يوضح كيفية عمل الكلمة المفتاحية implements في Dart. ستقوم بإنشاء فئات تعمل كواجهات ثم تقوم بتنفيذها في جهاز واحد يجمع بين قدرات متعددة.

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

  • media.dart: قم بتعريف فئات الواجهة والفئة المنفذة هنا:
    • فئة AudioPlayer مع طريقة playAudio(String track) تطبع Playing audio: [track]
    • فئة VideoPlayer مع طريقة playVideo(String title) تطبع Playing video: [title]
    • فئة SmartTV تقوم بتنفيذ كل من AudioPlayer و VideoPlayer. نظرًا لأن implements لا ترث أي كود، يجب عليك تقديم التنفيذ الخاص بك لكلتا الطريقتين. يجب أن تطبع SmartTV الخاصة بك SmartTV audio: [track] للصوت و SmartTV video: [title] للفيديو
  • main.dart: قم باستيراد ملف الوسائط الخاص بك ووضح كيف يمكن لفئة واحدة تنفيذ واجهات متعددة:
    • قم بإنشاء مثيل من SmartTV
    • قم باستدعاء playAudio('Jazz Collection')
    • قم باستدعاء playVideo('Nature Documentary')

لاحظ كيف يجب على SmartTV تقديم التنفيذ الخاص بها لكل طريقة من كلتا الواجهتين - فهي لا ترث التنفيذات الأصلية من AudioPlayer أو VideoPlayer. هذا هو الفرق الجوهري بين implements و extends.

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

SmartTV audio: Jazz Collection
SmartTV video: Nature Documentary

ورقة مرجعية

في لغة Dart، تحدد كل فئة (class) تلقائيًا واجهة (interface) تتكون من جميع أعضائها العامين. لتنفيذ واجهة دون وراثة الكود، استخدم الكلمة المفتاحية implements:

class Printer {
  void printDocument(String content) {
    print('Printing: $content');
  }
}

class Scanner {
  void scan() {
    print('Scanning document');
  }
}

// يجب تنفيذ جميع الطرق (methods) من كلتا الفئتين
class MultiFunctionDevice implements Printer, Scanner {
  @override
  void printDocument(String content) {
    print('MFD printing: $content');
  }
  
  @override
  void scan() {
    print('MFD scanning');
  }
}

الاختلافات الرئيسية عن extends:

  • implements لا ترث أي تنفيذ للكود
  • يجب عليك توفير التنفيذ الخاص بك لكل طريقة (method) وخاصية (property)
  • يمكن للفئة تنفيذ واجهات متعددة
  • إنه بمثابة عقد يضمن أن فئتك ستمتلك هذه القدرات

جرّب بنفسك

import 'media.dart';

void main() {
  // TODO: إنشاء كائن من SmartTV
  
  // TODO: استدعاء playAudio('Jazz Collection')
  
  // TODO: استدعاء playVideo('Nature Documentary')
  
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming