الموضوع 5
محددات الوصول Access Modifiers
كلمات تُكتب قبل الكلاس أو الخاصية أو الدالة، تحدّد من يستطيع الوصول إليها.
بعد هذا الدرس ستستطيع أن:
- تميّز بين معدّلات الوصول access modifiers ومعدّلات عدم الوصول non-access modifiers.
- تحدد نطاق الوصول لكل من public و private و protected و default.
- تتوقّع خطأ الترجمة عند الوصول إلى عضو غير مسموح بالوصول إليه.
- تختار محدد الوصول المناسب لكل خاصية ودالة في الكلاس.
١أقسام المعدّلات Modifiers
٢معدّلات الوصول الأربعة
تُكتب قبل اسم: الكلاس، أو دالة البناء، أو المتغير، أو الدالة.
| المحدد | داخل الكلاس | داخل الحزمة | خارج الحزمة بالوراثة | خارج الحزمة بلا وراثة |
|---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
| default (بلا كلمة) | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |
الدوائر في رأس الصفحة تمثّل الجدول نفسه: كل محدد يشمل نطاق ما قبله ويزيد عليه.
مثال الحزمتين p1 و p2
Package p1
class C1
- public int a;
- protected int b;
- int c;
- private int d;
class C2
C1 o = new C1( );
- o.a;يمكن الوصول له
- o.b;يمكن الوصول له
- o.c;يمكن الوصول له
- o.d;لا يمكن
class C3 extends C1
- a;يمكن الوصول له
- b;يمكن الوصول له
- c;يمكن الوصول له
- d;لا يمكن
Package p2
class C4
C1 o = new C1( );
- o.a;يمكن الوصول له
- o.b;لا يمكن
- o.c;لا يمكن
- o.d;لا يمكن
class C5 extends C1
- a;يمكن الوصول له
- b;يمكن الوصول له
- c;لا يمكن
- d;لا يمكن
- C2 في الحزمة نفسها p1 ولا يرث C1: يصل إلى a و b و c، ولا يصل إلى d لأنه private.
- C3 في الحزمة نفسها p1 ويرث C1: يصل إلى a و b و c، ولا يصل إلى d لأنه private.
- C4 في حزمة أخرى p2 ولا يرث C1: يصل إلى a فقط لأنه public.
- C5 في حزمة أخرى p2 ويرث C1: يصل إلى a لأنه public، وإلى b لأنه protected والوراثة تسمح بذلك. ولا يصل إلى c لأنه default (داخل الحزمة p1 فقط)، ولا إلى d لأنه private.
| الخلاصة | |
|---|---|
private | أقوى حماية |
| default | داخل الحزمة فقط |
protected | مثل default لكن يفتح الباب للوراثة من حزم أخرى |
public | مفتوح للجميع |
٣دالة بناء من نوع private
إذا جعلت دالة البناء private فلا يمكن إنشاء كائن من ذلك الكلاس من خارجه:
class A{ //private constructor private A(){ System.out.println("Welcome my object"); } void msg(){ System.out.println("Hello java"); }}public class Simple{ public static void main(String args[]){ //Compile Time Error A obj=new A(); }}
Simple.java:13: error: A() has private access in A
جرّب الزر «شغّل هنا» لترى رسالة المترجِم بنفسك.
٤ما الاستخدام الأمثل لمحددات الوصول؟
| المحدد | متى نستخدمه؟ |
|---|---|
| default | نستخدمه لحصر الوصول إلى العضو (متغير أو دالة أو كلاس) داخل الحزمة نفسها فقط، ومنعه عن أي كلاس خارجها حتى لو كان يرث الكلاس. مثال: كلاسات داخل حزمة واحدة تتعاون وتتشارك البيانات، بينما تبقى هذه التفاصيل مخفية عن أي حزمة أخرى تستخدمها. |
| public | للدوال التي نريد للجميع استخدامها. |
| private | للمتغيرات (الخصائص) دائمًا تقريبًا، مع دوال عامة للوصول إليها: هذا هو التغليف. |
| protected | لعضو نريد أن تصل إليه الكلاسات الوارثة حتى لو كانت في حزمة أخرى. |
محددات الكلاس نفسه
- الكلاس يكون public (يصل إليه أي كلاس) أو default (داخل حزمته فقط).
- لا يُعرَّف كلاس رئيسي بـ private أو protected.
توقّع وتحقّق
أجب قبل أن تنظر إلى الشرح. التصحيح فوري، وإجاباتك تُحفظ.
خاصية private يمكن الوصول إليها من:
إذا لم نكتب أي محدد وصول يكون:
تأمل الكود التالي من التدريب 8:
// File: ClassA.javapackage package1;public class ClassA { public String f_public = "public"; private String f_private = "private"; protected String f_protected = "protected"; String f_default = "default";} // File: ClassC.javapackage package2;import package1.ClassA;public class ClassC extends ClassA {}
الكلاس ClassC موجود في حزمة أخرى package2 ويرث ClassA. ما الخصائص التي يستطيع ClassC الوصول إليها؟
protected يسمح بالوصول من حزمة أخرى عن طريق الوراثة. أما f_default فداخل الحزمة package1 فقط، و f_private داخل ClassA فقط.
أي محدد يناسب خصائص الكلاس عادةً؟
ثم نوفّر دوال public للتعامل معها: التغليف.
الخلاصة
- private ⊂ default ⊂ protected ⊂ public في سعة النطاق.
- private داخل الكلاس، default داخل الحزمة، protected يضيف الوراثة عبر الحزم، public في كل مكان.
- الكلاس نفسه public أو default فقط.
- الخصائص private والدوال public: أساس التغليف.