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

تجاوز التنفيذات الافتراضية

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

تطبيقات default مريحة، لكن أحيانًا يحتاج نوعٌ ما إلى سلوك يختلف عن السلوك القياسي. عند حدوث ذلك، يمكنك override التطبيق الافتراضي من خلال توفير تطبيقك الخاص في كتلة impl.

ما عليك سوى تعريف method بالتوقيع نفسه، ولكن مع تضمين منطقك المخصص:

trait Greet {
    fn greet(&self) -> String {
        String::from("Hello there!")
    }
}

struct Robot {
    id: u32,
}

impl Greet for Robot {
    fn greet(&self) -> String {
        format!("BEEP BOOP. Unit {} online.", self.id)
    }
}

على الرغم من أن Greet يوفر method افتراضيًا باسم greet، فإن Robot يستبدله بالكامل بإصدار خاص به. عند استدعاء greet() على كائن من نوع Robot، تستخدم Rust الـ implementation المخصص:

let bot = Robot { id: 42 };
println!("{}", bot.greet());  // BEEP BOOP. الوحدة 42 متصلة.

يمنحك هذا مرونة: فالأنواع التي تكون راضية عن default لا تحتاج إلى كتابة أي شيء، بينما يمكن للأنواع التي تحتاج إلى سلوك متخصص أن تتجاوز فقط method التي تهتم بها. وتظل السمة تضمن أن كل نوع مُطبِّق يملك method متاحة.

challenge icon

التحدي

سهل

لنبنِ نظام إشعارات يمكن فيه لأنواع التنبيهات المختلفة تخصيص رسائلها! ستنشئ trait مع implementation افتراضية، ثم تجعل نوعًا واحدًا يستخدم الإعداد الافتراضي بينما يتجاوز نوع آخر ذلك بسلوك مخصص.

ستنظم كودك عبر ثلاثة ملفات:

  • notifiable.rs: عرّف trait عامة باسم Notifiable مع method باسم notify(&self) -> String لها implementation افتراضية تُرجع "Alert: Something happened!".
  • alerts.rs: أنشئ بنيتين عامتين تطبّقان trait بطرق مختلفة:
    • GenericAlert: بنية unit تستخدم الإشعار الافتراضي (كتلة impl فارغة)
    • UrgentAlert: بنية تحتوي على field عامة باسم message من النوع (String) وتقوم بعمل override للإعداد الافتراضي لإرجاع "URGENT: {message}" حيث إن {message} هي رسالتها المخزنة
  • main.rs: اجمع الوحدات معًا واعرض السلوكين. أنشئ GenericAlert وUrgentAlert باستخدام input المقدّم، ثم اطبع إشعاراتهما.

الفكرة الأساسية هنا هي أن GenericAlert يحصل على سلوك مجاني من الإعداد الافتراضي، بينما يوفّر UrgentAlert نسخته المتخصصة من خلال تعريف method في كتلة impl الخاصة به.

يجب أن يتبع ناتجك هذا التنسيق:

Alert: Something happened!
URGENT: {message}

على سبيل المثال، مع input هو Server is down!:

Alert: Something happened!
URGENT: Server is down!

ستتلقى input واحدًا: الرسالة الخاصة بالتنبيه العاجل.

جرّب بنفسك

mod notifiable;
mod alerts;

use alerts::{GenericAlert, UrgentAlert};
use notifiable::Notifiable;

fn main() {
    // اقرأ الإدخال لرسالة التنبيه العاجل
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let message = input.trim().to_string();

    // TODO: أنشئ مثيلاً من GenericAlert

    // TODO: أنشئ مثيلاً من UrgentAlert مع رسالة الإدخال

    // TODO: اطبع الإشعار من GenericAlert

    // TODO: اطبع الإشعار من UrgentAlert
}
quiz iconاختبر نفسك

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

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

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