OOP Interface – implements

✅ أولاً: ما هو الـ Interface؟
📘 التعريف:

interface هو عقد (contract) يحدد ما الذي يجب على الكلاس تنفيذه، لكنه لا يحتوي على أي منطق (body).

في Dart، لا يوجد keyword خاصة بـ interface، وإنما كل class يمكن اعتباره interface عند استخدامه مع implements.

🧠 كيف نستخدمه؟
  • Dart تعوض interface بالكلمة المفتاحية: implements.
  • الكلاس الذي يطبّق (implements) interface يجب أن ينفذ كل شيء فيه حرفيًا.
✅ لماذا نستخدم interface؟
الهدفالشرح
✅ فصل السلوك عن التنفيذالكلاس يحدد فقط “ما يجب فعله” وليس “كيف”
✅ قابلية التوسعةأي كلاس يمكنه تنفيذ الواجهة بطريقته
✅ دعم الوراثة المتعددةDart لا تدعم extends لأكثر من كلاس، لكن تدعم implements لعدة واجهات
✅ يساعد في كتابة كود مرن وقابل للاختبارلأنه يفصل بين الكود الفعلي والتجريد
✅ الشكل العام:
class InterfaceName {
  void method1();
  int method2(String name);
}

class MyClass implements InterfaceName {
  @override
  void method1() {
    // تنفيذ خاص بالكلاس
  }

  @override
  int method2(String name) {
    return name.length;
  }
}
Dart
✅ مثال 1: واجهة تسجيل الدخول
class AuthService {
  void login(String email, String password);
}

class FirebaseAuth implements AuthService {
  @override
  void login(String email, String password) {
    print("تسجيل الدخول باستخدام Firebase");
  }
}

class LocalAuth implements AuthService {
  @override
  void login(String email, String password) {
    print("تسجيل الدخول المحلي");
  }
}

void main() {
  AuthService auth = FirebaseAuth();
  auth.login("[email protected]", "123456");
}
Dart
✅ شرح المثال:
  • أنشأنا AuthService كـ واجهة: تحتوي فقط على الدالة login بدون body.
  • FirebaseAuth و LocalAuth قاموا بـ implements للواجهة ونفذوا دالة login بطريقتهم.
  • الكود صار مرن: تقدر تستبدل طريقة تسجيل الدخول بسهولة دون تغيير منطق البرنامج.
✅ ملاحظات مهمة جدًا:
المعلومةالتوضيح
❌ لا يمكن ترك دالة بدون تنفيذيجب تنفيذ كل الدوال الموجودة في الواجهة
✅ يمكن تنفيذ عدة واجهات معًاDart تدعم implements A, B, C...
✅ الواجهة لا تحتوي خصائص final أو متغيرات منجزةفقط التصريحات (declarations)
✅ الواجهة لا تنفذ شيءفقط تحدد ما يجب تنفيذه
✅ مثال 2: حيوانات لها صوت
class SoundMaker {
  void makeSound();
}

class Dog implements SoundMaker {
  @override
  void makeSound() {
    print("هاو هاو 🐶");
  }
}

class Cat implements SoundMaker {
  @override
  void makeSound() {
    print("مياو 🐱");
  }
}
Dart
✅ الفرق بين implements و extends و abstract class
المقارنةabstract classinterface (implements)extends (وراثة عادية)
يحتوي منطق (دوال عادية)؟✅ نعم❌ لا✅ نعم
يجب تنفيذ الدوال المجردة؟✅ نعم✅ نعم❌ لا
يرث من كلاس واحد فقط؟✅ نعم❌ يمكن من عدة واجهات✅ نعم
يمكن استخدام الخصائص؟✅ نعم❌ فقط الدوال✅ نعم
وراثة كاملة للسلوك؟❌ جزئي❌ لا✅ نعم
✅ استخدام أكثر من واجهة:
class Printable {
  void printInfo();
}

class Saveable {
  void save();
}

class Document implements Printable, Saveable {
  @override
  void printInfo() => print("طباعة المستند");

  @override
  void save() => print("حفظ المستند");
}
Dart

وهكذا جعلنا Document يجمع بين وظيفتين مختلفتين.

✅ متى تستخدم interface؟ ومتى abstract class؟
الحالةاستخدم interfaceاستخدم abstract class
عند الحاجة لتعريف هيكل بدون تنفيذ
عند الحاجة لمنطق مشترك بين الأبناء
عند الحاجة لتنفيذ أكثر من نوع
تريد فرض تنفيذ 100% للدوال
تريد مرونة كبيرة بالوراثة✅ (لأنها متعددة)❌ (واحدة فقط)
✅ خلاصة شاملة:
العنصرالتوضيح
interfaceمجرد عقد يجب على الكلاس تنفيذه
implementsالطريقة التي نطبق بها interface
يجب تنفيذ كل شيءأي دالة في الواجهة يجب تنفيذها بالكامل
مناسب لـ polymorphism والاختبارلأنه يتيح لك تبديل التنفيذ بسهولة
لا يمكن إنشاء كائن من interfaceلأنها ليست كلاس كامل التنفيذ