الفئات العامة
جزء من قسم البرمجة كائنية التوجه في رحلة Dart على Coddy. الدرس 65 من 110.
لقد رأيت كيف تستخدم المجموعات المضمّنة في Dart، مثل List<String>، معلمات النوع. حان الوقت الآن لإنشاء فئات generic خاصة بك تعمل مع أي نوع تحدده.
يستخدم الصنف generic معلَمة نوع (عادةً T) كعنصر نائب للنوع الفعلي الذي سيتم توفيره عند إنشاء مثيل:
class Box<T> {
T content;
Box(this.content);
T getContent() => content;
}
void main() {
var stringBox = Box<String>('Hello');
var intBox = Box<int>(42);
print(stringBox.getContent()); // Hello
print(intBox.getContent()); // 42
}يعمل T كمتغير نوع — عند إنشاء Box<String>، يصبح كل T في الفئة String. وهذا يمنحك أمان الأنواع دون كتابة فئات منفصلة لكل نوع.
يمكنك استخدام معاملات نوع متعددة عندما تحتاج فئتك إلى العمل مع أكثر من نوع واحد:
class Pair<K, V> {
K first;
V second;
Pair(this.first, this.second);
}
void main() {
var pair = Pair<String, int>('age', 25);
print('${pair.first}: ${pair.second}'); // age: 25
}تُعد الفئات generic أساسًا للشفرة القابلة لإعادة الاستخدام والآمنة من ناحية الأنواع. وبدلًا من تكرار المنطق لأنواع مختلفة أو فقدان معلومات النوع باستخدام dynamic، تتيح لك الأنواع العامة كتابة شفرة مرنة يمكن للمصرّف التحقق منها أيضًا.
التحدي
سهللنُنشئ نظامًا لتغليف الهدايا يستخدم الأصناف generic لإنشاء حاويات مرنة لأنواع مختلفة من العناصر. ستنشئ صنف Wrapper عامًا يمكنه تغليف أي نوع من content، وصنف GiftBox بمعاملَي نوع لربط هدية برسالة بطاقة.
ستنظّم الشيفرة في ملفين:
wrapper.dart: Define أصنافك العامة هنا:- صنف عام
Wrapper<T>مع خاصيةT contentوبانٍ. أضف أسلوبًاunwrap()الذي returns المحتوى، وأسلوبًاdescribe()يطبعWrapped: [content] - صنف عام
GiftBox<G, C>مع خاصيتين:G giftوC card. أضف بانياً وأسلوبًاopen()يطبعGift: [gift]في سطر واحد وCard: [card]في السطر التالي
- صنف عام
main.dart: استورد ملف Wrapper الخاص بك ووضّح الأصناف العامة باستخدام أنواع مختلفة:- Create
Wrapper<String>يحتوي على'Chocolate'واستدعِdescribe() - Create
Wrapper<int>يحتوي على42واستدعِdescribe() - Create
Wrapper<double>يحتوي على3.14واستدعِdescribe() - اطبع سطرًا فارغًا
- Create
GiftBox<String, String>مع الهدية'Teddy Bear'والبطاقة'Happy Birthday!'، ثم استدعِopen() - اطبع سطرًا فارغًا
- Create
GiftBox<int, String>مع الهدية100(يمثل قيمة بطاقة هدية) والبطاقة'Congratulations!'، ثم استدعِopen()
- Create
لاحظ كيف يعمل الصنف Wrapper نفسه بسلاسة مع السلاسل النصية والأعداد الصحيحة والأعداد العشرية. يوضّح الصنف GiftBox استخدام معاملَي نوع لربط نوعين مختلفين معًا - يمكن أن تكون الهدية من أي نوع، بينما تظل رسالة البطاقة سلسلة نصية.
الناتج المتوقع:
Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14
Gift: Teddy Bear
Card: Happy Birthday!
Gift: 100
Card: Congratulations!جرّب بنفسك
import 'wrapper.dart';
void main() {
// TODO: أنشئ Wrapper<String> يحتوي على 'Chocolate' واستدعِ describe()
// TODO: أنشئ Wrapper<int> يحتوي على 42 واستدعِ describe()
// TODO: أنشئ Wrapper<double> يحتوي على 3.14 واستدعِ describe()
// TODO: اطبع سطرًا فارغًا
// TODO: Create a GiftBox<String, String> with gift 'Teddy Bear'
// and card 'Happy Birthday!', then call open()
// TODO: اطبع سطرًا فارغًا
// TODO: أنشئ GiftBox<int, String> مع هدية 100
// and card 'Congratulations!', then call open()
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات الـ OOP
الملفات الخارجيةالمكتبات والـ Importsمقدمة في الـ OOPالـ Classes مقابل الـ Objectsالكلمة المفتاحية thisالـ Methodsمتغيرات الـ Instanceأساسيات الـ Constructorمراجعة - آلة حاسبة بسيطة4أمان الـ Null
مقدمة في أمان الـ NullNullable مقابل Non-Nullableعاملا الـ ? و !الكلمة المفتاحية Late وأمان الـ Nullالعوامل المدركة للـ Nullأمان الـ Null في الـ Classesمراجعة - نظام ملف تعريف المستخدم7الفئات المجردة والواجهات
الفئات المجردةالدوال المجردةالواجهات في Dartالواجهات الضمنيةالتنفيذ مقابل التوسيعالواجهات المتعددةمراجعة - حاسبة الأشكال10المجموعات والأنماط العامة
نظرة عامة على List و Set و Mapالمجموعات آمنة النوعالفئات العامةالدوال العامةقيود الأنماط العامةIterable و Iteratorملخص - التخزين العام13مفاهيم OOP المتقدمة
التركيب مقابل الوراثة (Composition vs Inheritance)دوال التوسعة (Extension Methods)الأصناف القابلة للاستدعاء (Callable Classes)الأصناف المختومة (Sealed Classes - Dart 3)السجلات (Records - Dart 3)الأنماط والمطابقة (Patterns & Matching - 3.0)التعدادات مع الدوال (Enums with Methods)2المنشئات في Dart
المنشئ الافتراضيالمنشئات المسماةقوائم التهيئةالمنشئات الثابتةالمنشئات المصنعيةالمنشئات الموجهةملخص - بناء الأشكال5التغليف (Encapsulation)
الأعضاء العامة مقابل الخاصةاتفاقية البادئة _الخصوصية على مستوى المكتبةتعمق في Getters و Settersإخفاء المعلوماتمراجعة - سجلات الطلاب8Mixins
مقدمة إلى Mixinsإنشاء Mixinsاستخدام Mixins متعددةالكلمة المفتاحية on في MixinsMixin مقابل الوراثة (Inheritance)Mixin مقابل الواجهة (Interface)مراجعة - نظام الحيوانات (Animal System)3خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticحقول Final و Constمتغيرات Lateالـ Static Methods والحقولدوال الـ Getters والـ Settersمراجعة - مدير الحساب البنكي6الوراثة
أساسيات الوراثةالكلمة المفتاحية superإعادة تعريف الدوال (Method Overriding)الوسم @overrideالكلمة المفتاحية final Classالدوال البانية والوراثةمراجعة - هيكلية الموظفين9تعدد الأشكال
أساسيات تعدد الأشكالتعدد الأشكال عبر الـ Interfacesالتحقق من النوع أثناء التشغيلالمعاملات is و asالكلمة المفتاحية Covariantملخص - معالج الدفع12البرمجة الكائنية غير المتزامنة (Async OOP)
Futures و async/awaitأساسيات الـ Streamsمتحكمات الـ Streamsالـ Constructors غير المتزامنةالعمليات غير المتزامنة في دوال الكلاسمراجعة - جالب البيانات (Data Fetcher)15أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودعتدرّب بنفسك: مترجم Dart عبر الإنترنت