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

الواجهات الضمنية

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

بما أن كل فئة Dart تُعرّف واجهة بشكل تلقائي، يمكنك استخدام أي فئة كواجهة - حتى الفئات الملموسة (concrete classes) ذات التنفيذات الكاملة. هذا ما نسميه واجهة ضمنية (implicit interface).

ضع في اعتبارك فئة (class) تحتوي على خصائص (properties) ووسائل (methods):

class Logger {
  String prefix = '[LOG]';
  
  void log(String message) {
    print('$prefix $message');
  }
  
  void clear() {
    print('Clearing logs...');
  }
}

عندما تقوم فئة أخرى بتنفيذ Logger، يجب أن توفر تنفيذها الخاص لـ كل شيء - بما في ذلك خاصية prefix:

class FileLogger implements Logger {
  @override
  String prefix = '[FILE]';
  
  @override
  void log(String message) {
    print('$prefix Writing to file: $message');
  }
  
  @override
  void clear() {
    print('Deleting log file...');
  }
}

هذه هي الرؤية الأساسية: عندما تستخدم implements، فأنت تقول "سيكون لفئتي (class) نفس الشكل" - نفس الأساليب (methods) والخصائص (properties). أنت لا ترث أي كود، أو منشئات (constructors)، أو قيم افتراضية. أنت تعد فقط بمطابقة هيكل الواجهة (interface).

هذا يجعل الواجهات الضمنية قوية لإنشاء مكونات قابلة للتبديل. الكود الذي يتوقع Logger يمكنه العمل مع أي فئة تنفذ واجهته، بغض النظر عن كيفية عمل ذلك التنفيذ داخلياً.

challenge icon

التحدي

سهل

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

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

  • notification.dart: حدد فئات الإشعارات الخاصة بك هنا:
    • فئة Notification مع خاصية String channel مضبوطة على 'default'، وطريقة send(String message) تطبع [channel]: [message]، وطريقة getStatus() تعيد السلسلة النصية 'Notification ready'
    • فئة EmailNotification التي تنفيذ (implements) Notification. نظرًا لأنك تستخدم implements، يجب عليك توفير خاصية channel الخاصة بك (اضبطها على 'email')، وطريقة send() الخاصة بك التي تطبع Sending email: [message]، وطريقة getStatus() الخاصة بك التي تعيد 'Email service active'
    • فئة PushNotification التي تنفيذ (implements) Notification. اضبط channel الخاصة بها على 'push'، واجعل send() تطبع Push alert: [message]، واجعل getStatus() تعيد 'Push service connected'
  • main.dart: استورد ملف الإشعارات الخاص بك ووضح كيف يمكن للفئات المختلفة تنفيذ نفس الواجهة الضمنية بسلوكيات مختلفة تمامًا:
    • أنشئ مثيلًا من EmailNotification و PushNotification
    • لكل إشعار، اطبع حالته باستخدام getStatus()، ثم استدعِ send() مع الرسالة 'Hello World'
    • اطبع سطرًا فارغًا بين الإشعارين

تذكر: عندما تستخدم implements، فأنت لا ترث أي كود من Notification. أنت تعد فقط بأن فئتك سيكون لها نفس الشكل - نفس الخصائص والطرق. توفر كل فئة منفذة تنفيذها الكامل الخاص بها.

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

Email service active
Sending email: Hello World

Push service connected
Push alert: Hello World

جرّب بنفسك

import 'notification.dart';

void main() {
  // TODO: إنشاء مثيل (instance) من EmailNotification
  
  // TODO: طباعة حالة إشعار البريد الإلكتروني باستخدام getStatus()
  
  // TODO: إرسال رسالة 'Hello World' باستخدام إشعار البريد الإلكتروني
  
  // TODO: طباعة سطر فارغ
  
  // TODO: إنشاء مثيل (instance) من PushNotification
  
  // TODO: طباعة حالة إشعار الدفع (push notification) باستخدام getStatus()
  
  // TODO: إرسال رسالة 'Hello World' باستخدام إشعار الدفع (push notification)
  
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming