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

الوسم @override

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

يُعد التعليق @override علامة من علامات أفضل الممارسات التي تخبر Dart (والمطورين الآخرين) بأنك تقوم عمداً باستبدال دالة (method) من فئة أب (parent class). وبينما يعمل تجاوز الدوال (method overriding) بدونه، فإن استخدام @override يضيف شبكة أمان مهمة.

class Animal {
  String name;
  
  Animal(this.name);
  
  void speak() {
    print('$name makes a sound');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  @override
  void speak() {
    print('$name barks: Woof!');
  }
}

يوفر هذا التعليق التوضيحي (annotation) فائدتين رئيسيتين. أولاً، يوثق نيتك بوضوح - فأي شخص يقرأ الكود سيعرف على الفور أن هذه الطريقة (method) موجودة في الفئة الأب (parent class). ثانياً، سيقوم محلل Dart (Dart's analyzer) بتنبيهك إذا كانت الطريقة الأب غير موجودة بالفعل، مما يساعد في اكتشاف الأخطاء الإملائية وأخطاء إعادة هيكلة الكود (refactoring) في وقت مبكر.

تأمل ما يحدث إذا أخطأت في كتابة اسم الطريقة بدون @override:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speek() {  // خطأ إملائي! لا يوجد تحذير بدون @override
    print('$name meows');
  }
}

بدون هذا التعليق التوضيحي (annotation)، يفترض Dart أنك تقوم بإنشاء طريقة (method) جديدة تسمى speek(). وباستخدام @override، سيقوم المحلل (analyzer) فوراً بالتنبيه إلى عدم وجود مثل هذه الطريقة في الفئة الأب (parent class). يمنع هذا التعليق التوضيحي البسيط الأخطاء الخفية التي قد يصعب تتبعها لاحقاً.

challenge icon

التحدي

سهل

لنقم ببناء نظام مشغل وسائط يوضح أهمية التعليق التوضيحي @override عند تخصيص السلوك الموروث. ستقوم بإنشاء أنواع وسائط مختلفة يقوم كل منها بتشغيل المحتوى بطريقته الخاصة.

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

  • media.dart: حدد التسلسل الهرمي للوسائط هنا:
    • فئة Media مع خاصية String title، ومنشئ (constructor) يأخذ العنوان، وطريقة play() تطبع Playing: [title]
    • فئة Song ترث من Media وتضيف خاصية String artist. استخدم التعليق التوضيحي @override وقم بإعادة كتابة play() لطباعة Playing song: [title] by [artist]
    • فئة Video ترث من Media وتضيف خاصية int duration (بالثواني). استخدم @override وقم بإعادة كتابة play() لاستدعاء نسخة الفئة الأب أولاً باستخدام super.play()، ثم طباعة Duration: [duration] seconds
  • main.dart: استورد ملف الوسائط الخاص بك واستعرض الطرق التي تمت إعادة كتابتها:
    • أنشئ كائن Media بالعنوان 'Generic Content' واستدعِ play()
    • اطبع سطراً فارغاً
    • أنشئ Song بالعنوان 'Imagine' والفنان 'John Lennon'، ثم استدعِ play()
    • اطبع سطراً فارغاً
    • أنشئ Video بالعنوان 'Dart Tutorial' ومدة 360، ثم استدعِ play()

يوثق التعليق التوضيحي @override نيتك ويساعد في اكتشاف الأخطاء. إذا أخطأت في كتابة play() كـ plya()، فسينبهك التعليق التوضيحي إلى عدم وجود مثل هذه الطريقة في الفئة الأب.

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

Playing: Generic Content

Playing song: Imagine by John Lennon

Playing: Dart Tutorial
Duration: 360 seconds

ورقة مرجعية

تُستخدم العلامة التوضيحية @override لتمييز الدوال التي تستبدل عمدًا دالة موجودة في الفئة الأب (parent class). ورغم أنها اختيارية، إلا أنها توفر الأمان والوضوح.

class Animal {
  String name;
  
  Animal(this.name);
  
  void speak() {
    print('$name makes a sound');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  @override
  void speak() {
    print('$name barks: Woof!');
  }
}

فوائد @override:

  • توثيق القصد - توضح أن الدالة موجودة بالفعل في الفئة الأب
  • اكتشاف الأخطاء - يقوم محلل Dart (analyzer) بإصدار تحذير إذا كانت الدالة الأب غير موجودة، مما يمنع الأخطاء الإملائية

بدون @override، تؤدي الأخطاء الإملائية إلى إنشاء دوال جديدة بدلاً من التنبيه بوجود خطأ:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speek() {  // Typo creates new method without warning
    print('$name meows');
  }
}

يمكنك استدعاء نسخة الفئة الأب باستخدام super:

@override
void play() {
  super.play();  // Call parent method first
  print('Additional behavior');
}

جرّب بنفسك

import 'media.dart';

void main() {
  // TODO: أنشئ كائن Media بالعنوان 'Generic Content' واستدعِ ()play
  
  
  // TODO: اطبع سطرًا فارغًا
  
  
  // TODO: أنشئ Song بالعنوان 'Imagine' والفنان 'John Lennon'، ثم استدعِ ()play
  
  
  // TODO: اطبع سطرًا فارغًا
  
  
  // TODO: أنشئ Video بالعنوان 'Dart Tutorial' ومدة 360، ثم استدعِ ()play
  
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming