در این آموزش سطوح دسترسی مختلف در زبان برنامهنویسی جاوا را معرفی کرده و کاربرد هر یک در کنترل سطح دسترسی به کلاسها، متغیرها و متدها را مورد بررسی قرار میدهیم. در واقع، مبحث سطوح دسترسی به هر یک از کلاسها، متغیرها و متدها به طور خاص در پروژههایی که توسعۀ آنها به صورت تیمی انجام میشوند از اهمیت بسیار بالایی برخوردار میباشد.
حال به منظور درک بهتر مفهوم و همچنین کاربرد سطوح دسترسی، شرایطی را در نظر میگیریم که در آن فرض میکنیم که قرار است تا به عنوان سرپرست گروهی از برنامهنویسان روی طراحی یک نرمافزار کار کرده و وظیفۀ کنترل سطح دسترسیِ اعضای تیم به کلاسها، متغیرها و متدهایی متناسب با وظایفشان را داریم. در عین حال، فرض میکنیم که آشنایی زیادی در رابطه با نحوۀ کنترل سطح دسترسی در زبان برنامهنویسی جاوا نداریم که در چنین شرایطی برای مثال ممکن است یکی از اعضای تیم در حین کار بر روی پروژه به برخی از متغیرها دسترسی داشته و بدون هیچ سوءقصدی مقدار اولیۀ آنها را تغییر دهد که در این صورت خروجی حاصل از پروژه به نتیجهای غیرقابلباور تبدیل خواهد شد!
به طور کلی، در زبان برنامهنویسی جاوا با استفاده از کلیدواژگان 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
خطی قرمز نمایش داده میشود که با قرار دادن نشانگر ماوس روی آن میبینیم که آیدیای اکلیپس به منظور رفع مشکل به وجود آمده پیشنهاد انتخاب سطح دسترسی مرتبط با این متد را ارائه میکند.