GagorAcadmey

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

آخر المواضيع

الثلاثاء، 21 أغسطس 2018

محددات الوصول في جافا

الـ Modifiers هم كلمات يمكنك إضافتهم عند تعريف أشياء جديدة ( سواء كلاس, متغير, دالة إلخ.. ) لتحديد طريقة الوصول إليها.
ستحتاجهم في الغالب إن كنت تعمل في برنامج كبير ضمن فريق من المبرمجين.
فإذا كنت تعمل على إنشاء برنامج معين ضمن فريق من المبرمجين, و تريد ضمان عدم إساءة إستخدام الأشياء التي قمت بتعريفها من قبل مبرمج آخر.
الـ Modifiers سيساعدوك في ذلك, فباستخدامهم يمكنك تحديد الأشياء التي يمكن لباقي المبرمجين الوصول إليها و الأشياء التي تريد التأكد من عدم التعديل عليها إلخ..

الـ Modifiers ينقسمون إلى قسمين أساسيين:
  1. Access Modifiers

  2. Non Access Modifiers

  • في المثال التالي قمنا بتعليم الكلمات التي تعتبر من الـ Access Modifiers باللون الأزرق و الكلمات التي تعتبر من الـ Non Access Modifiers باللون الأخضر.
  • public class Student {
    private String firstName;
    private String lastName;
    private String specialization;
    private int id;
    private boolean isWork;
    final String theAvgerageForSuccess = "50%";
    String CollegeName = "MIT";
    public static void printFullName() {
    System.out.println("Name: " +firstName+ " " +lastName);
      }
    }
    

    ملاحظة

    في هذا الدرس سنعطيك معلومات عامة عن الـ Modifiers و في الدروس المقبلة سنستخدمهم في معظم الدروس لذلك عليك التركيز عليهم جيداً.
    كما أننا سنتطرق قليلاً إلى الـ Encapsulation و الـ Inheritance, أي التغليف و الوراثة. لا تقلق إن لم تفهم أي شيء منهم الآن لأنك ستراهم في دروس لاحقة.

    Access Modifiers

    الجدول التالي يحتوي على الكلمات التي تنتمي للـ Access Modifiers.
    Modifier تعريفه
    public الكلاس أو الدالة أو المتغير الذي يتم تعريفه كـ public يمكن الوصول إليه مباشرةً.
    protected الدالة أو المتغير الذي يتم تعريفه كـ protected يمكن الوصول إليه فقط من الكلاسات الموجودة في نفس الـ package أو من الكلاسات التي ترث منه.

    ملاحظة:

    لا يمكنك تعريف كلاس كـ protected.
    private الـ private هو أعلا مستوى من حيث الحماية. المتغيرات و الدوال التي يتم تعريفها كـ private يمكن الوصول لها فقط من داخل الكلاس الذي تم تعريفها فيه.

    ملاحظات

    لا يمكنك تعريف كلاس كـ private.
    لا تقم بتعريف دالة كـ private إذا كان نوعها أيضاً abstract لأنك لن تستطيع أن تفعل لها override.

    ملاحظة

    إذا لم تضع أي كلمة من الـ Access Modifiers عند تعريف كلاس أو دالة أو متغير سيتم وضع Modifier إفتراضي عنك يسمى package private. و هذا يعني أنه يمكن الوصول إليه فقط من الكلاسات الموجودة في نفس الـ package.

    الـ Access Modifiers هم الأشياء الأساسية التي تسمح لك بتطبيق مبدأ الـ Encapsulation الذي يمكنك من إخفاء البيانات الأساسية في الكود التي لا تريد لأحد من المبرمجين الآخرين أن يعرف بتفاصيلهم. ستتعلم مبدأ الـ Encapsulation في الدرس التالي.

    كتابة الكود بشكل مثالي

    بشكل عام, الـ Modifier الإفتراضي لا يستخدم في الغالب. و الـ public يستخدم مع الدوال التي تريد للجميع أن يصل إليها. الـ private هو للمتغيرات التي لا تريد للكائنات و الكلاسات التي ترث من الكلاس أن تصل إليها. الـ protected يستخدم من أجل الكلاسات المرتبطة بالكلاس الذي تعمل عليه ( فعلياً التي ترث منه ) فمن خلاله ستكون البيانات متاحة أمام الكلاسات المرتبطة بالكلاس و لكنها غير متاحة أمام أي كلاس آخر.

    الخطوات التي عليك اتباعها للتحكم بالكود و لحمايته من المبرمجين الآخرين

    1. ضع Modifier ملائم لكل عنصر تقوم بتعريفه, لحماية البيانات قدر المستطاع.

    2. المتغيرات التي تمثل الخصائص يجب أن لا تكون أبداً public. يجب وضعهم private أو protected لتمنع الكلاسات الأخرى من الوصول المباشر إليهم.

    3. يجب تجهيز دوال نوعها public للتعامل مع هذه الخصائص. الدوال التي نوعها public تسمح للمبرمجين ( أو الكلاسات الأخرى ) بالوصول إلى الخصائص. هذه الدوال تسمح لك بإخفاء المتغيرات بالإضافة إلى التحكم بالخصائص كما تريد.

    القواعد التالية تم فرضها بالنسبة للدوال التي يرثها كلاس من كلاس آخر

    1. الدوال التي يتم تعريفها كـ public في الـ Superclass تعتبر public في جميع الـ Subclasses.

    2. الدوال التي يتم تعريفها كـ protected في الـ Superclass تعتبر protected أو public في جميع الـ Subclasses.

    3. الدوال التي يتم تعريفها كـ private, لا يتم توريثها إلى أي كلاس كان, لذلك لا يوجد قواعد من أجلهم.

    مثال

    في الصورة التالية قمنا بإنشاء كلاس إسمه C1 يحتوي على المتغيرات a, b, c, d و وضعنا Access Modifier لكل متغير.
    ثم قمنا بإنشاء الكلاسات C2 و C3 في نفس الـ package و التي إسمها p1.
    ثم قمنا بإنشاء الكلاسات C4 و C5 في package ثانية إسمها p2.
    و في كل كلاس حاولنا الوصول لجميع العناصر الموجودة في الكلاس C1.


    Non Access Modifiers

    جميع الكلمات التي تنتمي إلى الـ Non Access Modifiers هي التالية:
    1. static

    2. final

    3. abstract

    4. synchronized

    5. native

    6. transient

    7. volatile

    8. strictfp


    الجدول التالي يحتوي على الـ Non Access Modifiers الأكثر إستخداماً, مع العلم أننا سنشرح باقي الكلمات في دروس متقدمة.
    Modifier تعريفه
    static يستخدم لتعريف كلاس أو متغير أو دالة مشتركة بين جميع الكائنات من كلاس معين.
    final يستخدم لمنع الوراثة من الكلاس, أو لمنع كتابة محتوى الدالة ( أو تعديلها ) في الكلاس الذي يرثها, أو لجعل قيمة المتغير غير قابلة للتغير بعد تحديدها.
    abstract يستخدم لإنشاء كلاس أو دالة مجردة ( أي دالة لا تحتوي على كود ), الهدف من هذا الـ Modifier تجهيز كلاس معين و جعل الكلاسات التي ترث من هذا الكلاس هي من تقوم بتعريف الأشياء الموجودة بداخله.

    الكلمة static

    ما الحاجة إلى تعريف شيء كـ static؟
  • إن أردت تعريف شيء ثابت لجميع الكائنات, قم بتعريفه كـ static.
  • إن أردت تعريف شيء بداخل كلاس معين, و تريد الوصول إليه مباشرةً من الكلاس بدل إنشاء كائن من الكلاس ثم استدعاء الشيء منه, قم بتعريفه كـ static.

  • المتغيرات التي يتم تعريفها كـ static

    المتغير الذي يتم تعريفه كـ static يعتبر مشترك بين جميع الكائنات من نفس الكلاس. بمعنى أن كل كائن يتم إنشاءه من نفس الكلاس سيملك نفس هذا المتغير.
    فعلياً المتغير هنا سيتم تعريفه مرة واحدة في الذاكرة و جميع الكائنات من نفس الكلاس ستشير إليه بدل أن تملك نسخة خاصة منه. إذاً static تعني نسخة واحدة من المتغير لجميع الكائنات.
    المتغير الذي يتم تعريفه كـ static يسمى أيضاً Class Variable. لا يمكن تعريف الـ Local Variables كـ static.
    يمكن الوصول للمتغير الذي تم تعريفه كـ static بذكر إسم الكلاس الذي تم تعريفه فيه ثم وضع إسمه, أو من أي كائن من الكلاس.

    الدوال التي يتم تعريفها كـ static

    الدالة دائماً يتم تعريفها مرة واحدة في الذاكرة و جميع الكائنات من نفس الكلاس ستشير إليها. لكن الكلمة static تمكنك من الوصول إليها مباشرةً من الكلاس دون الحاجة لخلق كائن و استدعائها من خلاله.
    الدالة التي نوعها static يمكنها الوصول للمتغيرات المعرفة في الكلاس بشرط أن تكون هذه المتغيرات أيضاً static. لكن بشكل عام الدوال التي نوعها static لا تستخدم المتغيرات الموجودة في الكلاس, بل تستخدم المتغيرات التي يتم تعريفها كباراميترات لها أو المتغيرات التي يتم تعريفها بداخلها.
    يمكن الوصول للدالة التي تم تعريفها كـ static بذكر إسم الكلاس الذي تم تعريفها فيه ثم وضع إسمه, أو من أي كائن من الكلاس.

    دوال يتم تعريفها كstatic

    package sample;
    
    class SimpleStatic {
        // This is a static method
        static void myMethod() {
            System.out.println("myMethod");
        }
    
        public static void main(String[] args) {
              /* You can see that we are calling this
               * method without creating any object. 
               */
            myMethod();
        }
    }
    

    سنحصل على النتيجة التالية عند التشغيل.

    myMethod

    متغيرات يتم تعريفها كstatic

    package sample;
    
    class SimpleStaticExample {
        static int var1;
        static String var2;
        //This is a Static Method
        static void disp(){
            System.out.println("Var1 is: "+var1);
            System.out.println("Var2 is: "+var2);
        }
        public static void main(String args[])
        {
            disp();
        }
    }
    

    سنحصل على النتيجة التالية عند التشغيل.

    Var1 is: 0
    Var2 is: null
    

    Static Class

    يمكن جعل كلاس static في حالة واحدة فقط وهي إذا كان كلاس ادخلي Nested Class
    1. الكلاس المتداخل لا يحتاج الي مؤشر الي الكلاس الخارجي

    2. لا يمكن للكلاس الثابت static class الوصول الي أعضاء غير ثابتين Non-Static class من كلاس خارجي

    package sample;
    
    class SimpleStatic {
        private static String item = "Hello World!";
    
        //Static class
        private static class MyNestedClass {
            //non-static method
            private void display() {
    
        /* If you make the item variable of outer class
            * non-static then you will get compilation error
         * because: a nested static class cannot access non-
         * static members of the outer class.
         */
                System.out.println(item);
            }
        }
    
        public static void main(String args[]) {
           /* To create instance of nested class we didn't need the outer
     * class instance but for a regular nested class you would need
     * to create an instance of outer class first
            */
            SimpleStatic.MyNestedClass obj = new SimpleStatic.MyNestedClass();
            obj.display();
        }
    }
    

    سنحصل على النتيجة التالية عند التشغيل.

    Hello World!

    الكلمة final

    ما الحاجة إلى تعريف شيء كـ final؟
    1. في حال أردت إنشاء متغير يمكن تحديد قيمته مرة واحدة فقط.

    2. في حال أردت إنشاء دالة لا يمكن تعريفها من جديد في الكلاس الذي يرثها ( أي لمنع الـ override ).

    3. في حال أردت إنشاء كلاس لا يمكن الوراثة منه

    المتغيرات التي يتم تعريفها كـ final

    المتغير الذي يتم تعريفه كـ final يعني أنه بمجرد إعطاءه قيمة, لا يمكن تغييرها من جديد.
    عند إنشاء متغير نوعه final يجب تحديد قيمته مرة واحدة فقط إما عند تعريفه أو في الكونستركتور.
    class Demo{  
    
       final int MAX_VALUE=99;
       void myMethod(){  
          MAX_VALUE=100;
       }  
       public static void main(String args[]){  
          Demo obj=new  Demo();  
          obj.myMethod();  
       }  
    }
    

    سنحصل على النتيجة التالية عند التشغيل.

    Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
     The final field Demo.MAX_VALUE cannot be assigned
    

    Blank final variable

    يعرف المتغير الذي لم تتم تهيئته وقت الاعلان بblank final variable

    ويجب تهيئته في الدالة البنائية constructor of the class , غير ذلك يسحدث خطأ Error
    class Demo{  
       //Blank final variable 
       final int MAX_VALUE;
      
       Demo(){ //الدالة الانشائية
          //هنا تم تهيئته في هذه الدالة 
          MAX_VALUE=100;
       }
       void myMethod(){  
          System.out.println(MAX_VALUE);
       }  
       public static void main(String args[]){  
          Demo obj=new  Demo();  
          obj.myMethod();  
       }  
    }
    

    سنحصل على النتيجة التالية عند التشغيل.

    100

    لماذا نستخدم blank final variable

    دعنا نقول أن لدينا صف طلابي يحتوي على حقل يسمى Roll No.. بما أن Roll No لا يجب أن يتم تغييره بمجرد تسجيل الطالب ، يمكننا أن نعلن عنه كمتغير نهائي في الفصل ولكن لا يمكننا التهيئة التمهيدية مسبقا لجميع الطلاب (وإلا سيحصل كل الطلاب على نفس القوائم). في مثل هذه الحالة ، يمكننا أن نعلن عن عدم وجود متغير على أنه نهائي فارغ ونقوم بتهيئة هذه القيمة أثناء إنشاء الكائن كما يلي:

    class StudentData{  
        //Blank final variable
       final int ROLL_NO;  //لاحظ أن جميع المتغيرات الثابتة تكون بحروف كبيرة
      
       StudentData(int data){
           //It must be initialized in constructor
          ROLL_NO=data;
       }
       void myMethod(){  
          System.out.println("Roll no is:"+ROLL_NO);
       }  
       public static void main(String args[]){  
          StudentData obj=new  StudentData(1000);  
          obj.myMethod();  
       }  
    }
     

    سنحصل على النتيجة التالية عند التشغيل.

    Roll no is:1000

    Uninitialized static final variable

    يمكن تهيئة المتغيرات الثابتة في غير مكان التعريف , وتكون التهيئة في static block
    class Example{  
        //static blank final variable  
       static final int ROLL_NO;
       static{ 
          ROLL_NO=1000;
       }  
       public static void main(String args[]){  
          System.out.println(Example.ROLL_NO);  
       }  
    }
     

    سنحصل على النتيجة التالية عند التشغيل.

    1000

    المتغيرات التي يتم تعريفها كـ final static

    يمكن تعريف المتغير كـ final و static مع بعض, و عندها يمكن الوصول للمتغير من الكلاس مباشرةً أو من أي كائن من الكلاس, مع عدم إمكانية تغيير قيمته بعد تحديدها.
    الـ Math.PI و الـ Math.E هم من المتغيرات المعرفة كـ final static في جافا, يمكنك استخدامهم كما هم لكن لا يمكنك تغيير قيمهم.

    الدوال التي يتم تعريفها كـ final

    الدالة التي يتم تعريفها كـ final يعني أنه لا يمكن أن يتم تعريف محتواها في أي كلاس آخر. أي الكلاس الذي يرثها لا يسمح له بأن يفعل لها override.
    class first{  
       final void demo(){
          System.out.println("first Class Method");
       }  
    }  
          
    class second extends first{  
       void demo(){
          System.out.println("second Class Method");
       }  
          
       public static void main(String args[]){  
          second obj= new second();  
          obj.demo();  
       }  
    }
     

    سيظهر خطأ تجميع عند كتابة الكود السابق ولكن يمكننا حل المشكلة بالطريقة التالية

    class first{  
       final void demo(){
          System.out.println("first Class Method");
       }  
    }  
          
    class second extends first{  
       public static void main(String args[]){  
          second obj= new second();  
          obj.demo();  
       }  
    }
     

    سنحصل على النتيجة التالية عند التشغيل.

    first Class Method

    الكلاسات التي يتم تعريفها كـ final

    الكلاس الذي يتم تعريفه كـ final يعني أنه لا يمكن الوراثة منه.
    final class first{  
    }  
          
    class second extends first{  
       void demo(){
          System.out.println("My Method");
       }  
       public static void main(String args[]){  
          second obj= new second(); 
          obj.demo();
       }  
    }
     

    سنحصل على النتيجة التالية عند التشغيل.

    The type second cannot subclass the final class first

    نقاط مهمة

    1. A constructor cannot be declared as final.

    2. We cannot change the value of a final variable.

    3. All variables declared in an interface are by default final.

    4. A final class cannot be inherited.

    5. A final method cannot be overridden.

    6. It is a good practice to name final variable in all CAPS.

    7. Local final variable must be initializing during declaration.

    8. If method parameters are declared final then the value of these parameters cannot be changed.

    ليست هناك تعليقات:

    إرسال تعليق

    ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.

    صفحتنا علي الفيسبوك

    التسميات

    المتواجدين حاليا