الدوال العامة
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 66 من 110.
تماماً كما يمكن أن تكون الأصناف (classes) عامة (generic)، يمكن أيضاً للأساليب (methods) الفردية أن تمتلك معلمات النوع (type parameters) الخاصة بها. هذا مفيد عندما تحتاج إلى أسلوب مرن دون جعل الصنف بأكمله عاماً.
تُصرح الدالة العامة (generic method) عن معلمة النوع الخاصة بها قبل نوع الإرجاع:
T findFirst<T>(List<T> items) {
return items.first;
}
void main() {
var firstNumber = findFirst<int>([1, 2, 3]);
var firstWord = findFirst<String>(['hello', 'world']);
print(firstNumber); // 1
print(firstWord); // hello
}يمكن لـ Dart غالباً استنتاج النوع من الوسائط، لذا لا تحتاج دائماً إلى تحديده بشكل صريح:
var result = findFirst([10, 20, 30]); // Dart يستنتج intتُعد الطرق العامة (Generic methods) مفيدة بشكل خاص داخل الأصناف (classes) عندما تحتاج عمليات معينة فقط إلى مرونة في النوع:
class Printer {
void printItem<T>(T item) {
print('Printing: $item');
}
List<T> duplicate<T>(T item, int count) {
return List.filled(count, item);
}
}
void main() {
var printer = Printer();
printer.printItem<String>('Hello');
printer.printItem(42); // تم استنتاج النوع كـ int
var copies = printer.duplicate('Hi', 3);
print(copies); // [Hi, Hi, Hi]
}تمنحك الأساليب العامة (Generic methods) تحكماً دقيقاً في سلامة الأنواع على مستوى الأسلوب، مما يحافظ على بساطة فئاتك (classes) مع الاستمرار في الاستفادة من التحقق من الأنواع في وقت التجميع (compile-time).
التحدي
سهللنقم ببناء أداة مساعدة لتحويل البيانات تستعرض قوة الأساليب العامة (generic methods). ستقوم بإنشاء فئة Transformer تحتوي على أساليب يمكنها العمل مع أي نوع، مما يمنحك المرونة دون جعل الفئة بأكملها عامة.
ستقوم بتنظيم الكود الخاص بك في ملفين:
transformer.dart: أنشئ فئةTransformerمع هذه الأساليب العامة:T getFirst<T>(List<T> items)- تعيد العنصر الأول من القائمةT getLast<T>(List<T> items)- تعيد العنصر الأخير من القائمةList<T> repeat<T>(T item, int times)- تنشئ قائمة تحتوي على العنصر مكرراً لعدد المرات المحددvoid printPair<A, B>(A first, B second)- تطبع قيمتين بالتنسيقPair: [first] and [second]
main.dart: استورد ملف المحول الخاص بك واستعرض كل أسلوب عام مع أنواع مختلفة:- أنشئ مثيلاً (instance) من
Transformer - استخدم
getFirstعلى[10, 20, 30]واطبع النتيجة - استخدم
getFirstعلى['apple', 'banana', 'cherry']واطبع النتيجة - استخدم
getLastعلى[1.5, 2.5, 3.5]واطبع النتيجة - استخدم
repeatلإنشاء قائمة من'Hi'مكررة4مرات واطبع النتيجة - استخدم
repeatلإنشاء قائمة من7مكررة3مرات واطبع النتيجة - استخدم
printPairمع'Name'و42 - استخدم
printPairمع100وtrue
- أنشئ مثيلاً (instance) من
لاحظ كيف يعلن كل أسلوب عن معلمة (أو معلمات) النوع الخاصة به، مما يسمح لنفس كائن Transformer بالعمل مع الأعداد الصحيحة، السلاسل النصية، الأعداد العشرية، والقيم المنطقية - كل ذلك مع أمان النوع الكامل. يوضح أسلوب printPair استخدام معلمتين للنوع في أسلوب واحد.
المخرجات المتوقعة:
10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and trueورقة مرجعية
تُصرح الأساليب العامة (Generic methods) عن معاملات النوع قبل نوع الإرجاع، مما يسمح للأساليب الفردية بأن تكون مرنة دون جعل الفئة بأكملها عامة:
T findFirst<T>(List<T> items) {
return items.first;
}يمكن لـ Dart استنتاج النوع من الوسائط، لذا فإن التحديد الصريح للنوع اختياري:
var result = findFirst([10, 20, 30]); // Dart infers intيمكن استخدام الأساليب العامة داخل الفئات غير العامة:
class Printer {
void printItem<T>(T item) {
print('Printing: $item');
}
List<T> duplicate<T>(T item, int count) {
return List.filled(count, item);
}
}يمكن للأساليب التصريح عن معاملات نوع متعددة:
void printPair<A, B>(A first, B second) {
print('Pair: $first and $second');
}جرّب بنفسك
import 'transformer.dart';
void main() {
// إنشاء مثيل (instance) من Transformer
var transformer = Transformer();
// TODO: استخدم getFirst على [10, 20, 30] واطبع النتيجة
// TODO: استخدم getFirst على ['apple', 'banana', 'cherry'] واطبع النتيجة
// TODO: استخدم getLast على [1.5, 2.5, 3.5] واطبع النتيجة
// TODO: استخدم repeat لإنشاء قائمة من 'Hi' مكررة 4 مرات واطبعها
// TODO: استخدم repeat لإنشاء قائمة من 7 مكررة 3 مرات واطبعها
// TODO: استخدم printPair مع 'Name' و 42
// TODO: استخدم printPair مع 100 و true
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
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أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع