آشنایی با انواع سطوح دسترسی در زبان برنامه‌نویسی جاوا


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

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

به طور کلی، در زبان برنامه‌نویسی جاوا با استفاده از کلیدواژگان public ،protected و private در کنار نام کلاس، متد یا متغیر مورد نظر خود می‌توانیم سطوح دسترسی آن‌ها را مشخص سازیم به علاوه اینکه سطح دسترسی دیگری در زبان جاوا تعريف شده است که در صورت ذکر هيچ یک کلیدواژه‌های مطرح‌شده در بالا، کامپایلر جاوا به صورت پیش‌فرض سطح دسترسی Package را برای کلاس، متد یا متغیر مربوطه در نظر می‌گیرد که در ادامه به بررسی نحوۀ عملکرد هر یک از این سطوح دسترسی می‌پردازیم.

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

استفاده از کلیدواژۀ protected در کنار نام یک کلاس، متد یا متغیر حاکی از آن است که اِلِمان مورد نظر در همان کلاس، دیگر پکیج‌های پروژه و همچنین کلاس‌های ارث‌بری شده از آن قابل‌دسترسی می‌باشد.

به‌کارگیری کلیدواژۀ private در کنار نام یک کلاس، متد یا متغیر نیز بدین معنی است که اِلِمان مورد نظر صرفاً همان کلاس قابل‌دسترسی می‌باشد.

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

حال به منظور یادگیری بهتر نحوۀ کارکرد سطوح دسترسی در زبان جاوا، خلاصه‌ای از مطالب فوق‌الذکر را در قالب جدولی به صورت زیر آورده‌ایم:

Others Subclass Package Class
public
- protected
- - Package
- - - private

اکنون برای درک بهتر کاربرد کلیۀ سطوح دسترسی در قالب مثالی کاربردی، نیاز داریم تا سناریویی تعریف کرده و بر اساس آن برنامه‌ای را پیاده‌سازی نماییم. در همین راستا، دو کلاس داخل یک پکیج ایجاد می‌کنیم و برای یکی از آن‌ها محدودیت دسترسی بیشتری نسبت به کلاس دیگر تعریف می‌کنیم. در همین راستا، در آی‌دی‌ای اکلیپس پروژه‌ای تحت عنوان AccessControl ایجاد کرده و در آن کلاسی به نام MainClass می‌سازیم. همچنین در حین ساخت کلاس توجه داشته باشیم که پیش از زدن دکمۀ Finish می‌باید در فیلد مربوط به Package یک نام برای پکیج خود انتخاب کنیم که در این آموزش نام دلخواه MainPackage را مد نظر قرار داده‌ایم. به علاوه، به منظور انتخاب کلاس MainClass به عنوان نقطۀ شروع برنامۀ خود در حین ساخت کلاس لازم است تا تیک گزینۀ public static void main را بزنیم به طوری که در ابتدا کدی به صورت زیر خواهیم داشت:

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

همان‌طور که ملاحظه می‌کنیم، در سطر اول از کد فوق نام پکیج مورد نظر نوشته شده است. حال اقدام به ایجاد کلاسی دیگر تحت عنوان SecondClass می‌کنیم و این کلاس قرار نیست تا نقطۀ شروع برنامه باشد لذا گزینۀ public static void main را تیک نمی‌زنیم و از همین روی کد مربوط به SecondClass در ابتدا به صورت زیر خواهد بود:

package MainPackage;
public class SecondClass {

}

حال می‌خواهیم تا کلاس MainClass را به گونه‌ای تعریف کنیم تا یکسری از خصوصیات کلاس SecondClass را به ارث ببرد و از همین روی کد مربوط به MainClass را به صورت زیر بازنویسی می‌کنیم:

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

در ادامه، یکسری اتریبیوت‌ و متد برای SecondClass به صورت زیر تعریف می‌کنیم:

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

در کد فوق، ابتدا یک متغیر استاتیک با استفاده از دیتا تایپ int تحت عنوان number با مقدار اولیۀ 123 تعریف کرده سپس متدی به نام ()testMethod ایجاد کرده‌ایم که این وظیفه را دارا است تا در صورت فراخوانی، مقدار منتسب به متغیر number را با استفاده از متد ()println در کنسول چاپ نماید (البته این کلاس را نمی‌توان اجرا کرد چرا که نقطۀ آغازین یا همان متد ()main را ندارد. به علاوه، جهت کسب اطلاعات بیشتر در رابطه با متغیرهای استاتیک به آموزش آشنایی با کلیدواژۀ static و کاربردهای آن در قالب پروژۀ ثبت‌نام متقاضیان در باشگاه در زبان جاوا مراجعه نمایید.)

اکنون در کلاس MainClass متد ()testMethod را فراخوانی می‌کنیم و از آنجایی که کلاس MainClass از کلاس SecondClass ارث‌بری می‌کند، نیازی به ساخت آبجکت جدید از روی کلاس دوم نداشته و به سادگی می‌توانیم متد ()testMethod را در آن فراخوانی کنیم و بدین ترتیب کد کلاس MainClass به صورت زیر خواهد بود:

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

حال اگر برنامۀ فوق را اجرا کنیم در خروجی خواهیم داشت:

123

در واقع، عدد 123 مقدار متغیری تحت عنوان number است که در SecondClass تعریف شده و با فراخوانی متد ()testMethod از این کلاس توانستیم مقدار منتسب به متغیر مذکور را در کنسول چاپ نماییم. حال سطح دسترسیِ متد تعریف‌شده در SecondClass را محدود کرده و آن را به private تغییر می‌دهیم که برای این منظور کد مربوط به این کلاس را به صورت زیر بازنویسی می‌کنیم:

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

فایل مربوط به SecondClass را سِیو کرده و به محض انجام این کار هشداری در قالب عبارت زیر در کنار سطر مربوط به فراخوانی متد ()testMethod مشاهده خواهیم کرد:

The method testMethod() from the type SecondClass is not visible

این هشدار حاکی از آن است که متدی تحت عنوان ()testMethod از کلاس SecondClass قابل‌رؤیت نمی‌باشد (این هشدار در کلاس MainClass و در قالب اروری به همین صورت قابل‌مشاهده می‌باشد.) در واقع، به محض سِیو کردن فایل مربوط به SecondClass زیر نام متد ()testMethod در کلاس MainClass خطی قرمز نمایش داده می‌شود که با قرار دادن نشانگر ماوس روی آن می‌بینیم که آی‌دی‌ای اکلیپس به منظور رفع مشکل به وجود آمده پیشنهاد انتخاب سطح دسترسی مرتبط با این متد را ارائه می‌کند.

دانلود فایل‌های تمرین

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
karo.clan54
karo.clan54
۱۳۹۸/۰۶/۱۹
سلام استاد بهزاد عزیز ببخشید یکجا اشتباهی شده من خواستم گزارشش بدم قبلش درود فراوان و خسته نباشید ویژه بهتون میگم امیدوارم همیشه موفق باشید-
تو اسم پکیج اشتباه هست که با حروف بزرگ شروع بشه حتی خود اکلیپس هم این رو با وارد کردن حروف بزرگ هشدار میده ! این درسته mainControl
jani871
jani871
۱۳۹۶/۰۸/۲۰
درود فراوان
بنده آموزش های شما را دنبال میکنم و از روش آموزش بسیار راضی هستم
سپاس
کاربر میهمان
Titanمن یک کاربر مهمان هستم
۱۳۹۵/۰۴/۲۴
سلام.چه طور میشه تعین کرد که یک کلاس هم زمان از دوتا کلاس ارث بری کنه؟
کاربر میهمان
امیرمن یک کاربر مهمان هستم
۱۳۹۵/۰۱/۱۲
ببخشید من کاربرد static که قبل int تو کلاس SecondClass گذاشتید رو نفهمیدم (توضیح ندادید)
کاربر میهمان
حمیدمن یک کاربر مهمان هستم
۱۳۹۴/۱۰/۰۴
با سلام و عرض تشکر و خدا قوت
کاربرد پکیج ها چیست و برای چه منظور استفاده می شوند؟