دوال الـ Getters والـ Setters
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 21 من 110.
توفر دوال الجلب (Getters) والتعيين (Setters) طريقة للوصول إلى حقول الفئة (class fields) وتعديلها من خلال طرق خاصة تبدو وكأنها خصائص عادية. فبدلاً من كشف الحقول مباشرة، يمكنك التحكم في كيفية قراءة القيم وكتابتها.
يتم تعريف الـ getter باستخدام الكلمة المفتاحية get وتُرجع قيمة محسوبة أو مخزنة:
class Rectangle {
double width;
double height;
Rectangle(this.width, this.height);
double get area => width * height;
double get perimeter => 2 * (width + height);
}
Rectangle rect = Rectangle(5, 3);
print(rect.area); // 15.0
print(rect.perimeter); // 16.0لاحظ أن area و perimeter يتم الوصول إليهما كحقول، ولكن يتم حسابهما في كل مرة. لا حاجة للأقواس.
تستخدم دالة التعيين setter الكلمة المفتاحية set وتسمح لك بالتحكم في كيفية تعيين القيمة:
class Temperature {
double _celsius;
Temperature(this._celsius);
double get celsius => _celsius;
set celsius(double value) {
if (value >= -273.15) {
_celsius = value;
}
}
double get fahrenheit => _celsius * 9 / 5 + 32;
set fahrenheit(double value) {
celsius = (value - 32) * 5 / 9;
}
}
Temperature temp = Temperature(25);
print(temp.fahrenheit); // 77.0
temp.fahrenheit = 100;
print(temp.celsius); // 37.78تقوم دالة التعيين (setter) بالتحقق من صحة المدخلات قبل تخزينها، ويمكنها حتى التحويل بين الوحدات. يمنحك هذا تحكماً في بياناتك مع الحفاظ على صيغة برمجية نظيفة تشبه الخصائص لمستخدمي الفئة (class) الخاصة بك.
التحدي
سهللنقم ببناء متتبع نقاط للعبة يستخدم الـ getters والـ setters لإدارة إحصائيات اللاعب مع التحقق من الصحة والقيم المحسوبة.
ستقوم بتنظيم الكود الخاص بك في ملفين:
player.dart: قم بتعريف فئةPlayerالتي تتبع أداء اللاعب في اللعبة. يجب أن تحتوي الفئة الخاصة بك على:- حقل
String nameلاسم اللاعب - حقل
int _scoreخاص يبدأ بـ0 - حقل
int _livesخاص يبدأ بـ3 - منشئ (constructor) يأخذ اسم اللاعب
- getter باسم
scoreيعيد النتيجة الحالية - setter باسم
scoreيقبل فقط القيم التي تساوي0أو أكبر (تجاهل القيم السالبة) - getter باسم
livesيعيد عدد الأرواح الحالية - setter باسم
livesيقبل فقط القيم بين0و5شاملة (تجاهل القيم خارج هذا النطاق) - getter باسم
levelيحسب مستوى اللاعب بناءً على النتيجة: النتيجة مقسومة على100(قسمة أعداد صحيحة)، زائد1 - getter باسم
isAliveيعيدtrueإذا كان عدد الأرواح أكبر من0 - طريقة
displayStatus()تطبع حالة اللاعب الحالية
- حقل
main.dart: استورد فئة اللاعب الخاصة بك واستعرض الـ getters والـ setters:- أنشئ لاعباً باسم
'Alex' - قم بتعيين النتيجة إلى
250واستدعِdisplayStatus() - حاول تعيين النتيجة إلى
-50(يجب تجاهلها) واستدعِdisplayStatus() - قم بتعيين الأرواح إلى
1واستدعِdisplayStatus() - حاول تعيين الأرواح إلى
10(يجب تجاهلها) واستدعِdisplayStatus()
- أنشئ لاعباً باسم
يجب أن تطبع الطريقة displayStatus() بهذا التنسيق الدقيق:
[name] | Score: [score] | Level: [level] | Lives: [lives] | Alive: [isAlive]المخرجات المتوقعة:
Alex | Score: 250 | Level: 3 | Lives: 3 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 3 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 1 | Alive: true
Alex | Score: 250 | Level: 3 | Lives: 1 | Alive: trueورقة مرجعية
توفر دوال الجلب (Getters) والتعيين (Setters) وصولاً متحكماً فيه إلى حقول الفئة (class fields) من خلال طرق خاصة تبدو مثل الخصائص العادية.
Getter (دالة الجلب) - تُعرّف باستخدام الكلمة المفتاحية get، وتُرجع قيمة محسوبة أو مخزنة:
class Rectangle {
double width;
double height;
Rectangle(this.width, this.height);
double get area => width * height;
double get perimeter => 2 * (width + height);
}
Rectangle rect = Rectangle(5, 3);
print(rect.area); // 15.0 - يتم الوصول إليها كحقل، بدون أقواس
print(rect.perimeter); // 16.0Setter (دالة التعيين) - تستخدم الكلمة المفتاحية set، وتتحكم في كيفية تعيين القيم:
class Temperature {
double _celsius;
Temperature(this._celsius);
double get celsius => _celsius;
set celsius(double value) {
if (value >= -273.15) {
_celsius = value;
}
}
double get fahrenheit => _celsius * 9 / 5 + 32;
set fahrenheit(double value) {
celsius = (value - 32) * 5 / 9;
}
}
Temperature temp = Temperature(25);
print(temp.fahrenheit); // 77.0
temp.fahrenheit = 100;
print(temp.celsius); // 37.78يمكن لدوال التعيين التحقق من صحة المدخلات والتحويل بين الوحدات مع الحفاظ على بناء جملة نظيف يشبه الخصائص.
جرّب بنفسك
import 'player.dart';
void main() {
// TODO: أنشئ لاعباً باسم 'Alex'
// TODO: اضبط الـ score على 250 واستدعِ displayStatus()
// TODO: حاول ضبط الـ score على -50 (يجب تجاهله) واستدعِ displayStatus()
// TODO: اضبط lives على 1 واستدعِ displayStatus()
// TODO: حاول ضبط lives على 10 (يجب تجاهله) واستدعِ displayStatus()
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع