إعـــــــلان

تقليص
لا يوجد إعلان حتى الآن.

شرح الأكشن سكربت 3 الجزء الثاني البرمجة الكائنية (oop)

تقليص
هذا الموضوع مغلق.
X
X
 
  • تصفية - فلترة
  • الوقت
  • عرض
إلغاء تحديد الكل
مشاركات جديدة

  • شرح الأكشن سكربت 3 الجزء الثاني البرمجة الكائنية (oop)

    بسم الله الرحمن الرحيم

    الحمدلله والصلاة والسلام على رسول الله وعلى آله وصحبه أجمعين

    السلام عليكم ورحمة الله وبركاته

    الجزء الثاني: البرمجة الكائنية (OOP)

    مرحبا بكم في هذا الجزء الجديد من دروس دورة تعلم الاكشن سكربت 3
    تعلمنا في الجزء الاول أساسيات البرمجة في الاكشن سكربت 3 حيث رأينا كيف نقوم بانشاء متغيرات بمختلف انواعها
    الدوال الشرطية و الحلقات التكرارية و أيضا الجداول و الدوال

    لمتابعة الجزء الأول اضغظ هنا

    في هذا الجزء ان شاء الله سوف نتكلم عن البرمجة الكائنية

    OOP: تعني Oriented Object Programming
    بالفرنسية Programmation Orienté Objet



    _______________________

    البرمجة الكائنية يمكن اعتبارها كطريقة جديدة للتفكير و انشاء برنامج
    الكثير يعتبرها كنموذج للبرمجة .

    هذه الطريقة الجديدة في التفكير لا تقتصر فقط على الاكشن سكربت 3
    بل نجدها في الكثير من لغات برمجة أخرى.

    سنتحدث قليلا عن هذا المصطلح الجديد ثم نبدأ مغامرتنا في البرمجة الكائنية مع اعطاء الكثير من الامثلة و التمارين

    ______________

    المقدمة:

    سنة 1967 ظهرت أول لغة برمجية من هذا النوع تحت اسم simula-67
    simula هي اختصار ل simulation أي المحاكاة
    و هذا يعني محاكاة أي موقف للبرمجة في ذلك الوقت مثل برامج التسيير و المحاسبة ..الخ


    و هنا ظهرمصطلح الكائنات, الكلاس , الاحداث و ايضا جامع القمامة (garbage collector)
    أما مصطلح Oriented Object فلقد أطلقه ألان كاي (Alan kay) مهندس عند Xerox
    الذي قام يتوسيع ما استعمل في simula-67 و قام بتطوير لغة smalltalk
    و هو يعتبر نقطة الانطلاق الرسمي في برمجة الكائنات.

    أهمية البرمجة الكائنية تكمن في فصل الاكواد او المهام, التنظيم, و اعادة استعمال الاكواد.
    بامكاننا القول أن لكل نوع من الكائنات مهمات معينة يقوم بتنفيذها.

    ____________________________________

    مفاهيم:

    الكلاسات Classes:

    سبق و تكلمنا عن المتغيرات و انواعها في الدرس الثاني من الجزء الأول
    و قلنا هناك متغيرات بسيطة و معقدة
    سنجد نفسنا دائما نستعمل نفس الانواع
    String, int, Number, Array..الخ


    لكن ماذا لو أردنا صنع متغيرات خاصة بنا؟ تملك خصائص و وظائف معينة
    في الحقيقة المتغيرات المعقدة هي الكلاسات
    و هي مزيج من المتغيرات و التي تدعى attributes
    و الدوال التي تدعى methods


    الكلاس هي العجينة الاساسية التي بها نقوم بانشاء الكائنات
    بعد صنع الكلاس يمكننا انشاء عدد غير محدوج من الكائنات


    2.الكائن (Object):

    في عالمنا هذا يمكننا أن نمثل كل شئ على شكل كائن
    النباتات و الحيوانات, السيارات .. و حتى الارض


    في البرمجة يمكن رؤية الكائن كوحدة في حالة ما و يمكننا القيام بعدة مهمات
    مثلا التلفاز يمكننا تمثليه على شكل كائن, لديه حجم, لون , و عدة وظائف كالتشغيل و ايقاف التشغيل.


    بعد صنع الكلاسنقوم بانشاء متغيرات (تدعى كائنات) يكون نوعها نفس اسم الكلاس
    و هنا نتكلم عن instantiation
    مثلا لدينا كلاس اسمها car, ننشئ متغير اسمه myCar و نوعه car

    كود:
     var myCar : Car;




    و نقول أن هذا الكائن هو نموذج (instance) للكلاس
    و لانشاء نموذج نستعمل الكلمة new ( سنراها في الدرس القادم ان شاء الله)


    تذكير: في درس الجداول كنا ننشئها بهذه الطريقة:

    كود:
     var myArray1 :Array=new Array(); 
     var myArray2 :Array=new Array();
    - نقول أن الكائنين myArray1 و myArray2 نموذجين (instance) للكلاس Array
    -كما نرى فيمكننا صنع الكثير من النماذج بواسطة الكلاس Array (العجينة)


  • #2
    تعلم as3 - جزء2 [ oop ] - الدرس 1.2 [الكلاسات و الكائنات]

    السلام عليكم و رحمة الله

    مرحبا بكم في درس جديد من دورة تعلم الاكشن سكربت 3

    تعلم AS3 - جزء2 [ OOP ] - الدرس 1.2 [الكلاسات و الكائنات]

    في الدرس السابق تحدثنا عن الكلاسات و الكائنات لكن ليس بصفة نظرية

    قلنا انه بامكاننا صنع نوع جديد من المتغيرات وهذا عن طريق انشاء الكلاسات

    و قلنا -انها كالعجيبنة التي تمكننا من صنع الكثير من الكائنات من نفس النوع
    في هذا الدرس سنقوم بتطبيق تلك المفاهيم على الاكشن سكربت 3
    خطوة بـ خطوة
    ______________________________

    كيفية صنع كلاس في الاكشن سكربت3 (Syntax) :

    كود:
    package  //class directory
    {
           public class  name
          {
            //attributes
            //methodes
          }
    }
    ___________________________

    Package
    معمولة لتسهل علينا البرمجة حيث يتم وضع مجموعة كلاسات من نفس الموضوع
    داخل نفس المجلد
    و هذا يجعل مشروعنا اكثر تنظيما و أناقة فمثلا لدينا الكثير من الكلاسات
    و لدينا كلاسات تخص لاعبنا
    نريد انشاء كلاس جديدة اسمها character
    نقوم بانشاء مجلد اسمه player

    ثم نقوم بانشاء الكلاس character داخل مجلد player ليصبح الكود هكذا

    كود:
    package player
    {
         public class character
        {
           //attributes & methods
        }
    }
    ______________________________


    تطبيق

    سنقوم بانشاء أول كلاس لنا
    في الاكشن سكربت 3 الكلاسات يتم انشاءها في ملفات من نوع.as
    اتبع الخطوات التالية:

    1.قم بانشاء مشروع جديد من نوع ActionScript3



    2.قم بحفظ المشروع في مجلد
    3.قم بانشاء كلاس جديد
    File -> new.. -> ActionScript 3.0 Class
    و اعطيها اسمplayer
    4.قم بحفظها داخل نفس مجلد المشروع

    سنلاحظ انه تشكل لنا هذا الكود

    كود:
    package
    }
     public class player      
    }     
              public  function player()    
             {      
                //constructor code         
              } 
        }
    }
    الان عد الى المشروع و اضغط على اطار لكتابة أكواد الاكشن سكربت 3 من TIMELINE

    و اكتب ما يلي
    كود:
    var  p1: player = new player();
    trace(p1  is  player );
    نقوم بتشغيل البرنامج عن طريق
    Ctrl + enter
    او
    Control -> Test Scene
    سيكتب لنا true


    يعني ان p1 من نوع player
    كما نرى قمنا بنشاء نوع جديد من الكائنات
    نقول أن p1 هوinstance للكلاسplayer

    لايمكن انشاء كائن او متغير له اسم كلاس

    يعني ممنوع كتابة

    كود:
    var player: player = new player();
    ___________________________

    ماذا حدث بالظبط؟؟

    سندرس هذا السطر

    كود:
     var p1: player =new player();
    كود:
    var p1: player;
    فلنفرض انه لا وجود لnew player()
    قمنا بانشاء كائن من نوع playerدون اعطاء قيمة
    لحد الان هذا الكائنا قيمتهnull
    (القيمة الافتراضية كما رأينا في الدرس الثاني من الجزء الأول )

    كود:
    = new player();
    هنا قمنا بانشاء الكائن

    المترجم يدخل الى الكلاس player
    و يقوم بتنفيذ الدالة player اوتوماتيكيا
    هذه الدالة لها نفس اسم الكلاس و هي اجبارية حتى لو كانت فارغة
    تدعى ب constructor

    قبل قليل عندما انشأنا الكلاس
    كانت هناك دالة لها نفس اسم الكلاس و مكتوب داخلها
    constructor code
    و هي اول دالة تنفذ عند انشاء كائن جديد


    لكي نتأكد من هذا نقوم بالدخول الى الكلاسplayer مرة اخرى
    و نكتب هذا الكود داخلconstructor
    كود:
    trace(‘constructor executed!‘);
    لتصبح الكلاس هكذا

    كود:
      
    package
    {  
        public class player()                              
        {
             public function player() 
            { 
               trace(‘constructor exectued!’);
            } 
       } 
    {
    الان نعيد تشغيل البرنامج بctrl + enter

    نرى أنه يكتب لنا
    Constructor executed!

    و هذا يدل ان ال method
    ()player قد تم استدعاءها اوتوماتيكيا

    ___________________________

    في الدرس القادم سنكمل هذه الكلاس و سنضع فيها
    بعض المتغيرات و الدوال

    تعليق


    • #3
      تعلم as3 - جزء2 [ oop ] - الدرس 2.2 [الكلاسات و الكائنات]

      السلام عليكم و رحمة الله

      مرحبا بكم في درس جديد من دورة تعلم الاكشن سكربت 3

      تعلم AS3 - جزء2 [ OOP ] - الدرس 2.2 [الكلاسات و الكائنات]

      في الدرس السابق قمنا بانشاء أول كلاس لنا اسمها player

      في هذا الدرس سنقوم بتطويرها و سنشرح طريقة استعمالها و كيفية تغيير قيم attributes الخاصة بها واستدعاء الـ methods التي تملكها



      سنقوم بصنع لعبة بسيطة جدا وهي انشاء لاعبين
      حيث أن كل لاعب لديه اسم و نقاط خبرة و حياة
      و كل لاعب بامكانه مهاجمة لاعب اخر و في كل هجمة تتضاعف نقاط خبرته الى الضعف اذا لم تكن معدومة و الا سيتحصل على نقطة واحدة
      و كل لاعب يتلقى هجمة من الاعب الاخر و تنقص قيمة حياته نفس قيمة الخبرة التي يملكها الاعب المتعدي
      اذا وصلت نقاط الحياة الى 0 او اقل يموت الاعب
      مثلا:

      الاعب 1 يملك 0 نقاط خبرة
      الاعب 2 يملك 0 نقاط خبرة
      كلاهما يملكان حياة قيمتها 100
      سيناريو :
      الاعب 1 يهاجم الاعب 2
      اذن نقاط خبرة الاعب واحد ستصبح نقطة واحدة لانها حاليا معدومة
      الاعب 2 يتلقي الضربة و تنقص حياته نفس قيمة خبرة الاعب1 يعني ستصبح 99
      -الاعب 1 يهاجم الاعب 2 مجددا
      اذن نقاط خبرة الاعب1 ستتضاعف لانها ليست معدومة و ستصبح 1*2 يعني 2
      الاعب2 يتلقى الهجمة و تنقص قيمته ب 2 و تصبح 97
      ...
      و هكذا الى ان تصل قيمة حياة واحد منهما الى 0 أو أقل


      __________________________________

      حسنا ما هي ال attributes و methods الازمة التي يمكن استنتاجها من الفقرة السابقة؟
      كل لاعب لديه اسم اذن هناك attribute من نوع String
      كل لاعب لديه نقاط خبرة و حياة اذن هناك attribute للخبرة فليكن xp و الاخر للحياة life
      كلاهما من نوع int
      كل لاعب يهاجم و يتلقى ضربات اذن هناك method للمهاجمة ()attack و الاخر لتلقي الضربات ()receive
      و كل لاعب يموت ()die

      _______________________________

      الكود
      نفتح نفس الكلاس السابق و نقوم بتعديله

      كود:
      package
      {
            public  class player
           {
                //attributes
               var playerName:String;
               var xp:int;
               var life:int;
              //methods
      
               public function player(playerName :String= "player_anonyme")
               {
                        //constructor
                       /* 
      هذه أول method يتم تنفيذها اوتوماتكيا مع انشاء الكائن (()new player)
                          */
                     this.playerName = playerName;
                     xp = 0;
                     life = 100;
               }
              public function attack( p2:player):void
              {
                     if( xp == 0)
                        xp = 1;
                    else
                       xp = xp * 2;
      
                    p2.receive(xp);
               }
             public function receive(xp:int):void
            {
                   life = life - xp;
                  if(life <= 0)
                     die(); 
             }
             public function die():void
            {
                 trace(this.playerName + " is died!");
            }
         }
      }
      ملاحظات مهمة بخصوص ال constructor :

      فيه يتم عمل initialisation لكل المتغيرات و نقصد بها القيمة الابتدائية لكل attributes
      1.
      نلاحظ اننا نملك attribute اسمه playerName
      و لدينا مدخل اسمه playerName أي نفس الاسم
      كيف نفرق بينهما؟
      الحل هو this الذي يعني اننا سنتعمل attribute موجود داخل الكلاس
      و هو اجباري فهذا النوع من المواقف لكي نفرق بين المتغيرين
      هل playerName هو ذلك الخاص بالمدخل ام attribute
      الكلمة this ليست اجبارية في مواقف اخرى يمكن وضعها و يمكن الاستغناء عنها
      لكن من الافضل كتابها
      2.
      نلاحظ ان المدخل اختياري مثلما رأينا في درس الدوال
      و هنا عند انشاء instance لل player يمكننا اعطاء مدخل و سيأخذ playerName نفس قيمته
      و في حالة عدم اعطاء مدخل سيكون اسمه player_anonyme

      الدالة attack نضع فيها الاعب الثاني في المدخل (نوع player)
      لان بعد مهاجته سيكون (الاعب الثاني) باستدعاء الدالة receive لكي تنقص قيمة حياته
      ________________________________

      سنقوم بانشاء زوجين من instance ل player
      حيث يقوم الاعب 1 بمهاجمة الاعب 2
      الاعب 2 يلزمه 7 ضربات لكي يموت
      (الضربة الاولى تنقص له نقطة لتصبح نقاط حياته 99
      الثانية 97
      الثالثة 93
      ..الخ)

      نعود الى timeline لانشاء لاعبين
      كود:
      var p1 : player = new player("player 1 ");
      var p2 : player = new player("player2");
      for(vari:int = 0 ; i<7; i++)
           p1.attack(p2);
      في الاخير سيكتب لنا

      player2 is died
      ____________________________________

      كيفية الدخول الى attributes و methods الخاصة بالكائن من كلاس اخر :

      نقصد بهذا كيف نقوم بتنفيذ method
      أو قراءة أو تغيير قيمة attribute

      كما رأينا في الكود السابق

      كود:
      p1.attack(p2);
      قمنا باستدعاء الدالة attack الخاصة بالكائن p1 و ذلك بفصل اسم الكائن و اسم الدالة بنقطة
      طبعا مع احترام ترتيب و عدد المداخل الخاص ب method مثلما كنا نرى سابقا

      اظن أننا متعودون على هذا فلقد سبق و أن استعملناها في درس الجداول عندما كنا نستدعي الدوال push , pop, shift, splice..
      اذن تلك الدوال تخص الكلاس Array التي تم برمجتها من طرف مطوري الاكشن سكربت!
      ____________________

      نفس الشئ اذا اردنا الدخول الى attributes خاصة بالكائن
      الفرق بين استدعاء attribute و method:
      ال method تمتلك مداخل (و قد لا تملك)
      عموما تنتهي بقوسين

      كود:
      object.method();
      لكن ال attribut لا نضع فيه اقواس
      مثلما كنا نرى في درس الجداول مع المتغير length

      كود:
       myArray.length
      كنا ندخل الى attribute اسمه length و الذي يحتوي على عدد الخانات (طول الجدول)
      _________________________________

      الان سأطرح عليكم هذا الكود و قوموا بتجريبه قبل الدخول الى الدرس القادم
      أطلب منكم تغيير كود timeline لاظهار قيمة life الخاصة بالاعب p1

      يعني
      كود:
       var  p1 : player = new player("player 1");
      trace(p1.life);

      تعليق


      • #4
        تعلم as3 - جزء2 [ oop ] - الدرس 3 [خصائص الدوال و المتغيرات]

        السلام عليكم و رحمة الله

        مرحبا بكم في درس جديد من دورة تعلم الاكشن سكربت3

        تعلم AS3 - جزء2 [ OOP ] - الدرس 3 [خصائص الدوال و المتغيرات]



        في الدرس السابق طلبت منكم انشاء كلاس player
        و كتابة هذا الكود داخل ال timeline
        كود:
        var  p1 : player = new player("player 1");
        trace(p1.life);
        و النتيجة كانت كما تبينه الصورة



        1178: Attempted access of inaccessible property life through a reference with static type player.
        يعني أن الدخول الى attribute اسمه life غير مسموح لنا.

        غير مسموح يعني أننا لا نستطيع قراءة محتواه و لا تغييره من timeline
        ____________________________

        من الذي منعنا من الدخول اليها؟ و لماذا؟
        هل هو مشكل؟ و كيف يتم حله؟


        يجب أن أقول ان لكل متغير و دالة في الأكشن سكربت 3 خصوصيات
        و هناك 5 خصائص و هي:

        internal: يمكن قراءة أو تغيير المحتوى فقط من كلاسات أخرى من نفس ال package.
        public: المحتوى يمكن دخوله من أي كلاس اخر.
        private : يمكن دخوله فقط من الكلاس الخاص به.
        protected: يمكن دخول المحتوى من نفس الكلاس الخاص به و الكلاسات المشتقة منه (سنرى هذا في درس لاحق)
        static: هذه الكلمة تجعل المتغير عام (global) و يتم دخوله بكتابة اسم الكلاس و ليس اسم ال instance
        (سنشرحه في الاسفل)

        و نكتبها قبل كلمة var بهذا الشكل

        كود:
        property var varName:type;
        لكننا في الكود السابق لم نعطي للمتغير أي خاصية !

        في الاكشن سكربت 3, اذا لم نعطي للمتغير أي خاصية من الخواص الخمس التي ذكرناها
        فان المترجم يعتبره internal و هذا ما يعني أن الوصول اليها يكون فقط من كلاسات من نفس ال package.

        و منه نستننج أن الكود المكتوب داخل timeline ليس من نفس الحزمة (package)
        الموجودة فيها كلاس player.
        _____________________

        مهم ! :

        عند تشغيل البرنامج (بالضغط على CTRL +R ) أول الأكواد التي يتم تنفيذها هي الأكواد
        الموجودة داخل ال timeline .

        هناك الكثير من أنواع لغات البرمجة... سأتكلم عن نوعين و هما
        لغات من نوع البرمجة الكائنية (oriented object programming) مثل جافا و الاكشن سكربت ..الخ
        لغات عبارة عن مجموعة دوال نقوم بكتابتها ثم استعمالها مثل لغة C

        كلاهما يملكان دالة أساسية بحيث تكون هي أول دالة تنفذ تلقائيا
        نقول أنها نقطة دخول البرنامج
        أي منها يبدأ البرنامج
        مثلا في C و جافا الدالة لها اسم main

        في الأكشن سكربت 3 الكلاس الرئيسي (نقطة الدخول) هو MainTimeline
        اكوادها مكتوبة داخل ال timeline

        هل نحن مجبرون على كتابة أكواد نقطة الدخول في timeline؟

        الجواب هو لا.. فيمكننا كتابة كلاس اخر من انشائنا بحيث منه يبدأ برنامجنا
        سنشرح الطريقة في جزء اخر, لحد الان سنكتب الاكواد داخل timeline
        ___________________

        عد الى كود الكلاس player
        ثم قم بتغيير المتغير life الى public
        يعني:

        كود:
        public var life:int;
        أعد تشغيل البرنامج تاركا الكود السابق في timeline

        كود:
        var  p1 : player = new player("player 1");
        trace(p1.life);
        و سترى انه يمكننا الان الدخول الى المتغير life لما وضعنا الخاصية public ! وقمنا بقراءة محتواه
        فالان يمكننا قراءة و تغييره كما نريد

        كود:
        var  p1 : player = new player("player 1");
        p1.life = 50;
        trace(p1.life);
        _______________________________

        هل من الأفضل دائما كتابة المتغيرات على شكل public؟
        و هكذا يمكننا قراءتها و تغييرها من أي مكان...
        فما الفائدة من الخصائص الاخرى..

        لحسن الحظ أن الخصائص الاخرى مثل private , protected.. موجودة
        و إلا فبامكاننا ارتكاب أخطاء فاذحة و نصدم بنتائج غير متوقة بالرغم من أن الكود صحيح
        فالخصائص معمولة لحماية المستخدمين عند تغييرهم لقيمة المتغير
        و المستخدمون في هذه الحالة هم مستخدموا الكلاسات -أي المبرمجون- و ليس مستخدموا البرنامج

        و قد تكون الحماية ضدك أنت بالرغم من أنك صاحب الكلاس
        فبعد مرور زمن طويل قد تنسى أو لا تنتبه و تقوم بتغيير قيمة المتغير بطريقة غير صحيحة

        اليكم هذا السيناريو :

        - قام أحمد بانشاء كلاس تدعى PageGen من اجل صنع صفحات كتابية
        هذه الكلاس تحتوي على عدة دوال كاضافة صفحة و حذف صفحة ..الخ
        و مجموعة متغيرات منها متغير (global) لحساب عدد الصفحات. فليكن هذا

        كود:
        public static var NB_PAGES : int;
        في ال constructor نضيف 1 الى عدد الصفحات (فلقد أنشأنا صفحة جديدة)
        - أحمد يقدم الكلاش لأسامة الذي يبرمج معه هذا البرنامج
        أسامة لا يهمه كيف قام احمد بصنع تلك الدوال و أي متغيرات يستعمل
        كل ما يهمة هو أن الدالة addPage مثلا تقوم باضافة صفحة ..الخ
        أسامة يقوم بعرض عدد صفحاته بالدخول مباشرة الى المتغير الخاص بالكلاس NB_PAGES هكذا


        كود:
        trace(PageGen.NB_PAGES);
        أثناء التطوير خطرة فكرة لأحمد و أراد تحديث كلاساته (update)
        حيث يقوم بوضع كل الصفحات داخل جدول و يتخلى عن المتغير NB_PAGES
        لأنه يمكنه التعرف على عدد الصفحات عن طريف حساب طول الجدول

        كود:
        public static var PAGES_ARRAY:Array;
        يستلم أسامة النسخة الجديدة المليئة بالتغييرات إلا أنه سيُصطم بأخطاء أثناء الترجمة
        فالمتغير PageGen.NB_PAGE أصبح غير معروف

        أسامة يحاول اقناع احمد لارجاع النسخة القديمة لكن احمد سعيد بعمله الجديد و يرفض.
        فمن المخطئ؟
        أحمد هو المخطئ لأنه جعل التعامل مع المتغيرات مباشر و هذا شئ غير منصوح به
        في البرمجة فلو قام أحمد بصنع دالة اسمها getNbPage:
        - النسخة الاولى ترجع لنا المتغير NB_PAGES
        أسامة يستعمل getNbPage و لا يعلم كيف تعمل بالداخل
        - النسخة الثانية ترجع لنا طول الجدول
        أسامة يستعمل دائما نفس الدالة و النتيجة دائما صحيحة !
        ____________

        سيناريو 2:

        لدينا كلاس User تحتوي على الكثير من المتغيرات
        منها private var userName:String
        private var pseudo:String
        ...
        userName: اسم المستخدم الحقيقي
        pseudo: اسمه الافتراضي

        يقوم المستخدم بكتابة اسمه على هذا الشكل CHAfik
        طبعا لو نعطي هذه القيمة مباشرة الى المتغير userName سيصبح
        userName يحمل القيمة CHAfik
        و لكنني كمبرمج أريد أن يكون الحرف الاول كبير و بقية الاحرف صغيرة

        اذن الدخول المباشر الى المتغير غير منصوح به هنا أيضا فمن الأفضل
        صنع دالة setUserName مثلا و التي نقوم فيها بتعديل الاسم

        _____________

        - و اذا أردت تغيير متغير private من كلاس اخر؟؟!

        سنستعمل الـ getters و setters وهناك طريقتين :

        getter/setter الطريقة الأولى :

        1.Setter :
        سنعود الى السيناريو الثاني
        يجب انشاء دالة تقوم بفحص المداخل قبل اعطائه للمتغير
        كود:
        public function setUserName(n : String):void
        {
                  this.userName = n.charAt(0).toUpperCase() + s.substr(1).toLowerCase();
        }
        نفرض أن المدخل هو chAfiK
        (n.charAt(0 سبق وأن رأيناها في درس الجداول و السلاسل الحرفية
        و تعني أننا سنذهب الى الحرف الأول
        ()toUpperCase: تحويل الحرف الى حرف كبير

        كود:
        n.charAt(0).toUpperCase
        يعني اننا سنأخذ الحرف الاول و نقوم بتكبيره( لحد الان userName قيمته C)

        + : للـ concatenation يعني اضافة كلمة لكلمة اخرى
        (substr(1: هذه الدالة سنتكلم عنها في درس اخر
        لكن في هذا المثال ستقوم بحذف الحرف الاول فقط
        اذن تعطينا hAfiK
        toLowerCase: تحويل الاحرف الى احرف صغيرة
        hafik

        اذن قمنا باضافة C الى hafik لتصبح Chafik :)

        لكتابة قيمة في المتغير نستدعي الدالة بهذا الشكل:
        كود:
        instanceName.setUserName("chafik");
        (instanceName اسم الكائن)
        _______________

        2. Getter:

        نبقى دائما مع السيناريو الثاني

        في الكود السابق أردنا تغيير قيمة المتغير userName الى chAfiK
        لكننا ادخلناه عن طريق دالة كوسيط لتعديله كما أردنا
        كيف يمكننا أن نقرأ محتواه الان ؟
        لو حاولنا الدخول اليه مباشرة فلن نستطيع لأنه private

        كود:
        trace(p1.userName);
        يلزمنا من اجل هذا كتابة دالة داخل الكلاس و التي تقوم بارجاع قيمة المتغير
        بما ان الدالة موجودة داخل الكلاس اذن بامكانها الدخول الى المتغير private
        سنستغل هذا لنرجع قيمة userName بهذه الدالة بهذا الشكل

        كود:
        public function getUserName() : String
        {
               return (this.userName);
        }
        كما نرى فالدالة public يعني بامكاننا استدعائها من أي كود
        نوعها String يعني ترجع لنا قيمة من نوع سلسلة احرف
        و هكذا نحصل على قيمة userName :)

        لفحص ما يحتويه المتغير userName نعمل الاتي

        كود:
        trace( instanceName.getUserName() );
        ____________________________________

        2.الطريقة الثانية getter/setter :

        في الطريقة السابقة كنا نغير/نقرأ قيم المتغيرات باستدعاء الدوال المخصص
        كود:
        instance.setVar(value);
        instance.getValue();
        لكن هناك طريقة اخرى للكتابة و القراءة كما لو كانت المتغيرات public مثلا
        كود:
        instance.attribute = value;
        trace(instance.attribute);
        كما نرى لاوجود للقوسين ...

        و ذلك باستعمال الكلمة الدلالية set / get :
        1.set
        : الهدف منها هو كتابة قيمة داخل المتغير المراد مثلما رأينا سابقا و يجب ان تحتوي على مدخل واحد على الاقل و الا سيكون هناك خطأ في الترجمة

        كود:
        public function set userName(n:String):
        {
               this._userName = n.charAt(0).toUpperCase() + n.substr(1).toLowerCase();                    
        }
        يجب تغيير اسم المتغير من userName الى userName_ (مثلا) او اي اسم اخر
        لانه يُمنع كتابة دالة لها نفس اسم متغير
        اذن للدخول الى المتغير userName_ نقوم بالتالي

        كود:
        instanceName.userName = value;
        value: القيمة المراد ادخالها
        _________________

        2.get :

        هذه الدالة يجب ان ترجع لنا قيمة و أيضا تكون بدون مداخل
        و الا سيكون هناك خطأ في الترجمة
        و تكتب هكذا
        كود:
        public function get userName():String
        {
                return this._userName;
        }
        للحصول على قيمة ال userName

        كود:
        trace(instanceName.userName);
        ما قمنا بشرحه يسمى ب Encapsulation و يعني اخفاء المتغيرات و هذا جد مهم
        ___________________________________________


        لحد الان تعرفنا على الخصائص internal و public و private

        الخاصية protected
        تعني أن المتغيرات يمكننا الدخول اليها من الكلاس الموجودة فيه (مثلما رأينا مع private)
        و أيضا من الكلاسات المشتقة منها (و سنرى هذا لما ندخل في درس التوريث, inheritance او héritage بالفرنسية)

        static:

        كلمة static تجعلنا ندخل الى المتغير عن طريق اسم الكلاس و ليس ال instance
        و نقصد بهذا انها سيكون متغير عام (global) و لا يخص فقط الكائن و سنشرحه بالتفصيل في هذا الدرس

        سابقا عندما أنشأنا الكائنين p1 و p2 ثم قام الاعب 1 بمهاجمة الاعب 2
        كان هناك تغير اختلاف في قيم كل لاعب
        يعني المتغيرات الخاصة بالكائن p1 كانت لها قيم
        أما الكائن p2 فكانت له هو أيضا قيما اخرى
        مثلا p1.life تساوي 100
        p2.life تساوي 99



        للدخول الى قيمة life الخاصة بالاعب نكتب اسم الاعب . المتغير

        p1.life
        p2.life
        ...

        الان نعود الى الكلاس player
        و نضيف هذا ال attribute في الاعلى امام المتغيرات الاخرى
        اسمه counter و الهدف منه هو حساب عدد الاعبين
        يعني في كل مرة ننشئ لاعبا جديدا نضيف قيمة 1 الى المتغير counter

        كود:
        public static var counter: uint= 0;

        الان نغير ال constructor

        كود:
        public function player(playerName :String= "player_anonyme")
        {
            this.playerName = playerName;
            xp = 0;
            life = 100;
            player.counter++;
        }
        المتغير counter هو static اذن يمنع كتابة this.counter داخل الكلاس فهو لن يخص أي كائن و انما الكلاس
        ثم ندخل الى ال timeline و نكتب
        كود:
        var p1 : player = new player("Player1");
        var p2 : player = new player("Player2");
        trace( player.counter);
        سكتب لنا 2

        كما نلاحظ فان المتغير counter تم استدعاؤه عن طريق اسم الكلاس و ليس الكائن

        بامكاننا أيضا اعطاءها خصوصيات اخرى مثل private static
        (و هو ما ينصح به في هذا المثال فالمتغير counter بما انه public بامكاننا تغييره
        من كلاس اخر مثلا

        كود:
        player.counter = 50;
        بالرغم اننا نملك فقط لاعبين
        اذن من الافضل أن تكون private و في نفس الوقت صنع getter لمعرفة القيمة
        فقط دون وضع setter)

        و لكل مبرمج الحرية و طريقة تفكير خاصة به

        تعليق


        • #5
          تعلم AS3 - جزء2 [ OOP ] - الدرس 4 [التوريث inheritance]

          السلام عليكم و رحمة الله

          مرحبا بكم في درس جديد من دورة تعلم الاكشن سكربت 3

          تعلم AS3 - جزء2 [ OOP ] - الدرس 4 [التوريث inheritance]



          في هذا الدرس سنرى مفهوما جديدا و مهما في البرمجة الكائنية و هو التوريث

          __________________

          كلمة توريث مأخوذة من العالم الحي
          كل عنصر في العالم يأخذ خصائص عنصر اخر
          مثلا الانسان له الكثير من خصائص الثدييات (الانسان يرث من الثدييات)
          الموز له خصائص الفواكه (الموز يرث من الفواكه تلك الخصائص)

          يُستعمل التوريث في العلاقات من نوع "is a" أي "هو.."
          مثلا في لعبة ما لدينا الاعبون العاديون(player) و المشرفون على اللعبة(admin)
          المشرفون 'هم لاعبون' (فهم يملكون نفس الخصائص)

          المشرف يرث كل خصائص الاعب العادي
          الكلاس player تدعى الكلاس الأم أو سوبر كلاس (super class)
          و الكلاس admin تدعى الكلاس البنت (sub-class)


          _______________________

          الوراثة في الأكشن سكربت 3 :

          لكي ترث كلاس نفس خصائص كلاس اخر نستعمل الكلمة الدلالية

          extends

          مثال الكلاس admin ترث من الكلاس player
          كود:
          package
          {
                   public class admin extends player
                  {
                         public function admin()
                       {
                                // constructor code
                       }
                  }
          }
          الان لكي ننشئ instance للكلاس admin نستعمل نفس الطريقة السابقة نذهب الى timeline و نكتب الكود

          كود:
          var myAdmin : admin = new admin();

          اذا جربنا هذا الكود ستظهر لنا رسالة خطأ 1203

          عندما ترث كلاس بنت من كلاس أم
          يجب علينا أن نمرّ على ال constructor الخاص بالأم مع احترام المداخل الخاص به

          لكي ندخل الى constructor الخاص بالأم نستعمل الكلمة super
          _______________________

          التوريث في الأكشن سكربت 3 :

          لكي ترث كلاس نفس خصائص كلاس اخر نستعمل الكلمة الدلالية

          extends

          مثال الكلاس admin ترث من الكلاس player

          كود:
          package
          {
                   public class admin extends player
                  {
                         public function admin()
                       {
                              super(); 
                       }
                  }
          }
          _________________________

          الهدف من التوريث :

          فلنفرض ان في الكلاس player هذه المتغيرات

          كود:
          var playerName:String;
          var xp:int;
          var life:int;
          و هذه الدوال
          كود:
              
          public function attack( p2:player):void
          public function receive(xp:int):void
          public function die():void

          و أردنا انشاء نوع اخر من الاعبين بحيث تكون له نفس خصائص الاعب العادي و لكن اضافة الى هذا
          يمكنه الاشراف عليهم
          مثلا طرد الاعبين الغشاشين
          حذف الاعب ..الخ

          عوضا ان ننشئ كلاس admin نضع بداخلها المتغيرات
          كود:
          var playerName:String;
          var xp:int;
          var life:int;
          و الدوال
          كود:
              public function attack( p2:player):void
          public function receive(xp:int):void
          public function die():void

          يكفي أن نستعمل extends و ستأخذ الكلاس admin كل خصائص الكلاس player

          __________________________________

          مثال اخر

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

          عوضا أن ننشئ الكلاسات الثلاث و نكتب نفس المتغيرات و الدوال في كل كلاس مثلا

          var maxSpeed
          var sound
          ..
          كود:
          .function set MaxSpeed(s:int):void
          function get MaxSpeed():int
          ....

          يكفي انشاء كلاس animal و وضع كل الخصائص
          ثم نستعمل extends لكي ترث باقي الكلاسات منها
          public class lion extends animal
          public class dog extends animal

          ..
          ______________________________

          : super-types / sub-types

          بفضل التوريث الكلاس admin تملك نوعين
          player : يعتبر super-type
          admin: يعتبر sub-type

          لو نكتب الكود التالي
          كود:
          var myAdmin : admin = new admin();
          trace(myAdmin is admin); //true
          trace(myAdmin is player);  //true
          سيظهر لنا true و هذا يعني أن myAdmin هو admin و player

          كلما قمنا بتوسيع ال super type (توسيع يعني هناك كلاسات ترث منه)
          يمكننا تمرير instance من sub-type
          يعني المتغيرات من نوع player يمكنها تخزين كائنات من نوع admin

          مثال
          كود:
          var myAdmin : player = new admin();
          trace(myAdmin is admin); //true
          trace(myAdmin is player);  //true

          كل admin هو player

          المترجم يعلم ان كل الخصائص الموجودة في player هي موجودة أيضا في admin

          العكس غير صحيح

          كود:
          var myAdmin : admin = new player();
          _________________________

          كود:
          ما الفائدة من تمرير متغير sub type الى متغير super type؟
          فلنفرض أننا نملك دالة ترجع لنا أنواع مختلفة من الكائنات

          مثلا
          كود:
          getBestPlayer():player
          هذه الدالة مثلا ترجع لنا أقوى لاعب في اللعبة من نوع player
          لكن قد يكون أقوى لاعب من نوع admin أو نوع اخر
          يمكننا و بدون أي مشكل ارجاع أحسن لاعب مهما كان نوعه player او admin

          كود:
          return (admin_type);
          مثال اخر

          هذه الدالة موجودة داخل الفلاش بحيث سترجع لنا كل انواع الكائنات الجرافيكية (سنراها في الاجزاء القادمة)

          كود:
          public function getChildAt(index:int):DisplayObject
          هناك الكثير من المتغيرات الجرافيكية مثل
          shape MovieClip Sprite SimpleButton

          كل هذه الانواع ترث من الكلاس DisplayObject و لهذا فإن تلك الدالة ترجع لنا مختلف الانواع الجرافيكية

          ______________


          ماذا لو جربنا الكود التالي؟


          نفرض أن في الكلاس admin الدالة التالية

          كود:
          banPlayer(p:player):void
          الهدف منها طرد لاعب لسبب معين

          هل هذا الكود صحيح؟
          كود:
          var playerHacker : player = new player();
          var myAdmin : player = new admin();
          myAdmin.banPlayer(playerHacker);
          اذا جربنا هذا الكود سنقع في رسالة خطأ 1061

          الكلاس player لا تملك الدالة banPlayer بالرغم من أننا مررنا للمتغير myAdmin كائن من نوع admin

          لكي نتمكل من تنفيذ الدالة banPlayer نستعمل نفس الطريقة التي رأيناها في درس المتغيرات (casting)
          هكذا
          type ( myObject)

          ليصبح الكود هكذا

          كود:
          var playerHacker : player = new player();
          var myAdmin : player = new admin();
          
          admin( myAdmin ).banPlayer(playerHacker);

          هذه المفاهيم في البرمجة الكائنية تدعى Polymorphism
          ____________

          تعديل دالة موروثة (override) :

          عندما نرث من كلاس معينة فاننا نرث كل المتغيرات و الدوال الخاص بالكلاس الأم

          لكن أحيانا نحتاج الى تغيير دالة ما كإضافة بعض الاكواد مثلا

          فلنفرض أن في الكلاس player لدينا دالة introduceMySelf
          حيث سنظهر فيها اسم الاعب
          كود:
          public function introduceMySelf():void
          {
                 trace("my name is :"+ this.playerName);
          }
          أنا في الكلاس admin عوضا أن أظهر اسم الاعب أريد أن أظهر رسالة i'm admin
          كود:
          override public function introduceMySelf():void
          {
                trace("I'm admin!");
          }
          ملاحظة مهمة:
          الدالة المعدلة يجب أن تملك نفس اسم و المداخل و نوع ارجاع الدالة الام


          عندما نعدل دالة ما فهذا لن يفقدنا الدالة الموروثة .يمكننا الدخول الى الدالة الام عن طريق الكلمة super
          كود:
          override public function introduceMySelf():void
          {
                super.introduceMySelf();  // الدخول الى الدالة الام و التي تظهر اسم الاعب
                trace("I'm admin!");
          }

          نلتقي في الدرس القادم ان شاء الله

          تعليق


          • #6
            تعلم as3 - جزء2 [ oop ] - الدرس 5 [كلاسات جاهزة و مهمة]

            السلام عليكم و رحمة الله

            مرحبا بكم في درس جديد من دورة تعلم الاكشن سكربت 3

            تعلم AS3 - جزء2 [ OOP ] - الدرس 5 [كلاسات جاهزة و مهمة]

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



            يجب معرفة معنى الكلاس و الخصائص ( كما سبق و رأينا في الدروس السابقة)
            و كيفية انشاء كائن خاص بالكلاس قبل قراءة هذا الدرس
            و أيضا فهم الداول و المداخل

            مثلا:

            كود:
            functionName(param: int):Number
            هذه الدالة اسمها fuctionName تأخذ مدخلا واحدا من نوع int و ترجع لنا قيمة من نوع Number


            كود:
            functionName(param: int = 5 ):Number
            مثل الدالة السابقة لكن الفرق هنا أن المدخل ليس اجباري ففي حالة عدم وضعه سيأخذ القيمة 5

            يعني عندما نستدعي هذه الدالة بهذه الطريقة

            كود:
            functionName();
            كأننا استدعيناها هكذا
            كود:
            functionName(5);
            _____________________________

            String

            هذه الكلاس سبق و ان رأيناها في الجزء الأول و هي الخاصة بالسلاسل الحرفية

            أهم الدوال (methods) الخاصة بالكلاس String:

            charAt(index:Number = 0):String : ترجع لنا الحرف الموجود في الموقع المحدد بالمدخل index

            charCodeAt(index:Number = 0):Number : ترجع لنا رقم الحرف الموجود في الاندكس المعطى

            الذاكرة المركزية تخزن كل شئ على شكل أعداد فلا يمكن كتابة 'a' داخل الذاكرة
            و انما يتم تخزينه بالعدد 97 و هذا الكود يدعى كود ASCII
            لما نريد اظهار الحرف a يقوم الكمبيوتر بتحويله من 97 الى الحرف a
            كل حرف له كود خاص به اضعط هنا لرؤية بعض الاحرف و الاكواد الخاصة بها

            concat(... args):String : هذه الدالة تأخذ عدة سلاسل حرفية كمدخل -او سلسلة واحدة- و ترجعها لنا على شكل سلسلة واحدة يعني انها تفوم بالصاقها, مثلا

            كود:
            var a:String = "a";
            var b:String = "b";
            var c:String = "c";
            var abc:String = a.concat(b,c);
            trace(abc);  // abc
            trace(a);  //a

            كما نرى فالمتغير abc قيمته "abc" فلقد تم الصاق قيمة المتغيرات aو b و c في سلسلة واحدة
            دون تغيير قيمتهم الأصلية (يعني المتغير a قيمته تبقى دائما "a" .. )

            toLowerCase():String
            : ترجع لنا الاحرف الصغيرة
            toUpperCase():String : ترجع لنا الاحرف الكبيرة

            __________________

            أهم attribute
            length : int : يحتوي على طول السلسلة الحرفية (عدد الاحرف)


            لمزيد من المعلومات حول الكلاس String اضغط هنا
            ______________________________

            سأذكر بعض الكلاسات الاخرى المهمة مع وضع رابط مباشر للموقع adobe التي يحتوي على الشرح


            Array
            Math
            DisplayObject
            MovieClip(سنراه في الجزء القادم)
            Object
            Bitmap (سنخصص لها جزءا كاملا)
            Timer
            الموقع الرسمي

            تعليق


            • #7
              الحمدلله والصلاة والسلام على رسول الله وعلى آله وصحبه أجمعين
              بارك الله فيكم أستاذ أبو همام ونفع بكم

              تعليق


              • #8
                بارك الله فيك أخينا أبو همام

                تعليق


                • #9
                  بارك الله فيك اخي أبو همام على هذا الجهد الرائع

                  :teslam:

                  تعليق


                  • #10
                    شـكــ وبارك الله فيك ـــرا لك ... لك مني أجمل تحية .

                    تعليق


                    • #11

                      تعليق

                      مواضيع تهمك

                      تقليص

                      المنتدى: القسم العام نشرت بواسطة: ماريا عبد الله الوقت: 06-08-2025 الساعة 11:33 PM
                      المنتدى: القسم العام نشرت بواسطة: ماريا عبد الله الوقت: 06-04-2025 الساعة 05:29 PM
                      المنتدى: القسم العام نشرت بواسطة: ماريا عبد الله الوقت: 05-31-2025 الساعة 10:07 PM
                      المنتدى: القسم العام نشرت بواسطة: ماريا عبد الله الوقت: 05-30-2025 الساعة 11:48 PM
                      المنتدى: التصنيع والانتاج نشرت بواسطة: HaMooooDi الوقت: 05-30-2025 الساعة 09:36 AM
                      يعمل...
                      X