معدلات الوصول
جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 31 من 70.
تتحكم معدلات الوصول في من يمكنه رؤية واستخدام أعضاء الفئة الخاصة بك. فهي أساس التغليف - أحد المبادئ الأساسية للبرمجة كائنية التوجه (OOP). من خلال تقييد الوصول، فإنك تحمي بياناتك وتنشئ حدوداً واضحة في التعليمات البرمجية الخاصة بك.
توفر لغة C# أربعة معدلات وصول رئيسية:
public class BankAccount
{
public string AccountHolder; // يمكن الوصول إليه من أي مكان
private decimal balance; // داخل هذه الفئة فقط
protected string accountType; // هذه الفئة والفئات المشتقة
internal int branchCode; // داخل نفس التجميع (assembly)
}يمكن الوصول إلى الأعضاء public من أي كود.
يمكن الوصول إلى أعضاء private فقط من داخل نفس الفئة - وهذا هو الأكثر تقييداً والوضع الافتراضي لأعضاء الفئة.
يسمح protected بالوصول من الفئة نفسها ومن أي فئة ترث منها.
يقيد internal الوصول إلى الكود داخل نفس التجميع (المشروع) (assembly).
عندما لا يتم تحديد معدل وصول، تكون أعضاء الفئة private بشكل افتراضي:
class Example
{
int secret; // خاص بشكل افتراضي
}اختيار مستوى الوصول الصحيح يتعلق بالكشف عما هو ضروري فقط. ابدأ بـ private وقم بزيادة مستوى الرؤية فقط عندما يكون لديك سبب واضح. هذا يمنع الأكواد الأخرى من الاعتماد على تفاصيل التنفيذ التي قد ترغب في تغييرها لاحقاً.
التحدي
سهللنقم ببناء نظام ملف تعريف مستخدم آمن يوضح كيف تحمي معدلات الوصول (access modifiers) البيانات الحساسة مع كشف ما هو ضروري فقط. ستقوم بإنشاء فئة (class) حيث تمتلك أجزاء مختلفة من المعلومات مستويات رؤية مختلفة بناءً على من يجب أن يكون قادراً على الوصول إليها.
ستقوم بتنظيم الكود الخاص بك عبر ثلاثة ملفات:
UserProfile.cs: أنشئ فئةUserProfileداخل مساحة الأسماءSecurityالتي تدير معلومات المستخدم بمستويات وصول مناسبة. يجب أن يحتوي ملف التعريف على:- خاصية
publicباسمUsername(string) - يمكن لأي شخص رؤية اسم المستخدم. - حقل
privateباسمpassword(string) - يجب أن تصل الفئة نفسها فقط إلى هذا الحقل. - حقل
protectedباسمemail(string) - يمكن للفئة والفئات المشتقة منها الوصول إلى هذا الحقل. - حقل
internalباسمuserId(int) - يمكن الوصول إليه داخل نفس التجميع (assembly).
publicيسمىGetPublicInfo()يعيد"User: {Username}". أضف تابعاًpublicآخر يسمىValidatePassword(string input)يعيدtrueإذا كان الإدخال يطابق كلمة المرور الخاصة، وfalseخلاف ذلك.- خاصية
AdminProfile.cs: أنشئ فئةAdminProfileداخل مساحة الأسماءSecurityترث منUserProfile. توضح هذه الفئة كيف تصبح الأعضاء المحميةprotectedقابلة للوصول في الفئات المشتقة. يجب أن يقبل المنشئ نفس المعلمات الأربعة ويمررها إلى منشئ الفئة الأساسية. أضف تابعاًpublicيسمىGetAdminInfo()يعيد"Admin: {Username}, Email: {email}"- لاحظ أنه يمكنك الوصول إلى حقلemailالمحمي هنا!Program.cs: في ملفك الرئيسي، أنشئ كائناً منUserProfileوآخر منAdminProfileباستخدام قيم الإدخال. استعرض مستويات الوصول من خلال استدعاء التوابع العامة المتاحة والوصول إلى الحقل الداخلي (internal) مباشرة (بما أنك في نفس التجميع). أظهر المعلومات التي يمكن لكل نوع من المستخدمين الكشف عنها.
ستتلقى خمسة مدخلات:
- Username
- Password
- User ID (عدد صحيح)
- محاولة كلمة المرور للتحقق منها
اطبع المخرجات بهذا التنسيق:
Regular User:
{GetPublicInfo() result}
Internal ID: {userId}
Password valid: {ValidatePassword result}
Admin User:
{GetAdminInfo() result}على سبيل المثال، إذا كانت المدخلات هي alice، و secret123، و alice@email.com، و 1001، و secret123، يجب أن تكون المخرجات:
Regular User:
User: alice
Internal ID: 1001
Password valid: True
Admin User:
Admin: alice, Email: alice@email.comلاحظ كيف تظل كلمة المرور مخفية تماماً - يمكنك فقط التحقق من صحتها، ولا يمكنك استرجاعها أبداً. البريد الإلكتروني محمي، لذا يمكن فقط لـ AdminProfile (فئة مشتقة) الكشف عنه. الـ userId الداخلي يمكن الوصول إليه من ملفك الرئيسي لأنه في نفس التجميع. هذا هو مفهوم التغليف (encapsulation) في أبهى صوره!
ورقة مرجعية
تتحكم معدلات الوصول (Access modifiers) في رؤية وإمكانية الوصول إلى أعضاء الفئة (class members)، مما يشكل أساس التغليف (encapsulation) في البرمجة كائنية التوجه (OOP).
توفر لغة C# أربعة معدلات وصول رئيسية:
public class BankAccount
{
public string AccountHolder; // يمكن الوصول إليه من أي مكان
private decimal balance; // داخل هذه الفئة فقط
protected string accountType; // هذه الفئة والفئات المشتقة منها
internal int branchCode; // داخل نفس التجميع (assembly)
}public: يمكن الوصول إليه من أي كود
private: يمكن الوصول إليه فقط داخل نفس الفئة (الأكثر تقييداً، وهو الافتراضي لأعضاء الفئة)
protected: يمكن الوصول إليه من الفئة نفسها ومن أي فئات مشتقة منها
internal: يمكن الوصول إليه فقط داخل نفس التجميع (المشروع)
عندما لا يتم تحديد معدل وصول، يتم تعيين أعضاء الفئة افتراضياً إلى private:
class Example
{
int secret; // private بشكل افتراضي
}أفضل ممارسة: ابدأ بـ private وقم بزيادة مستوى الرؤية فقط عند الضرورة لمنع الكود الخارجي من الاعتماد على تفاصيل التنفيذ.
جرّب بنفسك
using System;
using Security;
class Program
{
public static void Main(string[] args)
{
// قراءة المدخلات
string username = Console.ReadLine();
string password = Console.ReadLine();
string email = Console.ReadLine();
int userId = Convert.ToInt32(Console.ReadLine());
string passwordAttempt = Console.ReadLine();
// TODO: إنشاء كائن UserProfile باستخدام قيم المدخلات
// TODO: إنشاء كائن AdminProfile باستخدام نفس قيم المدخلات
// TODO: طباعة "Regular User:"
// TODO: طباعة نتيجة GetPublicInfo()
// TODO: طباعة "Internal ID: " متبوعاً بحقل userId (يمكن الوصول إليه لأنه في نفس الـ assembly)
// TODO: طباعة "Password valid: " متبوعاً بنتيجة ValidatePassword()
// TODO: طباعة "Admin User:"
// TODO: طباعة نتيجة GetAdminInfo()
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injection