الـ Static Methods والحقول
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 20 من 110.
الآن بعد أن فهمت الفرق بين أعضاء المثيل (instance) والأعضاء الساكنة (static)، دعنا نستكشف كيفية استخدام الأساليب والحقول الساكنة بفعالية. فالأعضاء الساكنة مثالية للوظائف التي تنتمي إلى مفهوم الفئة (class) نفسه بدلاً من الكائنات الفردية.
تخزن الحقول الساكنة (Static fields) البيانات المشتركة عبر جميع المثيلات. وتشمل الاستخدامات الشائعة العدادات، أو قيم التكوين، أو البيانات المخزنة مؤقتًا:
class MathHelper {
static const double pi = 3.14159;
static int calculationCount = 0;
static double circleArea(double radius) {
calculationCount++;
return pi * radius * radius;
}
}
print(MathHelper.circleArea(5)); // 78.53975
print(MathHelper.circleArea(3)); // 28.27431
print(MathHelper.calculationCount); // 2لاحظ أنك تستدعي الأساليب الثابتة (static methods) مباشرة على اسم الفئة، وليس على مثيل (instance). تعمل الفئة MathHelper كأداة مساعدة - لن تحتاج أبداً إلى إنشاء كائن MathHelper.
قاعدة مهمة: لا يمكن للدوال الساكنة (static methods) الوصول إلى أعضاء الكائن (instance members) مباشرة. ليس لديها وصول إلى this لأنها غير مرتبطة بأي كائن محدد:
class Counter {
int value = 0; // حقل مثيل (Instance field)
static int total = 0; // حقل ثابت (Static field)
void increment() {
value++; // صحيح - دالة مثيل تصل إلى حقل مثيل
total++; // صحيح - دالة مثيل يمكنها الوصول إلى حقل ثابت
}
static void reset() {
total = 0; // صحيح - دالة ثابتة تصل إلى حقل ثابت
// value = 0; // خطأ! لا يمكن الوصول إلى حقل مثيل
}
}استخدم الأعضاء الساكنة (static members) عندما لا تعتمد الوظيفة على حالة الكائن (object state) - وتعد الدوال المساعدة (utility functions) أو تتبع المصنع (factory tracking) أو الثوابت المشتركة (shared constants) خيارات مثالية لذلك.
التحدي
سهللنقم ببناء فئة أدوات (utility class) لعمليات السلاسل النصية توضح كيفية عمل الأساليب (methods) والحقول (fields) الثابتة (static) معاً لتوفير وظائف مفيدة دون الحاجة إلى إنشاء كائنات (objects).
ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:
string_utils.dart: قم بتعريف فئةStringUtilsالتي تعمل كمساعد أدوات. يجب أن تحتوي الفئة الخاصة بك على:static const String defaultSeparatorمضبوط على'-'static int operationCountيبدأ بـ0لتتبع عدد العمليات التي تم إجراؤها- أسلوب ثابت
reverse(String text)يقوم بزيادةoperationCountوإرجاع السلسلة النصية معكوسة - أسلوب ثابت
join(String first, String second)يقوم بزيادةoperationCountوإرجاع السلسلتين النصيتين مدموجتين باستخدامdefaultSeparator - أسلوب ثابت
countVowels(String text)يقوم بزيادةoperationCountوإرجاع عدد الحروف المتحركة (a, e, i, o, u - غير حساسة لحالة الأحرف) - أسلوب ثابت
getStats()يرجع سلسلة نصية توضح إجمالي العمليات التي تم إجراؤها
main.dart: قم باستيراد فئة الأدوات الخاصة بك واستخدم أساليبها الثابتة:- استدعِ
reverse()مع'hello'واطبع النتيجة - استدعِ
join()مع'dart'و'lang'واطبع النتيجة - استدعِ
countVowels()مع'Programming'واطبعVowels: [count] - اطبع الإحصائيات باستخدام
getStats()
- استدعِ
تذكر استدعاء جميع الأساليب مباشرة على اسم الفئة لأنها ثابتة (static) - لن تقوم بإنشاء أي كائنات من StringUtils.
يجب أن يرجع الأسلوب getStats() بهذا التنسيق:
Operations performed: [operationCount]المخرجات المتوقعة:
olleh
dart-lang
Vowels: 3
Operations performed: 3ورقة مرجعية
تنتمي الأعضاء الساكنة (Static members) إلى الفئة نفسها بدلاً من الحالات الفردية. قم بالوصول إليها باستخدام اسم الفئة، وليس الكائن.
تخزن الحقول الساكنة (Static fields) البيانات المشتركة عبر جميع الحالات:
class MathHelper {
static const double pi = 3.14159;
static int calculationCount = 0;
static double circleArea(double radius) {
calculationCount++;
return pi * radius * radius;
}
}
print(MathHelper.circleArea(5)); // 78.53975
print(MathHelper.calculationCount); // 1قواعد الوصول:
- يمكن لأساليب الحالة (Instance methods) الوصول إلى كل من أعضاء الحالة والأعضاء الساكنة
- يمكن للأساليب الساكنة (Static methods) الوصول فقط إلى الأعضاء الساكنة (لا يمكن الوصول إلى
this)
class Counter {
int value = 0; // حقل حالة
static int total = 0; // حقل ساكن
void increment() {
value++; // صحيح - أسلوب حالة يصل إلى حقل حالة
total++; // صحيح - أسلوب حالة يمكنه الوصول إلى حقل ساكن
}
static void reset() {
total = 0; // صحيح - أسلوب ساكن يصل إلى حقل ساكن
// value = 0; // خطأ! لا يمكن الوصول إلى حقل الحالة
}
}استخدم الأعضاء الساكنة للوظائف المساعدة، أو الثوابت المشتركة، أو العدادات، أو الوظائف التي لا تعتمد على حالة الكائن.
جرّب بنفسك
import 'string_utils.dart';
void main() {
// TODO: استدعِ ()reverse مع 'hello' واطبع النتيجة
// TODO: استدعِ ()join مع 'dart' و 'lang' واطبع النتيجة
// TODO: استدعِ ()countVowels مع 'Programming' واطبع "Vowels: [count]"
// TODO: اطبع الإحصائيات باستخدام ()getStats
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع