مدیریت سطح دسترسی ها در زبان برنامه نویسی جاوا


در این قسمت قصد داریم تا به بررسی Access Control (اکسس کنترل) به معنی "مدیریت سطح دسترسی" در کلاس ها، متغیر ها و متد ها بپردازیم. در واقع، یکی از مواقعی که این مبحث اهمیتش دو چندان می شود، زمانی است که تیمی از برنامه نویسان بخواهند به صورت گروهی روی پروژه ای یکسان کار کنند.

فرض کنیم که قرار است به عنوان سرپرست گروهی از برنامه نویسانی باشیم که روی طراحی یک نرم افزار کار می کنند. وظیفه ای که مدیر پروژه بر عهده ی ما گذاشته این است که کنترل کنیم که هر برنامه نویسی بنا به وظیفه ای که دارد تا چه حدی به دیگر کلاس ها، متغیر ها و متد هایی که توسط دیگر برنامه نویسان نوشته می شوند، می تواند دسترسی داشته باشد.

اگر ما به عنوان سرپرست مابقی برنامه نویسان کار خود را به خوبی انجام دهیم، به نظر می رسد که مشکلی حادی در این رابطه بوجود نیاید. فرض کنیم ما آن طور که باید و شاید در مورد اکسس کنترل در زبان برنامه نویسی جاوا آگاهی نداریم. در این جا است که پروژه ما با مشکلات جدی مواجه خواهد شد چرا به طور مثال برنامه نویسی که نمی بایست به یک متغیر از جنس int دسترسی داشته باشد حال این امکان برایش فراهم شده و ایشان هم بدون هیچ سوء قصدی مقدار اولیه آن متغیر را تغییر داده اند و نتیجه ای که برنامه در حین کار می بایست داشته باشد به نتیجه ای غیر قابل باور تبدیل خواهد شد!

برای درک بهتر سطح دسترسی در زبان برنامه نویسی جاوا پروژه ای تحت عنوان Access Control ایجاد می کنیم. در زبان برنامه نویسی جاوا، ما با قرار دادن کلیدواژگان public, protected, private و گاهی اوقات هم هیچ کلیدواژه ای، مشخص می کنیم که اکسس یا «میزان دسترسی» به یک کلاس، متد و یا متغیر چقدر می بایست باشد. 

در حقیقت با قرار دادن کلید واژه ی public پیش از یک کلاس، متد و یا متغیر این دستور را به برنامه خود می دهیم که این کلاس، متد و یا متغیر در دیگر بخش های برنامه و توسط دیگر کلاس ها قابل دسترسی است. به عبارت دیگر از هر جای دیگر برنامه من جمله بخش های دیگر همان کلاس، دیگر پکیج ها، کلاس های ارث بری شده از آن می توان به عناصر public دسترسی داشته و در صورت لزوم تغییری در آن ها ایجاد کرد.

کلید واژه ی protected حاکی از آن است که عنصری که این کلید واژه قبل از آن قرار گرفته است در همان کلاس، دیگر پکیج ها و کلاس های ارث بری شده از آن قابل دسترسی خواهد بود.

کلید واژه ی private این معنا را می رساند که مثلا متغیری که private است فقط و فقط در همان کلاس قابل دسترسی خواهد بود.

زمانی هم که هیچ کلید واژه ی محدود کننده ای قبل از نام یک کلاس، متد و یا متغیر نباشد، این سطح دسترسی Package Access نامیده می شود و بدان معنا است که عنصری که فاقد هرگونه public, protected, private باشد در همان کلاس و یا دیگر کلاس های موجود در همان پکیج قابل دسترسی خواهد بود. برای روشن شدن تفاوت مابین این چهار سطح دسترسی می توان از جدول زیر کمک گرفت:

اکنون برای درک بهتر کلیه سطوح دسترسی نیاز داریم تا یک پروژه کوچک تعریف کرده و بر اساس آن یک برنامه بنویسیم. فرض کنیم که می خواهیم دو کلاس داخل یک پکیج ایجاد کنیم که یکی از آن ها دارای محدودیت بیشتری نسبت به کلاس دیگری است.

در پروژه ای که در ابتدای این آموزش ایجاد کردیم یک کلاس تحت عنوان MainClass به معنی کلاس اصلی ایجاد می کنیم. پیش از زدن دکمه Finish می بایست یک نام برای پکیج خود نیز انتخاب کنیم. برای همین منظور نام MainPackage را نیز به معنی "پکیج اصلی" در نظر می گیریم. برای روش تر شدن مطلب به تصویر زیر توجه کنید:

همان طور که در این تصویر مشاهده می شود جایی که با فلش قرمز مشخص شده می بایست برای نام پکیج نوشته شود و جایی که با فلش سبز رنگ مشخص شده می بایست برای نام کلاس پر شود. از آنجا که این کلاس قرار است کلاسی باشد که برنامه در آن شروع شود از این رو در حین ساختن آن می بایست گزینه public static void main(String[] args) را تیک بزنیم.

در این مرحله کد ما می بایست به شکل زیر باشد:

package MainPackage;
public class MainClass {
    public static void main (String[] args){
    }
}

همان طور که در کد بالا ملاحظه می شود، در خط اول نام پکیج نوشته شده است. حال اقدام به ایجاد یک کلاس دیگر تحت عنوان SecondClass به معنی "کلاس دوم" می کنیم. از آنجا که این کلاس قرار نیست که به منزله نقطه شروع برنامه باشد گزینه ی (public static void main(String[] args را تیک نمی زنیم. کد مربوط به کلاس دوم ما نیز می بایست به شکل زیر باشد:

package MainPackage;
public class SecondClass {

}

حال می خواهیم تا کلاس اول ما یکسری از خصوصیات کلاس SecondClass را به ارث ببرد از این رو کد MainClass را به شکل زیر بازنویسی می کنیم:

package MainPackage;
public class MainClass extends SecondClass{
    public static void main (String[] args){
    }
}

در ادامه کلاس دوم خود را به شکل زیر تکمیل می کنیم:

package MainPackage;
public class SecondClass {
    static int number = 123;
    public static void testMethod() {
        System.out.println(number);
    }
}

در این کد ما یک متغیر از جنس int تحت عنوان number به معنی "شماره" ایجاد کرده سپس یک متد به اسم testMethod ایجاد کرده و در آن دستور داده ایم که مقدار متغیر ما تحت عنوان number در پنجره ی کنسول نمایش داده شود. البته این کلاس از آن جا که نقطه آغازین یا همان متد main را ندارد چیزی اجرا نخواهد کرد. اکنون در کلاس MainClass متد testMethod را اجرا می کنیم (از آنجا که کلاس MainClass از روی کلاس SecondClass ارث بری می کند، دیگری نیازی به ساخت یک آبجکت از روی کلاس دوم نداشته و به سادگی می توانیم متد testMethod را اصطلاحا Call یا «فراخوانی» کنیم.) کد ما در کلاس MainClass به شکل زیر خواهد بود:

package MainPackage;
public class MainClass extends SecondClass {
    public static void main(String[] args) {
        testMethod();
    }
}

حال اگر برنامه را اجرا کنیم، تصویر زیر مشاهده خواهد شد:

در واقع عدد 123 مقدار متغیری تحت عنوان number است که در کلاس SecondClass ایجاد شده است. حال می خواهیم تا از قصد سطح دسترسی متد ایجاد شده در SecondClass را محدود کنیم. به عبارت دیگر سطح دسترسی آن را از نوع public به نوع private تغییر می دهیم. کد ما به شکل زیر بازنویسی خواهد شد:

package MainPackage;
public class SecondClass {
    static int number = 123;
    private static void testMethod() {
        System.out.println(number);
    }
}

به محض این که فایل خود را Save کنیم، در پنجره Problems خطای زیر ایجاد خواهد شد:

این ارور حاکی از آن است که متدی تحت عنوان testMethod از کلاس SecondClass قابل روئیت نمی باشد (چنانچه پنجره Problems باز نباشد می توان از منوی اصلی محیط برنامه نویسی اکلیپس گزینه Window را انتخاب کرده سپس گزینه Show View و در نهایت گزینه Problems را کلیک نماییم.) اگر به MainClass نگاهی بیندازیم می بینیم که آنجا هم این مشکل خود را نشان خواهد داد. در واقع به محض Save کردن فایل خود دور نام متد testMethod یک نقطه چین قرار خواهد گرفت و با قرار دادن نشانگر موس خود روی آن می بینیم که اکلیپس به ما پیشنهاد می دهد که اکسس کنترل مرتبط با این متد را تغییر دهیم تا مشکل برنامه رفع گردد.

دانلود فایل‌های تمرین
لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
کاربر میهمان
کاربر میهمان
سلام یه سوال
چرا نمی شه تو main به متغیر ها رو مدیرت دسترسی داد هرچی میزاری(public , private) خطا میده.
با تشکر
jani871
jani871
درود فراوان
بنده آموزش های شما را دنبال میکنم و از روش آموزش بسیار راضی هستم
سپاس
کاربر میهمان
کاربر میهمان
با سلام. چرا ما باید یک متد یا متغیر رو private یا محدود کنیم. میشه بیشتر توضیح بدید. اگه امکانش هست.
aliireza
aliireza
سلام ممنون از اموزش های خوبتون.این متد static که استفاده کردینو اصلا توضیح ندادین که معنیش چیه کاربردش چیه میشه درموردش یکم توضیح بدین؟
aliireza
aliireza
ببخشید بالارونخونده بودم!

در پاسخ به

کاربر میهمان
کاربر میهمان
سلام.چه طور میشه تعین کرد که یک کلاس هم زمان از دوتا کلاس ارث بری کنه؟
mohammad m
mohammad m
سلام,خسته نباشید
static int number = 123;
در اینجا کار static چیست؟
CIna Deuxshiri
CIna Deuxshiri
سلام. در نظر بالایی من وضیح دادم.

در پاسخ به

کاربر میهمان
کاربر میهمان
ببخشید من کاربرد static که قبل int تو کلاس SecondClass گذاشتید رو نفهمیدم (توضیح ندادید)
CIna Deuxshiri
CIna Deuxshiri
سلام. کاربرد استاتیک رو باید در یک مطلب به طور کامل آموزش داد. اما در اینجا برای اینکه متد testMethod به صورت استاتیک تعریف شده، فقط می‌تونه از فیلد‌ها و متد‌های استاتیک استفاده کنه. برای همین متغیر number به صورت استاتیک تعریف شده.

در پاسخ به

عیسی پور
عیسی پور
سلام و خدا قوت.
مثل همیشه عالی
دو تا پیشنهاد داشتم یکی اینکه یه بخشی رو برای گرفتن تست مربوط به هر آموزش یا کل آموزش های یک زبان به صورت کلی ایجاد کنید و یکی هم اینکه یه بخشی رو اختصاص بدید به ارورهای رایج هر زبانی که آموزش میدید.
سپاس
کاربر میهمان
کاربر میهمان
با سلام و عرض تشکر و خدا قوت
کاربرد پکیج ها چیست و برای چه منظور استفاده می شوند؟
CIna Deuxshiri
CIna Deuxshiri
سلام
برای دسته بندی کلاس های مرتبط با هم و پکیج می کنند. اگه دقت کنید تمام کتابخانه های جاوا به صورت پکیج هستند.

در پاسخ به