/Java Programming: Let's Master 9/i

Java Programming: Let's Master 9/i

النهاردا معادنا بقا عشان نتكلم عن الوراثة في البرمجة وخصوصا في الجافا

Inheritance and Polymorphism

9.1. Introduction

احنا قولنا قبل كده ان طريقة البرمجة اللي اسمها object-oriented بتدينا إمكانية عمل كلاس جديد من واحد موجود بالفعل وبياخد منه كل خصائصه وده مايسمي بالـ inheritance او التوريث وهو فعلا زي ما المعني بيقول بمعني ان الكلاس القديم بيدي الكلاس الجديد كل خصائصه والكلاس الجديد ممكن يزود خصائص خاصة بيه هو فقط وهكذا .. وكل الكلاسات اللي بنعملها بتبقي وارثة او inherited صفاتها من كلاسات تانية سواء تم ذكر ده علنا او ضمنيا . وعلي فكرة كل الكلاسات اللي عملناها قبل كده كانت وارثة صفاتها من كلاس java.lang.Object .

النهاردا  هنتعرف اكتر علي مفهوم التوريث او inheritance وبالتحديد اكتر هنتعرف علي الكلاسات السوبر او الكلاسات الأم (superclasses) والكلاسات الأبناء (subclasses) لو شبهناها بكده يعني , وهنتعرف علي كلمة جديدة اسمها super وهنتعرف علي كلاس Object وهنتعرف علي مصطلح اسمه polymorphism او تعدد الأشكال بمعني اني من كلاس واحد اقدر اعمل اكتر من كلاس مختلفين وهنتعرف كمان علي مصطلح generic programming و casting objects وهنعرف modifiers غير الـ public وهما الـ  protected والـ final .

9.2. Superclasses and Subclasses :

في الجافا لما نقول ان كلاس c1 معموله extend من كلاس  c2 ده معناه ان c1 اسمه subclass و C2 اسمه superclass . والـ superclass له اسامي تانية زي supertype, parent  class او base class والـ subclass له اسامي تانية زي subtype, child class او derived class .والـ subclass بيورث كل صفات الـ superclass من متغيرات و methods وكمان يقدر يزود صفات خاصة بيه .

لو افترضنا اننا عاوزين نعمل كلاسات بتمثل الأشكال الهندسية زي مثلا الدايرة والمستطيل. لو لاحظنا هنلاقي ان فيه صفات مشتركة بين معظم الأشكال الهندسية زي ملا اللون وسواء الشكل مفرغ ولا مملوء علشان كده هنعمل كلاس فيه كل الصفات العامة وهنسميه GeometricObject وهيحتوي علي متغيرات اللون وحالة الإمتلاء او الفراغ وميثودس الـ get و set الخاصة بيهم ونقدر كمان نزود فيه تاريخ عمل الشكل او dateCreated ونعمل ليه ميثود الـ get ونقدر نزود ميثود toString() علشان نطبع فيها بيانات الشكل المطلوب. وطبعا بما إن الدايرة ممكن تستخدم خواص زي اللون وحالة الإمتلاء او الفراغ وتاريخ العمل تبقي تقدر تستخدم الكلاس بتاعنا ده ونفس الكلام ينطبق علي المستطيل.وعلشان كده منطقي جدا اننا نعمل كلاس نسميه Circle ويكون subclass من كلاس GeometricObject ونعمل كلاس Rectangle ويكون برده subclass من كلاس GeometricObject .وده شكل الكلاسات مع بعضها:

هنلاقي عندنا ان كلاس الدايرة (Circle) بيستخدم كل المتغيرات او (data fields) الموجودة في الـ superclass اللي هو GeometricObject وكمان عملنا فيه متغير خاص بيه وهو نصف القطر (radius) مع ميثودس الـ get & set الخاصة بيه وزودنا كمان ميثودس جديدة خاصة بيه زي getArea(), gtPerimeter() & getDiameter() لحساب المساحة والمحيط والقطر . وبالمثل كلاس المستطيل (Rectangle) بيستخدم كل خواص ومتغيرات وميثودس الكلاس السوبر (GeometricObject) بالإضافة لمتغيرات خاصة بيه زي width & height وميثودس جديدة getArea() & getPerimeter() لحساب المساحة و المحيط.

ملحوظة:: لتسهيل الأمور يراعي استخدام اسماء للكلاسات تكون معبرة عنهم ويراعي ايضا وضعهم في package خاصة بيهم .

      1-  كلاس GeometricObject :

      2 – كلاس Circle :

      3- كلاس Rectangle :

نلاحظ اننا علشان نعرف الـ compiler ان كلاسات الدايرة والمستطيل واخدين صفات كلاس GeometricObject استخدمنا كلمة محفوظة اسمها extends وبعدها اسم الكلاس اللي هناخد صفاته.

دلوقتي هنعمل كلاس نطبع فيه خواص الكلاسين الدايرة والمستطيل:

ملحوظة:: لازم ناخد بالنا ان الكلاس الأبن مش جزء من الكلاس الأب بالعكس ده دايما بيحتوي علي حاجات اكتر من الكلاس الأب.

ملحوظة:: لازم نراعي ان العلاقة بين الكلاس الأبن والكلاس الأب تكون علاقة (is-a) يعني بمعني ان الدايرة عبارة عن شكل والمستطيل برده عبارة عن شكل (Circle is a geometric object) , ولازم نراعي ان العلاقات بين الكلاسات الأبناء والآباء تكون متجانسة يعني مش ينفع نقول ان كلاس الشجرة extends من كلاس الإنسان لأن مفيش اي صفات مشتركة بينهم.

9.3. Using the super Keyword :

إحنا دلوقتي اتفقنا ان الـ subclass بيورث المتغيرات والميثودس الموجودة في الـ superclass طيب ياتري بيورث برده الـ constructor ؟؟

في شابتر 7 استخدمنا كلمة this علشان نعمل object من الكلاس الحالي اللي احنا فيه ونستخدمه في نفس الكلاس . هنا هنستخدم كلمة super علشان نقدر نستخدم اي ميثود او constructor موجودين في الـ superclass .

9.3.1. Calling Superclass Constructors :

علشان نقدر ننادي الـ constructor الخاص بالـ superclass بيبقي بالشكل ده:

نلاحظ هنا ان الجملة دي لما نحب نستخدمها لازم نكتبها في اول سطر بداخل الـ constructor الخاص بالـ subclass ودي الطريقة الوحيدة لإستخدام الـ constructor الخاص بالـ superclass .

ملحوظة:: جزء الـ constructor لا يعتبر من الصفات التي يتم توريثها وعلشان اقدر استخدمه لازم استخدم كلمة super .

دلوقتي بقا هنتكلم عن حاجة مهمة جدا وهتكمل معانا في الجافا طووووول العمر..ا

ال constructor chaining

9.3.2. Constructor Chaining :

ببساطة الكونستركتور شينينج أو سلسلة الكونستركتور معناها ان في حالة ان كلاس ورث كلاس تاني

لما الكونستركتور بتاع الكلاس الابن يجي يتنفذ.. بينادي على كونستركتور الأب وينفذه الأول قبل ما يتنفذ هو.. ولو الأب دا وارث من جد.. في الحالة دي هينادي على الكونستركتور بتاع الجد الأول برضه.. وهيكون التنفيذ بالترتيب دا .. جد أب ابن.. يالا بقا نشوف الكلام دا عملي….

بداخل الـ constructor ممكن ننادي اي constructor اخر ولو لم يتم تحديد اي حاجة الـ compiler بيحط اوتوماتك جملة super() في اول سطر زي كده:

 

بيقول علي كل حال سواء عملناها او لأ مجرد ما بعمل object من الكلاس بينادي كل الـ constructors الخاصة بالـ superclass وبيتم ندائم قبل نداء الـ constructor الخاص بالكلاس نفسه  وده مايسمي بالـ (constructor chaining) زي كده:

هنا هنلاقي ان في كلاس faculty جوه الـ constructor هينادي علي الـ constructor الخاص بكلاس employee وفي كلاس employee هينادي الـ constructor الخاص بكلاس person وبكده الناتج هيكون كده :

ملحوظة:: لو هنعمل الكلاس من الأول بحيث انه بيـ extend او بيورث صفات كلاس تاني يبقي في الحالة دي من الأحسن اننا نعمل له constructor لتفادي اي اخطاء زي كده :

في الحالة دي لما الـ compiler بيجي يتاعمل مع البرنامج هيلاقي ان كلاس apple مش فيه constructor فيقوم عامل ليه واحد ضمنيا وزي ماقولنا ينادي جواه اوتوماتك الـ constructor الخاص بالكلاس الأب ولكن طبعا كل الحاجات دي بتنادي الـ non-arg constructors يعني الـ constructors اللي مش بنبعت ليهم اي متغيرات طبعا هيجيي يشوف فين الـ non-arg constructor الخاص بالكلاس الأب مش هيلاقي فهيطلع خطأ .

9.3.3. Calling Superclass Methods :

طيب احنا قولنا ان كلمة super بنستخدمها لما بنيجيي ننادي علي الـ constructor الخاص بالكلاس الأب وكمان بنستخدمها علشان ننادي اي ميثود في الكلاس الأب زي كده:

ملحوظة :: لو فرضنا ان عندنا كلاس a واخد بيـ extend من كلاس b وكلاس b بيـ extend من كلاس c وميثود p() في كلاس c ياتري ممكن اننا نقول مثلا super.super.p(); جوه كلاس a ؟؟ الإجابة هي لأ مش ممكن الطريقة دي غلط تماما في الجافا.

وهنشوف الموضوع دا بالتوضيح لما نتكلم عن مصطلح الDynamic binding..

وبكده نكون خلصنا النهاردا.. وأنصح الناس كلها بمطالعة المرجع.. وزي كل مرة بقول.. الترجمة مش كفاية.. وأهم من كل دا انك تشتغل بإيدك وتجرب تكود بإيدك وتشتغل ولو حاجة وقفت أو أي استفسار.. انا موجود 🙂

it’s totally free to share

Thanks a lot CATReloaded

thanks a lot CATaZine

om4rezz