البرمجة الكائنية
| English | العربية |
|---|---|
| object/ˈɒbdʒekt/ | الجسم |
| encapsulation/ɪnˌkæpsjʊˈleɪʃn/ | التغليف |
| class/klæs/ | كلاس |
| instance/ˈɪnstəns/ | مثال |
| constructor/kənˈstrʌktə/ | الدالة الإنشائية |
| inheritance/ɪnˈherɪtəns/ | الإرث |
| subclass/ˈsʌbklæs/ | فئة فرعية |
| superclass/ˈsuːpəklæs/ | الكلاس الأب |
| polymorphism/ˈpɒlɪmɔːfɪzəm/ | تعدد الأشكال |
| abstraction/əbˈstrækʃn/ | التجريد |
| containment/kənˈteɪnmənt/ | التضمين |
| aggregation/ˌæɡrɪˈɡeɪʃn/ | التجميع |
تغيير في مكان واحد كان يعني سابقًا تغييرًا في خمسين
- يخزن برنامج ما رصيد العميل كرقم عام. عشرين وحدة فرعية تقرأه وخمسة عشر تكتبه. الآن يجب ألا ينزل الرصيد أبدًا تحت الصفر.
- بدون كائنات، يجب إضافة هذه القاعدة في fifteen (خمسة عشر) مكانًا، وفي اليوم الذي يضيف فيه شخص ما كاتبًا سادس عشرًا، يتم كسر القواعد مجددًا.
- بالنسبة للكائنات، الرصيد خاص والطريقة الوحيدة لتغييره هي دالة تطبق القاعدة. هناك مكان واحد لإضافتها ولا يوجد مفر من ذلك.
- هذا هو التغليف، وهو السبب في وجود البرمجة كائنية التوجه. هذه الدرس يغطي الكائنات، الفئات، والأعمدة الأربعة.
الكائنات والفئات
- الكائن يجمع بين الخصائص، وهي بياناته، والدوال، وهي العمليات التي تعمل على تلك البيانات. إنه وحدة للحالة والسلوك معاً.
- الفئة هي المخطط: فهي تحدد ما هي الخصائص والدوال التي سيكون عليها كل كائن من هذا النوع. الكائن هو مثال لفئة، بقيم خاصة به.
- فئة واحدة
Taxi، وكل سيارة أجرة فعلية هي كائن له تسجيل وطاقة خاصة به.

الخصائص في الأعلى، والدوال في الأسفل، وموضحة visibility (الرؤية)
معمل مفاهيم البرمجة
صل الأمثلة بالفكرة البرمجية التي تمثلها.
الكائن يجمع:
يكبس الكائن بياناته (الخصائص) مع العمليات (الطرق) التي تؤثر عليه.
ما هي العلاقة بين الفئة والكائن؟
فئة Taxi واحدة تحدد الخصائص والطرق؛ كل سيارة أجرة فعلية هي كائن بسعتها وتسجيلها الخاص.
الدوال المبدئة، والمُحْصِلة والمُضَبِّط
- الدالة المبدئة هي دالة خاصة تُنفَّذ عند إنشاء كائن، لضبط خصائصه على قيم ابتدائية صالحة.
- بما أن الخصائص خاصة، توفر الفئة دوال مُحصِلة لقراءة قيمة ودوال مضبطة لتغييرها. الدالة المضبطة هي المكان الذي تُطبق فيه قواعد مثل "لا يكون سالباً أبداً".
- هذا ما يجعل الخاصية الخاصة ذات قيمة: القاعدة تُطبق على كل تغيير، لأنه لا يوجد طريق آخر للوصول إلى البيانات.
CLASS Taxi
PRIVATE Capacity : INTEGER
PUBLIC PROCEDURE NEW(StartCapacity : INTEGER)
Capacity ← StartCapacity
ENDPROCEDURE
PUBLIC FUNCTION GetCapacity() RETURNS INTEGER
RETURN Capacity
ENDFUNCTION
ENDCLASS
البنّاء (Constructor) هو طريقة خاصة:
يُميّز البنّاء خصائص كائن جديد وقت إنشائه.
العمود 1: التغليف
- التغليف يعني أن بيانات الكائن مخفية خلف دواله. الخصائص خاصة؛ ويستخدم الكود الخارجي الدوال العامة.
- فائدتان، والامتحان يطلب كليهما: يمكن للكائن تطبيق قواعده الخاصة على كل تغيير، ويمكن تغيير التمثيل الداخلي بأمان لاحقاً، لأن أي كود خارجي لا يعتمد عليه.
- تخزّن الرصيد بالباوند اليوم وبالسنت غداً: كل مستخدم للفئة ما زال يتصل
GetBalance()ولا شيء خارجي ينكسر.
التغليف يعني:
التغليف يخفي البيانات؛ الكود الخارجي يستخدم الطرق العامة، لذا يمكن تغيير internals بأمان.
ماذا يمنحك التغليف؟ اختر كل الخيارات المطبقة.
التغليف يتعلق بالصيانة والدقة، وليس السرعة. البيانات الخاصة مع الطرق العامة هي ما يجعل كليهما ممكنين.
العمود 2: الوراثة
- الوراثة تسمح بتعريف فئة فرعية بدلالة فئة عليا، بأخذ جميع خصائصها ودوالها ثم إضافة خاصة بها أو استبدالها.
- تمثّل علاقة "هي-نوع": المدير هو موظف، لذا
Managerيرث منEmployeeويضيف إدارة. - الفائدة هي أن الكود المشترك يُكتب مرة واحدة في الفئة العليا، وأي تغيير فيها يصل إلى كل الفروع الفرعية.

الجزء المشترك يعيش في الأعلى؛ الاختلافات تعيش في الأسفل
الوراثة تحاكي علاقة "هي-نوع" (المدير هو موظف)، لذا يرث الفئة الفرعية ويوسع فئتها الأب.
الوراثة هي تخصص "هي-نوع"؛ أما علاقات "تحتوي على" فتُحاكى بالتركيب بدلاً من ذلك.
تحاكي الوراثة علاقة "____ نوع"، مثل أن يكون المدير موظفاً.
السيارة تحتوي على محرك، وهو تركيب وليس وراثة. فهم هذا التمييز بوضوح هو ما تختبره السؤال.
العمودان 3 و4: تعددية الأشكال والتجريد
- تعدد الأشكال يعني أن الكائنات المختلفة تستجيب لـ نفس استدعاء الطريقة بطريقتها الخاصة. كل
Shapeله طريقةArea()؛CircleوRectangleيطبقانها كلٌ بطريقة مختلفة. - قيمتها: يمكن للكود المرور على قائمة من الأشكال باستدعاء
Area()على كل منها، دون معرفة أو اهتمام بنوع كل منها. إضافة فئةTriangleلاحقاً لن تحتاج هذا الحلقة لأي تغيير على الإطلاق. - التجريد يعني إظهار واجهة بسيطة وإخفاء التعقيد خلفها: المُنادي بـ
Area()لا يحتاج لمعرفة أي هندسة.
تعدد الأشكال يسمح بـ:
ينفذ نفس الاستدعاء (مثل Area()) بشكل صحيح لكل نوع — ولا يحتاج المنادي إلى معرفة الفئة الدقيقة.
رتب عواقب تعدد الأشكال، من التعريف إلى الفائدة.
استدعاء واحد، عدة تطبيقات، وكود الاستخدام لا يحتاج أبداً لمعرفة الجديد منها.
مثال محلول: سَمِّ العمود
- فئة
BankAccountتحافظ على خصوصية توازنها وتوفرDeposit()وWithdraw()طرقاً ترفض جعله سالباً. التغليف: البيانات مخفية والقاعدة مفروضة من خلال المسارات الوحيدة للوصول إليها. - فئة
SavingsAccountمُعرَّفة كفئةBankAccountمع إضافة معدل فائدة. الوراثة: علاقة "هي-نوع"، إعادة استخدام كود الفئة العليا. - حلقة استدعي
Print()على كل مستند في قائمة، وكل نوع يطبع نفسه بطريقة مختلفة.* تعددية الأشكال: استدعاء واحد، عدة implementations.** - سَمِّ العمود و ميزة السيناريو التي تُظهره.
طابق كل ركيزة من أعمدة البرمجة كائنية التوجه بمعناها.
التغليف = إخفاء؛ الوراثة = تخصص "هي-نوع"؛ تعدد الأشكال = نفس الواجهة، سلوك متنوع.
مثال محلول: لماذا البرمجة كائنية التوجه لنظام كبير
- قدم فائدتين لاستخدام البرمجة كائنية التوجه لنظام كبير. [4]
- التغليف يعني أنه يمكن تغيير internals (الداخل) لكل فئة دون التأثير على بقية البرنامج، مما يجعل النظام أسهل في الصيانة并能 يعمل فريق على فئات بالتوازي.
- الوراثة تعني أن السلوك المشترك يُكتب مرة واحدة ويُعاد استخدامه، مما يقلل الكود المكرر وتطبيق الإصلاح في كل مكان في آن واحد.
- تعددية الأشكال تعني أنه يمكن إضافة أنواع جديدة دون تغيير الكود الذي يستخدمها. كل إجابة هي ميزة و نتيجتها.
الفريق يحتوي لاعبين؛ هو ليس لاعبًا
- التضمين يعني أن الكائن يحتوي على كائن آخر كصفة واحدة منه. في التركيبة، يمكن للكائن المُحتَوى أن يوجد بشكل مستقل:
Teamيحتوي على إشارات إلىPlayerكائنات يمكن أن تنتقل إلى فريق آخر. - اختر بناءً على العلاقة:
Goalkeeperهو نوع منPlayer، لذا استخدم الوراثة؛Teamيحتوي على لاعبين، لذا استخدم التركيبة. إن وراثة فريق لطريقةKick()الخاصة باللاعب هو خطأ في التصميم، حتى لو كان الفريق يستحق أخذ ركلة الجزاء.
يخزن الفريق إشارات مرجعية لكائنات اللاعب. يبقى اللاعبون عند إزالة الفريق. أي علاقة تناسب؟
يحتوي الفريق على كائنات لاعبين مستقلة. تتطلب الوراثة علاقة "هو-" (is-a).
مثال محلول: تصميم فريق دون نسخ لاعبيه
- معطيات:
Playerله اسم خاص وطريقةGetName(). صممTeamبمجموعة خاصةMembersتحتوي على إشارات إلىPlayerكائنات وطريقةAddPlayer(NewPlayer)تضيف إشارة. - يمكن لـ
Playerأن يوجد قبل الفريق، ويمكن إزالة الفريق بينما يبقى لاعبوته. هذا تركيب. تغيير اسم اللاعب عبر طريقتِه الخاصة مرئي لجميع الكائنات التي تحتفظ بذلك اللاعب؛ ستصبح نسخة النسخ النصية قديمة.
Player object: name = "Sam"
Team object: Members = [reference to Sam's Player object]
Goalkeeper class: inherits the Player attributes and methods
في هذا التصميم، يجب أن يؤدي إزالة الفريق أيضًا إلى تدمير كل لاعب يحتويه.
يوجد اللاعبون بشكل مستقل. إزالة الفريق تزيل إشاراتها المرجعية، وليس بالضرورة كائنات اللاعبين.
طابق كل تصميم بعلاقته.
نموذج الوراثة هو "هو-نوع" (is-a)؛ ونموذج التجميع هو "يمتلك-شيء" (has-a) مع كائنات مستقلة؛ والتغليف يتحكم في الوصول إلى البيانات.
علامات ضائعة
- الفئة هي المخطط، والكائن هو مثال لها. لا تستخدم الكلمتين بالتبادل.
- التغليف هو إخفاء البيانات خلف الدوال، وفوائده هي تطبيق القواعد والتغير الآمن للداخل. "إنه أكثر أماناً" غير محدد جداً.
- الوراثة هي علاقة "هي-نوع". السيارة لديها محرك، وهو تركيب (composition)، وليس وراثة.
- تعددية الأشكال هي نفس الاستدعاء يتصرف بشكل مختلف حسب الفئة، وهو ما يسمح بإضافة فرع فرعي جديد دون تغيير الكود الموجود.
لقد فهمت الأمر
- كائن يجمع بين خصائص ودوال؛ فئة هي المخطط والكائن هو مثال، مُعد بواسطة دالة مبدئة
- التغليف: بيانات خاصة خلف دوال عامة، حتى يتم تطبيق القواعد على كل تغيير ويمكن تغيير الداخل بأمان
- الوراثة: فئة فرعية تأخذ أعضاء فئة عليا وتضيف أو تستبدلها، نمذجة "هي-نوع" وكتابة الكود المشترك مرة واحدة
- تعددية الأشكال: نفس الاستدعاء مُنفَّذ بشكل مختلف حسب الفئة، حتى لا تحتاج الأنواع الجديدة لتغيير الكود الموجود؛ التجريد: واجهة بسيطة تخفي التعقيد