دليل لغة دارت الشامل

تعلم أساسيات ومتقدمات لغة البرمجة دارت

1. مقدمة عن لغة دارت

دارت (Dart) هي لغة برمجة حديثة طورتها شركة جوجل، وهي اللغة الأساسية لتطوير تطبيقات Flutter. تتميز دارت بسهولة التعلم والقوة في الأداء.

مميزات لغة دارت:

  • سهولة في التعلم والاستخدام
  • أداء عالي وسرعة في التنفيذ
  • دعم البرمجة كائنية التوجه(oop)
  • إدارة ذاكرة تلقائية
  • مكتبات غنية ومتنوعة
                        
                            void main() {
                                print('أهلاً بك في عالم دارت!');
                            }
                        
                    

2. كل شيء عن المتغيرات

المتغيرات في دارت هي حاويات لتخزين البيانات. يمكن تعريف المتغيرات بطرق مختلفة:

طرق تعريف المتغيرات:

                        
                            //من أجل إنشاء متغير جديد
                            type_variable name_variable = value_variable ; 
                            //أمثلة  
                            String firstName = 'hamza';
                            int age = 25 ;     
                        
                    

خصائص المتغيرات:

  • يمكن تغيير قيمتها بعد التعريف
  • لها نوع بيانات محدد
  • تحتاج إلى تهيئة قبل الاستخدام
  • حساسة لحالة الأحرف

3. أنواع المتغيرات

دارت تدعم عدة أنواع من البيانات الأساسية:

النوع الوصف مثال شروط تغيير القيمة
int الأعداد الصحيحة int age = 25; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع int
double الأعداد العشرية double height = 175.5; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع double
String النصوص String name = "hamza"; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع String
bool القيم المنطقية bool isStudent = true; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع bool
List القوائم List<String> names = ['hamza', 'ahmed']; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع List
Map الخرائط Map<String, int> grades = {'ahmed': 85}; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نوع Map
var يتخد نوع القيمة المخزنة فيه var value = 'hamza'; يمكن تغيير قيمتها بعد التعريف بشرط أن تكون من نفس نوع قيمته البدئية
dynamic يتخد نوع القيمة المخزنة فيه dynamic value = 'hamza'; يمكن تغيير قيمتها بعد التعريف بأي نوع من المتغيرات
                        
                            void main() {
                                // أمثلة على أنواع المتغيرات
                                int studentCount = 30;
                                double average = 85.5;
                                String courseName = 'البرمجة بدارت';
                                bool isPassed = true;
                                
                                List<String> students = ['أحمد', 'فاطمة', 'محمد'];
                                Map<String, double> grades = {
                                    'ahmed': 88.5,
                                    'fatima': 92.0,
                                    'mohamed': 85.5
                                };
                                
                                print('عدد الطلاب: $studentCount');
                                print('المعدل: $average');
                                }
                        
                    

4. كيفية تسمية المتغيرات

هناك قواعد وإرشادات مهمة لتسمية المتغيرات في دارت:

القواعد الإجبارية:

  • يجب أن تبدأ بحرف صغير أو شرطة سفلية (_)
  • لا يمكن أن تبدأ برقم
  • لا تحتوي على مسافات
  • لا تستخدم الكلمات المحجوزة
  • حساسة لحالة الأحرف

الإرشادات المستحسنة:

                        
                            // أسماء جيدة - camelCase
                            String firstName = 'أحمد';
                            int studentAge = 20;
                            bool isLoggedIn = false;
                            double accountBalance = 1500.50;

                            // أسماء للثوابت - SCREAMING_SNAKE_CASE
                            const int MAX_STUDENTS = 100;
                            const String API_URL = 'https://api.example.com';

                            // أسماء للمتغيرات الخاصة - تبدأ بـ _
                            String _privateData = 'بيانات خاصة';
                            int _internalCounter = 0;

                            // أمثلة على أسماء سيئة (تجنبها)
                            // String abc = 'غير واضح';
                            // int 123number = 10; // خطأ - يبدأ برقم
                            // bool class = true; // خطأ - كلمة محجوزة
                        
                    
نصيحة: استخدم أسماء واضحة ومعبرة تصف الغرض من المتغير.

5. دمج المتغيرات

هناك عدة طرق لدمج المتغيرات والنصوص في دارت:

1. استخدام علامة الدولار ($)

                        
                            String firstName = 'أحمد';
                            String lastName = 'محمد';
                            int age = 25;

                            // الدمج باستخدام $
                            String introduction = 'اسمي $firstName $lastName وعمري $age سنة';
                            print(introduction);

                            // للتعبيرات المعقدة استخدم ${}
                            String message = 'العام القادم سأكون ${age + 1} سنة';
                            print(message);
                        
                    

2. استخدام علامة الجمع (+)

                        
                            String greeting = 'مرحباً ' + firstName + ' ' + lastName;
                            String ageText = 'عمرك هو ' + age.toString() + ' سنة';
                        
                    

3. استخدام StringBuffer للدمج المتقدم

                        
                            StringBuffer buffer = StringBuffer();
                            buffer.write('الاسم: ');
                            buffer.write(firstName);
                            buffer.write(' ');
                            buffer.write(lastName);
                            buffer.writeln(); // سطر جديد
                            buffer.write('العمر: ');
                            buffer.write(age);

                            String result = buffer.toString();
                            print(result);
                        
                    

4. دمج القوائم

                        
                            List<String> names = ['أحمد', 'فاطمة', 'محمد'];
                            String allNames = names.join(', '); // 'أحمد, فاطمة, محمد'
                            print('الأسماء: $allNames');    
                        
                    

6. التحويل بين أنواع المتغيرات

غالباً ما نحتاج لتحويل البيانات من نوع إلى آخر:

تحويل النصوص إلى أرقام

                        
                            // تحويل النص إلى عدد صحيح
                            String ageText = '25';
                            int age = int.parse(ageText);

                            // تحويل النص إلى عدد عشري
                            String heightText = '175.5';
                            double height = double.parse(heightText);

                            // التحويل الآمن مع معالجة الأخطاء
                            String invalidNumber = 'abc';
                            int? result = int.tryParse(invalidNumber); // يعيد null إذا فشل
                            if (result != null) {
                            print('الرقم: $result');
                            } else {
                            print('فشل في التحويل');
                            }
                        
                    

تحويل الأرقام إلى نصوص

                        
                            int count = 42;
                            double price = 99.99;

                            String countText = count.toString(); // '42'
                            String priceText = price.toString(); // '99.99'

                            // تنسيق الأرقام العشرية
                            String formattedPrice = price.toStringAsFixed(1); // '100.0'
                            print('السعر: $formattedPrice ريال');
                        
                    

تحويلات أخرى مفيدة

                        
                            // تحويل بين int و double
                            int wholeNumber = 10;
                            double decimalNumber = wholeNumber.toDouble(); // 10.0

                            double floatNumber = 15.7;
                            int integerPart = floatNumber.toInt(); // 15

                            // تحويل القوائم
                            List<int> numbers = [1, 2, 3, 4, 5];
                            List<String> stringNumbers = numbers.map((n) => n.toString()).toList();

                            // تحويل إلى منطقي
                            String boolText = 'true';
                            bool boolValue = boolText.toLowerCase() == 'true';

                        
                    

7. جميع جوانب إدخال المستخدم

للحصول على إدخال من المستخدم، نستخدم حزمة dart:io:

                        
                            import 'dart:io';

                            void main() {
                            // إدخال نص بسيط
                            print('ما اسمك؟');
                            String? name = stdin.readLineSync();
                            print('أهلاً $name!');
                            
                            // إدخال رقم
                            print('كم عمرك؟');
                            String? ageInput = stdin.readLineSync();
                            int age = int.parse(ageInput ?? '0');
                            print('عمرك $age سنة');
                            
                            // إدخال مع التحقق
                            int? validAge;
                            while (validAge == null) {
                                print('أدخل عمرك (رقم صحيح):');
                                String? input = stdin.readLineSync();
                                validAge = int.tryParse(input ?? '');
                                if (validAge == null) {
                                print('خطأ: يرجى إدخال رقم صحيح');
                                }
                            }
                            }
                        
                    

دوال مساعدة للإدخال الآمن

                        
                            import 'dart:io';

                            // دالة للحصول على نص
                            String getStringInput(String prompt) {
                            print(prompt);
                            return stdin.readLineSync() ?? '';
                            }

                            // دالة للحصول على رقم صحيح
                            int getIntInput(String prompt) {
                            while (true) {
                                print(prompt);
                                String? input = stdin.readLineSync();
                                int? result = int.tryParse(input ?? '');
                                if (result != null) {
                                return result;
                                }
                                print('خطأ: يرجى إدخال رقم صحيح');
                            }
                            }

                            // دالة للحصول على رقم عشري
                            double getDoubleInput(String prompt) {
                            while (true) {
                                print(prompt);
                                String? input = stdin.readLineSync();
                                double? result = double.tryParse(input ?? '');
                                if (result != null) {
                                return result;
                                }
                                print('خطأ: يرجى إدخال رقم صالح');
                            }
                            }

                            void main() {
                            String name = getStringInput('ما اسمك؟');
                            int age = getIntInput('كم عمرك؟');
                            double height = getDoubleInput('ما طولك بالسنتيمتر؟');
                            
                            print('الاسم: $name');
                            print('العمر: $age سنة');
                            print('الطول: $height سم');
                            }
                        
                    

8. تعريف const و final والفروقات بينهما

كلاهما يستخدم لإنشاء متغيرات لا يمكن تغييرها، لكن هناك فروقات مهمة:

const - الثوابت وقت الترجمة

                        
                            // const يجب أن تكون قيمتها معروفة وقت الترجمة
                            const String appName = 'تطبيق دارت';
                            const int maxUsers = 1000;
                            const double pi = 3.14159;

                            // يمكن استخدامها في التعبيرات الثابتة
                            const int secondsInMinute = 60;
                            const int minutesInHour = 60;
                            const int secondsInHour = secondsInMinute * minutesInHour; // 3600

                            // للقوائم والخرائط الثابتة
                            const List<String> weekDays = [
                            'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 
                            'الخميس', 'الجمعة', 'السبت'
                            ];

                            const Map<String, String> colors = {
                            'أحمر': '#FF0000',
                            'أخضر': '#00FF00',
                            'أزرق': '#0000FF'
                            };
                        
                    

final - الثوابت وقت التنفيذ

                        
                            // final يمكن تحديد قيمتها وقت التنفيذ
                            final String currentTime = DateTime.now().toString();
                            final int randomNumber = (1000 * 0.5).round();

                            // يمكن تهيئتها لاحقاً
                            final String userName;
                            // ... كود آخر
                            userName = 'أحمد محمد'; // يتم تحديدها مرة واحدة فقط

                            // للكائنات المعقدة
                            final List<String> dynamicList = [];
                            dynamicList.add('عنصر 1'); // يمكن تعديل محتوى القائمة
                            dynamicList.add('عنصر 2');
                            // dynamicList = []; // خطأ - لا يمكن إعادة تعيين المتغير
                        
                    

جدول المقارنة

الخاصية const final
وقت التحديد وقت الترجمة وقت التنفيذ
إعادة التعيين غير مسموح غير مسموح
تعديل المحتوى غير مسموح مسموح للكائنات القابلة للتغيير
استهلاك الذاكرة أقل (نسخة واحدة) عادي
نصيحة: استخدم const للقيم الثابتة المعروفة مسبقاً، و final للقيم التي تحدد مرة واحدة وقت التنفيذ.

9. المنطق والعوامل العلائقية

العوامل المنطقية والعلائقية أساسية لبناء الشروط والقرارات:

نوع bool

                        
                            bool isStudent = true;
                            bool isGraduated = false;
                            bool isOnline = true;

                            // يمكن تحديدها من خلال التعبيرات
                            int age = 20;
                            bool isAdult = age >= 18; // true
                            bool isChild = age < 13;  // false
                        
                    

العوامل العلائقية (Relational Operators)

                        
                            int a = 10;
                            int b = 20;

                            // المقارنة
                            bool isEqual = (a == b);        // false - متساوي
                            bool isNotEqual = (a != b);     // true - غير متساوي
                            bool isGreater = (a > b);       // false - أكبر من
                            bool isLess = (a < b);          // true - أصغر من
                            bool isGreaterEqual = (a >= b); // false - أكبر من أو يساوي
                            bool isLessEqual = (a <= b);    // true - أصغر من أو يساوي

                            print('$a == $b: $isEqual');
                            print('$a != $b: $isNotEqual');
                            print('$a > $b: $isGreater');
                            print('$a < $b: $isLess');
                        
                    

العوامل المنطقية (Logical Operators)

                        
                            bool hasLicense = true;
                            bool hasInsurance = false;
                            int age = 22;

                            // AND (&&) - يجب أن تكون كلا الحالتين صحيحتين
                            bool canDriveAnd = hasLicense && (age >= 18); // true
                            bool canDriveAll = hasLicense && hasInsurance && (age >= 18); // false

                            // OR (||) - يكفي أن تكون إحدى الحالتين صحيحة
                            bool hasDocument = hasLicense || hasInsurance; // true

                            // NOT (!) - عكس القيمة المنطقية
                            bool doesntHaveLicense = !hasLicense; // false
                            bool isMinor = !(age >= 18); // false

                            print('يمكن القيادة: $canDriveAnd');
                            print('لديه وثيقة: $hasDocument');
                            print('قاصر: $isMinor');
                        
                    

أمثلة عملية

                        
                            // فحص صحة كلمة المرور
                            String password = 'MyPass123';
                            bool isLongEnough = password.length >= 8;
                            bool hasUpperCase = password.contains(RegExp(r'[A-Z]'));
                            bool hasLowerCase = password.contains(RegExp(r'[a-z]'));
                            bool hasDigit = password.contains(RegExp(r'\d'));
                        
                    

10. شروط if

جمل الشرط تتيح لنا تنفيذ كود مختلف بناءً على شروط معينة:

الشرط البسيط if

                        
                            int age = 18;

                            if (age >= 18) {
                                print('أنت بالغ');
                            }
        
                            // شرط بدون أقواس للسطر الواحد
                            if (age >= 18) print('يمكنك القيادة');        
                        
                    

if-else الشرط مع البديل

                        
                            int score = 75;

                            if (score >= 60) {
                                print('نجحت في الامتحان');
                            } else {
                                print('للأسف، لم تنجح');
                            }
        
                            // تحديد مستوى الدرجة
                            if (score >= 90) {
                                print('ممتاز');
                            } else if (score >= 80) {
                                print('جيد جداً');
                            } else if (score >= 70) {
                                print('جيد');
                            } else if (score >= 60) {
                                print('مقبول');
                            } else {
                                print('راسب');
                            }
        
                        
                    

الشروط المعقدة

                        
                            String username = 'أحمد';
                            String password = '12345';
                            bool isLoggedIn = false;

                            // شرط مركب
                            if (username.isNotEmpty && password.length >= 5) {
                                if (username == 'أحمد' && password == '12345') {
                                    isLoggedIn = true;
                                    print('تم تسجيل الدخول بنجاح');
                                } else {
                                    print('اسم المستخدم أو كلمة المرور خاطئة');
                                }
                            } else {
                                print('يرجى إدخال بيانات صحيحة');
                            }

                            // شرط بالعامل الثلاثي (Ternary Operator)
                            String message = isLoggedIn ? 'مرحباً $username' : 'يرجى تسجيل الدخول';
                            print(message);
                        
                    

التحقق من null

                        
                            String? userName; // قابل للقيمة null

                            // التحقق التقليدي
                            if (userName != null) {
                                print('اسم المستخدم: $userName');
                            } else {
                                print('لم يتم تعيين اسم المستخدم');
                            }
        
                            // استخدام null-aware operators
                                // تعيين قيمة افتراضية إذا كانت null
                                userName ??= 'ضيف '; 
                                print('أهلاً ${userName ?? "ضيف"}'); 
        
                            // Safe navigation
                                String? email = null;
                                // لن يسبب خطأ حتى لو كانت null
                                int? emailLength = email?.length; 
                                // قيمة افتراضية عند العرض
                                print('طول الايميل: ${emailLength ?? "غير محدد"}');        
                        
                    

switch-case للشروط المتعددة

                        
                            String day = 'الاثنين';

                            switch (day) {
                                case 'السبت':
                                case 'الأحد':
                                    print('عطلة نهاية الأسبوع');
                                    break;
                                case 'الاثنين':
                                    print('بداية الأسبوع');
                                    break;
                                case 'الثلاثاء':
                                case 'الأربعاء':
                                case 'الخميس':
                                    print('منتصف الأسبوع');
                                    break;
                                case 'الجمعة':
                                    print('آخر يوم عمل');
                                    break;
                                default:
                                    print('يوم غير معروف');
                            }
        
                            // switch expression (في Dart 3.0+)
                            String dayType = switch (day) {
                                'السبت' || 'الأحد' => 'عطلة',
                                'الاثنين' => 'بداية الأسبوع',
                                'الجمعة' => 'نهاية الأسبوع',
                                _ => 'يوم عادي'
                            };
                            print('نوع اليوم: $dayType');
        
                        
                    

11. جميع أنواع الحلقات التكرارية

الحلقات التكرارية تتيح لنا تنفيذ كود متكرر بفعالية:

حلقة for التقليدية

                        
                            // الشكل الأساسي
                            for (int i = 0; i < 5; i++) {
                                print('الرقم: $i');
                            }
        
                            // عد تنازلي
                            for (int i = 10; i >= 1; i--) {
                                print('العد التنازلي: $i');
                            }
        
                            // خطوات مختلفة
                            for (int i = 0; i <= 20; i += 2) {
                                print('الأرقام الزوجية: $i');
                            }
        
                            // حلقات متداخلة - طباعة جدول الضرب
                            for (int i = 1; i <= 3; i++) {
                                for (int j = 1; j <= 3; j++) {
                                    print('$i × $j = ${i * j}');
                                }
                                print('---');
                            }
        
                        
                    

حلقة for-in للمجموعات

                        
                            // للقوائم
                            List fruits = ['تفاح', 'موز', 'برتقال', 'عنب'];
                            for (String fruit in fruits) {
                                print('الفاكهة: $fruit');
                            }
                            // للخرائط
                            Map grades = {
                                'أحمد': 85,
                                'فاطمة': 92,
                                'محمد': 78
                            };
        
                            for (String student in grades.keys) {
                                print('$student: ${grades[student]}');
                            }
        
                            // للنصوص (كل حرف)
                            String word = 'مرحبا';
                            for (String char in word.split('')) {
                                print('الحرف: $char');
                            }
                        
                    

حلقة while

                        
                            // while الأساسية
                            int counter = 0;
                            while (counter < 5) {
                                print('العداد: $counter');
                                counter++;
                            }

                            // مثال عملي - البحث في قائمة
                            List numbers = [1, 5, 8, 12, 15, 20];
                            int target = 12;
                            int index = 0;
                            bool found = false;

                            while (index < numbers.length && !found) {
                                if (numbers[index] == target) {
                                    found = true;
                                    print('وُجد الرقم $target في الموضع $index');
                                }
                                index++;
                            }

                            if (!found) {
                                print('لم يُوجد الرقم $target');
                            }

                            // حلقة لا نهائية مع شرط الخروج
                            while (true) {
                                print('أدخل "خروج" للإنهاء:');
                                String? input = stdin.readLineSync();
                                if (input?.toLowerCase() == 'خروج') {
                                    break;
                                }
                                print('كتبت: $input');
                            }
                        
                    

حلقة do-while

                        
                            // تنفذ مرة واحدة على الأقل
                            int attempts = 0;
                            String? password;

                            do {
                                attempts++;
                                print('أدخل كلمة المرور (المحاولة $attempts):');
                                password = stdin.readLineSync();
                                
                                if (password != 'سري123') {
                                    print('كلمة مرور خاطئة');
                                }
                            } while (password != 'سري123' && attempts < 3);

                            if (password == 'سري123') {
                                print('تم تسجيل الدخول بنجاح');
                            } else {
                                print('تم استنفاد المحاولات');
                            }

                            // مثال آخر - قائمة طعام
                            int choice;
                            do {
                                print('--- القائمة ---');
                                print('1. إضافة عنصر');
                                print('2. عرض العناصر');
                                print('3. حذف عنصر');
                                print('0. خروج');
                                print('اختر رقماً:');
                                
                                choice = int.tryParse(stdin.readLineSync() ?? '') ?? -1;
                                
                                switch (choice) {
                                    case 1:
                                    print('تم اختيار إضافة عنصر');
                                    break;
                                    case 2:
                                    print('تم اختيار عرض العناصر');
                                    break;
                                    case 3:
                                    print('تم اختيار حذف عنصر');
                                    break;
                                    case 0:
                                    print('شكراً لاستخدام البرنامج');
                                    break;
                                    default:
                                    print('خيار غير صحيح');
                                }
                            } while (choice != 0);
                        
                    

كلمات التحكم في الحلقات

                        
                            // break - للخروج من الحلقة
                            for (int i = 1; i <= 10; i++) {
                                if (i == 5) {
                                    print('توقف عند $i');
                                    break; // يخرج من الحلقة
                                }
                                print('الرقم: $i');
                            }
        
                            // continue - لتخطي التكرار الحالي
                            print('\nالأرقام الفردية فقط:');
                            for (int i = 1; i <= 10; i++) {
                                if (i % 2 == 0) {
                                    continue; // يتخطى الأرقام الزوجية
                                }
                                print('رقم فردي: $i');
                            }
        
                            // Label للحلقات المتداخلة
                            outer: for (int i = 1; i <= 3; i++) {
                                for (int j = 1; j <= 3; j++) {
                                    if (i == 2 && j == 2) {
                                        print('خروج من كلا الحلقتين');
                                        break outer; // يخرج من الحلقة الخارجية
                                    }
                                    print('i=$i, j=$j');
                                }
                            }
        
                        
                    

12. الدوال في دارت

الدوال هي كتل من الكود يمكن إعادة استخدامها وتنظيم البرنامج:

الدوال الأساسية

                        
                            // دالة بسيطة بدون معاملات ولا ترجع قيمة
                            void sayHello() {
                                print('أهلاً وسهلاً!');
                            }

                            // دالة ترجع قيمة
                            String getGreeting() {
                                return 'مرحباً بك في عالم دارت';
                            }

                            // دالة بمعاملات
                            int addNumbers(int a, int b) {
                                return a + b;
                            }

                            // دالة بمعاملات اختيارية
                            void printInfo(String name, [int? age, String? city]) {
                                print('الاسم: $name');
                                if (age != null) print('العمر: $age');
                                if (city != null) print('المدينة: $city');
                            }

                                // استخدام الدوال
                            void main() {
                                sayHello();
                                
                                String greeting = getGreeting();
                                print(greeting);
                                
                                int sum = addNumbers(10, 20);
                                print('المجموع: $sum');
                                
                                printInfo('أحمد');
                                printInfo('فاطمة', 25);
                                printInfo('محمد', 30, 'الرياض');
                            }
                        
                    

المعاملات المسماة

                        
                            // معاملات مسماة اختيارية
                            void createUser({String? name, int? age, String? email, bool isActive = true}) {
                                print('--- معلومات المستخدم ---');
                                print('الاسم: ${name ?? "غير محدد"}');
                                print('العمر: ${age ?? "غير محدد"}');
                                print('الايميل: ${email ?? "غير محدد"}');
                                print('نشط: $isActive');
                            }
        
                            // معاملات مسماة مطلوبة
                            void registerUser({required String username, required String password, String? email}) {
                                print('تم تسجيل المستخدم: $username');
                                if (email != null) {
                                    print('الايميل: $email');
                                }
                            }
        
                            // الاستخدام
                            void main() {
                                createUser();
                                createUser(name: 'أحمد');
                                createUser(name: 'فاطمة', age: 25, email: 'fatima@example.com');
                                
                                registerUser(username: 'ahmed123', password: 'mypass');
                                registerUser(username: 'fatima456', password: 'herpass', email: 'fatima@example.com');
                            }        
                        
                    

الدوال المختصرة (Arrow Functions)

                        
                            // للدوال البسيطة من سطر واحد
                            int square(int x) => x * x;
                            bool isEven(int number) => number % 2 == 0;
                            String formatName(String firstName, String lastName) => '$firstName $lastName';

                            // دوال مع معاملات مسماة
                            double calculateArea({required double width, required double height}) => width * height;

                            // استخدام
                            void main() {
                                print('مربع 5: ${square(5)}'); // 25
                                print('هل 4 زوجي؟ ${isEven(4)}'); // true
                                print('الاسم الكامل: ${formatName("أحمد", "محمد")}');
                                print('المساحة: ${calculateArea(width: 10, height: 5)}');
                            }
                        
                    

الدوال عالية المستوى (Higher-Order Functions)

                        
                            // دالة تأخذ دالة أخرى كمعامل
                            void executeOperation(int a, int b, int Function(int, int) operation) {
                                int result = operation(a, b);
                                print('النتيجة: $result');
                            }
        
                            // دالة ترجع دالة أخرى
                            Function(int, int) getOperation(String operationType) {
                                switch (operationType) {
                                    case 'add':
                                    return (int a, int b) => a + b;
                                    case 'multiply':
                                    return (int a, int b) => a * b;
                                    case 'subtract':
                                    return (int a, int b) => a - b;
                                    default:
                                    return (int a, int b) => 0;
                                }
                            }
        
                            // استخدام مع الدوال المجهولة
                            void main() {
                                // استخدام دالة محددة مسبقاً
                                executeOperation(10, 5, addNumbers);
                                
                                // استخدام دالة مجهولة
                                executeOperation(10, 5, (int x, int y) => x * y);
                                
                                // الحصول على دالة من دالة أخرى
                                var addFunc = getOperation('add');
                                print('10 + 5 = ${addFunc(10, 5)}');
                                
                                // استخدام مع القوائم
                                List numbers = [1, 2, 3, 4, 5];
                                
                                // map - تحويل كل عنصر
                                List doubled = numbers.map((n) => n * 2).toList();
                                print('الأرقام المضاعفة: $doubled');
                                
                                // where - تصفية العناصر
                                List evenNumbers = numbers.where((n) => n % 2 == 0).toList();
                                print('الأرقام الزوجية: $evenNumbers');
                                
                                // forEach - تنفيذ عملية على كل عنصر
                                numbers.forEach((n) => print('الرقم: $n'));
                            }
                        
                    

الدوال العكسية (Recursive Functions)

                        
                            // حساب المضروب
                            int factorial(int n) {
                                if (n <= 1) {
                                    return 1;
                                }
                                return n * factorial(n - 1);
                            }
        
                            // تسلسل فيبوناتشي
                            int fibonacci(int n) {
                                if (n <= 1) {
                                    return n;
                                }
                                return fibonacci(n - 1) + fibonacci(n - 2);
                            }
        
                            // البحث الثنائي
                            int binarySearch(List sortedList, int target, [int start = 0, int? end]) {
                                end ??= sortedList.length - 1;
                                
                                if (start > end) {
                                    return -1; // لم يتم العثور على العنصر
                                }
                                
                                int mid = (start + end) ~/ 2;
                                
                                if (sortedList[mid] == target) {
                                    return mid;
                                } else if (sortedList[mid] > target) {
                                    return binarySearch(sortedList, target, start, mid - 1);
                                } else {
                                    return binarySearch(sortedList, target, mid + 1, end);
                                }
                            }
        
                            void main() {
                                print('مضروب 5: ${factorial(5)}'); // 120
                                print('فيبوناتشي للرقم 7: ${fibonacci(7)}'); // 13
                                
                                List sortedNumbers = [1, 3, 5, 7, 9, 11, 13, 15];
                                int index = binarySearch(sortedNumbers, 7);
                                print('الرقم 7 موجود في الموضع: $index');
                            }        
                        
                    

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

دارت لغة كائنية التوجه بالكامل، وتدعم جميع المفاهيم الأساسية للـ OOP:

الفئات الأساسية (Basic Classes)

                    
                        // تعريف فئة بسيطة
                        class Person {
                            // خصائص الفئة
                            String name;
                            int age;
                            String? email; // اختيارية
            
                            // منشئ (Constructor)
                            Person(this.name, this.age, [this.email]);
            
                            // منشئ مسمى
                            Person.withEmail({required this.name, required this.age, required this.email});
            
                            // منشئ للضيف
                            Person.guest() : name = 'ضيف', age = 0;
            
                            // دوال الفئة (Methods)
                            void introduce() {
                                print('أهلاً، اسمي $name وعمري $age سنة');
                                if (email != null) {
                                    print('يمكنكم التواصل معي على: $email');
                                }
                            }
            
                            bool isAdult() {
                                return age >= 18;
                            }
            
                            void celebrateBirthday() {
                                age++;
                                print('عيد ميلاد سعيد! أصبح عمري $age سنة');
                            }
            
                            // تمثيل نصي للكائن
                            @override
                            String toString() {
                                return 'Person(name: $name, age: $age, email: $email)';
                            }
                        }
        
                        // استخدام الفئة
                        void main() {
                            // إنشاء كائنات مختلفة
                            Person person1 = Person('أحمد', 25);
                            Person person2 = Person.withEmail(name: 'فاطمة', age: 22, email: 'fatima@example.com');
                            Person guest = Person.guest();
            
                            person1.introduce();
                            person2.introduce();
                            guest.introduce();
            
                            print('هل أحمد بالغ؟ ${person1.isAdult()}');
                            person1.celebrateBirthday();
                        }        
                    
                

الوراثة (Inheritance)

                    
                        // الفئة الأساسية
                        class Animal {
                            String name;
                            String species;
                            int age;
            
                            Animal(this.name, this.species, this.age);
            
                            void eat() {
                                print('$name يأكل');
                            }
            
                            void sleep() {
                                print('$name ينام');
                            }
            
                            void makeSound() {
                                print('$name يصدر صوتاً');
                            }
            
                            @override
                            String toString() => '$species اسمه $name';
                        }
        
                        // فئة مشتقة - القط
                        class Cat extends Animal {
                            String furColor;
            
                            Cat(String name, int age, this.furColor) : super(name, 'قط', age);
            
                            // إعادة تعريف دالة من الفئة الأساسية
                            @override
                            void makeSound() {
                                print('$name يموء: مياو مياو');
                            }
            
                            // دالة خاصة بالقطط
                            void purr() {
                                print('$name يخرخر بسعادة');
                            }
            
                            void scratch() {
                                print('$name يحك أظافره');
                            }
                        }
        
                        // فئة مشتقة - الكلب
                        class Dog extends Animal {
                            String breed;
            
                            Dog(String name, int age, this.breed) : super(name, 'كلب', age);
            
                            @override
                            void makeSound() {
                                print('$name ينبح: هاو هاو');
                            }
            
                            void wagTail() {
                                print('$name يهز ذيله');
                            }
            
                            void fetch() {
                                print('$name يجلب الكرة');
                            }
                        }
        
                        void main() {
                            Cat myCat = Cat('قطقوط', 3, 'برتقالي');
                            Dog myDog = Dog('بوبي', 5, 'جولدن ريتريفر');
            
                            print(myCat);
                            myCat.eat();
                            myCat.makeSound();
                            myCat.purr();
            
                            print('\n${myDog}');
                            myDog.eat();
                            myDog.makeSound();
                            myDog.wagTail();
                        }
        
                    
                

التجريد (Abstract Classes) والواجهات (Interfaces)

                        
                            // فئة مجردة
                            abstract class Shape {
                                String name;
            
                                Shape(this.name);
            
                                // دالة مجردة يجب تنفيذها في الفئات المشتقة
                                double calculateArea();
                                double calculatePerimeter();
            
                                // دالة عادية يمكن استخدامها
                                void displayInfo() {
                                    print('الشكل: $name');
                                    print('المساحة: ${calculateArea()}');
                                    print('المحيط: ${calculatePerimeter()}');
                                }
                            }
        
                            // واجهة (Interface)
                            abstract class Drawable {
                                void draw();
                                void erase();
                            }
        
                            // تنفيذ الفئة المجردة والواجهة
                            class Rectangle extends Shape implements Drawable {
                            double width;
                            double height;
        
                            Rectangle(this.width, this.height) : super('مستطيل');
        
                            @override
                            double calculateArea() => width * height;
        
                            @override
                            double calculatePerimeter() => 2 * (width + height);
        
                            @override
                            void draw() {
                                print('رسم مستطيل بعرض $width وارتفاع $height');
                            }
        
                            @override
                            void erase() {
                                print('مسح المستطيل');
                                }
                            }
        
                            class Circle extends Shape implements Drawable {
                                double radius;
            
                                Circle(this.radius) : super('دائرة');
            
                                @override
                                double calculateArea() => 3.14159 * radius * radius;
            
                                @override
                                double calculatePerimeter() => 2 * 3.14159 * radius;
            
                                @override
                                void draw() {
                                    print('رسم دائرة بنصف قطر $radius');
                                }
            
                                @override
                                void erase() {
                                    print('مسح الدائرة');
                                }
                            }
                            void main() {
                                List shapes = [
                                Rectangle(10, 5),
                                Circle(7),
                                ];
            
                                for (Shape shape in shapes) {
                                shape.displayInfo();
                                
                                // التحقق من النوع والتحويل
                                if (shape is Drawable) {
                                    shape.draw();
                                }
                                print('---');
                                }
                            }        
                        
                    

التغليف (Encapsulation) والخصائص الخاصة

                    
                        // التغليف (Encapsulation) والخصائص الخاصة
                        class BankAccount {
                            String _accountNumber; // خاصية خاصة (تبدأ بـ _)
                            String _holderName;
                            double _balance;
                            
                            // Constructor
                            BankAccount(this._accountNumber, this._holderName, this._balance);
                            
                            // Getters للوصول للخصائص الخاصة
                            String get accountNumber => _accountNumber;
                            String get holderName => _holderName;
                            double get balance => _balance;
                            
                            // Setter مع التحقق من صحة البيانات
                            set holderName(String name) {
                                if (name.isNotEmpty) {
                                    _holderName = name;
                                } else {
                                    throw ArgumentError('اسم صاحب الحساب لا يمكن أن يكون فارغاً');
                                }
                            }
                            
                            // دوال للعمليات المصرفية
                            bool withdraw(double amount) {
                                if (amount <= 0) {
                                    print('مبلغ السحب يجب أن يكون أكبر من صفر');
                                    return false;
                                }
                                
                                if (amount > _balance) {
                                    print('الرصيد غير كافي');
                                    return false;
                                }
                                
                                _balance -= amount;
                                print('تم سحب $amount ريال. الرصيد الحالي: $_balance ريال');
                                return true;
                            }
                            
                            void deposit(double amount) {
                                if (amount <= 0) {
                                    print('مبلغ الإيداع يجب أن يكون أكبر من صفر');
                                    return;
                                }
                                
                                _balance += amount;
                                print('تم إيداع $amount ريال. الرصيد الحالي: $_balance ريال');
                            }
                            
                            void displayAccountInfo() {
                                print('--- معلومات الحساب ---');
                                print('رقم الحساب: $_accountNumber');
                                print('اسم صاحب الحساب: $_holderName');
                                print('الرصيد: $_balance ريال');
                            }
                            
                            // دالة إضافية لتحويل الأموال
                            bool transfer(BankAccount targetAccount, double amount) {
                                if (amount <= 0) {
                                    print('مبلغ التحويل يجب أن يكون أكبر من صفر');
                                    return false;
                                }
                                
                                if (amount > _balance) {
                                    print('الرصيد غير كافي للتحويل');
                                    return false;
                                }
                                
                                _balance -= amount;
                                targetAccount._balance += amount;
                                print('تم تحويل $amount ريال إلى حساب ${targetAccount._holderName}');
                                print('رصيدك الحالي: $_balance ريال');
                                return true;
                            }
                        }
        
                        void main() {
                          // إنشاء حساب جديد
                          BankAccount account = BankAccount('123456789', 'أحمد محمد', 5000);
                          
                          // عرض معلومات الحساب
                          account.displayAccountInfo();
                          print('');
                          
                          // إيداع مبلغ
                          account.deposit(1000);
                          print('');
                          
                          // سحب مبلغ
                          account.withdraw(2000);
                          print('');
                          
                          // محاولة سحب مبلغ أكبر من الرصيد
                          account.withdraw(10000);
                          print('');
                          
                          // تغيير اسم صاحب الحساب
                          account.holderName = 'أحمد علي محمد';
                          print('تم تحديث اسم صاحب الحساب');
                          print('');
                          
                          // إنشاء حساب آخر للتحويل
                          BankAccount account2 = BankAccount('987654321', 'فاطمة أحمد', 2000);
                          
                          // تحويل مبلغ بين الحسابات
                          account.transfer(account2, 500);
                          print('');
                          
                          // عرض معلومات الحسابين
                          print('=== الحساب الأول ===');
                          account.displayAccountInfo();
                          print('');
                          
                          print('=== الحساب الثاني ===');
                          account2.displayAccountInfo();
                          
                          // مثال على استخدام الـ Getters
                          print('');
                          print('الوصول للبيانات باستخدام الـ Getters:');
                          print('رقم الحساب الأول: ${account.accountNumber}');
                          print('اسم صاحب الحساب الأول: ${account.holderName}');
                          print('رصيد الحساب الأول: ${account.balance} ريال');
                        }
                    
                

14. التعامل مع الاستثناءات

الاستثناءات (Exceptions) تُستخدم لمعالجة الأخطاء أثناء تنفيذ البرنامج. يمكنك استخدام try-catch للقبض على الأخطاء والتعامل معها.

                        // مثال على try-catch
                        void main() {
                            try {
                                int result = 10 ~/ 0; // محاولة القسمة على صفر
                                print(result);
                            } catch (e) {
                                print('حدث خطأ: 0e');
                            }
                        }
                        
                    
  • try: الكود الذي قد ينتج عنه خطأ.
  • catch: الكود الذي ينفذ عند حدوث خطأ.

15. البرمجة غير المتزامنة (Asynchronous Programming)

تُستخدم البرمجة غير المتزامنة للتعامل مع العمليات التي تستغرق وقتاً طويلاً مثل جلب البيانات من الإنترنت.

                        
                            // مثال على Future و async/await
                            Future fetchData() async {
                                await Future.delayed(Duration(seconds: 2));
                                return 'تم جلب البيانات!';
                            }

                            void main() async {
                                print('جاري جلب البيانات...');
                                String result = await fetchData();
                                print(result);
                            }
                        
                    
  • Future: يمثل عملية ستكتمل في المستقبل.
  • async: تُستخدم مع الدوال التي تحتوي على عمليات غير متزامنة.
  • await: تنتظر انتهاء العملية قبل الانتقال للسطر التالي.