تجاوز التنفيذات الافتراضية
جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 32 من 61.
تعتبر عمليات التنفيذ الافتراضية ملائمة، ولكن في بعض الأحيان يحتاج النوع إلى سلوك يختلف عن المعيار. عندما يحدث هذا، يمكنك تجاوز الوضع الافتراضي من خلال توفير التنفيذ الخاص بك في كتلة impl.
ببساطة، قم بتعريف الطريقة (method) بنفس التوقيع (signature)، ولكن قم بتضمين منطقك الخاص:
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 يوفر طريقة greet افتراضية، إلا أن Robot يستبدلها بالكامل بنسخته الخاصة. عندما تستدعي greet() على Robot، تستخدم Rust التنفيذ المخصص:
let bot = Robot { id: 42 };
println!("{}", bot.greet()); // BEEP BOOP. الوحدة 42 متصلة.
هذا يمنحك المرونة—فالأنواع التي تكتفي بالسلوك الافتراضي لا تحتاج إلى كتابة أي شيء، بينما الأنواع التي تحتاج إلى سلوك مخصص يمكنها عمل override فقط للـ methods التي تهمها. لا تزال الـ trait تضمن أن كل نوع يقوم بالتنفيذ لديه الـ method متاحة.
التحدي
سهللنقم ببناء نظام تنبيهات حيث يمكن لأنواع التنبيهات المختلفة تخصيص رسائلها! ستقوم بإنشاء سمة (trait) مع تنفيذ افتراضي، ثم تجعل أحد الأنواع يستخدم التنفيذ الافتراضي بينما يقوم نوع آخر بتجاوزه بسلوك مخصص.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
notifiable.rs: قم بتعريف سمة عامةNotifiableمع طريقةnotify(&self) -> Stringتحتوي على تنفيذ افتراضي يعيد"Alert: Something happened!".alerts.rs: أنشئ هيكلين (structs) عامين ينفذان السمة الخاصة بك بشكل مختلف:GenericAlert— هيكل وحدة (unit struct) يستخدم التنبيه الافتراضي (كتلة impl فارغة).UrgentAlert— هيكل يحتوي على حقلmessageعام (String) يقوم بـ تجاوز (override) التنفيذ الافتراضي ليعيد"URGENT: {message}"حيث{message}هي الرسالة المخزنة فيه.
main.rs: اجمع وحداتك معاً واستعرض كلا السلوكين. أنشئGenericAlertوUrgentAlertباستخدام المدخلات المقدمة، ثم اطبع تنبيهاتهما.
الفكرة الأساسية هنا هي أن GenericAlert يحصل على سلوك مجاني من التنفيذ الافتراضي، بينما يوفر UrgentAlert نسخته المتخصصة من خلال تعريف الطريقة في كتلة impl الخاصة به.
يجب أن يتبع مخرجك هذا التنسيق:
Alert: Something happened!
URGENT: {message}على سبيل المثال، مع المدخل Server is down!:
Alert: Something happened!
URGENT: Server is down!ستتلقى مدخلاً واحداً: الرسالة الخاصة بالتنبيه العاجل (urgent alert).
ورقة مرجعية
يمكنك تجاوز تطبيقات السمات (trait) الافتراضية من خلال توفير تطبيقك الخاص في كتلة impl:
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)
}
}
let bot = Robot { id: 42 };
println!("{}", bot.greet()); // BEEP BOOP. Unit 42 online.
يمكن للأنواع التي لا تحتاج إلى سلوك مخصص استخدام كتلة impl فارغة لقبول التطبيق الافتراضي، بينما يمكن للأنواع التي تتطلب سلوكًا متخصصًا تجاوز طرق (methods) محددة من خلال تعريفها بنفس التوقيع (signature).
جرّب بنفسك
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
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائط