پکیج در جاوا گروهی از کلاسها، اینترفیس ها و زیر پکیج ها هستند.
پکیج ها به دو گونه هستند، پکیج های داخلی و پکیج های ساخته کاربر. تعداد زیادی پکیج داخلی مانند io ،lang و awt وجود دارد. در ادامه طرز دسترسی و ساخت پکیج ها را بررسی می کنیم.
مزایای پکیج کردن
- دسته بندی کلاس ها و اینترفیس ها به گونه ای که به راحتی نگهداری شود.
- برای محدود کردن دسترسی مورد استفاده قرار می گیرد.
- در صورت یکسانی اسم چندین کلاس، می توان از پکیج برای میسر کردن این اتفاق انجام داد.
تعریف پکیج
//save as Simple.java package mypack; public class Simple{ public static void main(String args[]){ System.out.println("Welcome to package"); } }
کامپایل پکیج جاوا
در صورتی که از IDE خاصی استفاده نمی کنید، از سینتکس زیر پیروی کنید:
avac -d directory javafilename
به عنوان مثال:
javac -d . Simple.java
سویچ –d برای مشخص کردن مکانی است که فایل کلاس های ساخته شده در آنجا قرار می گیرند. به جای این سویچ می توانید مکان مورد نظر خود را قرار دهید و در صورتی که می خواهید در همین دایرکتوری پکیج را نگه دارید، آدرس خود را پس از نقطه وارد کنید.
برای اجرای کلاس هم به شکل زیر عمل کنید:
کامپایل : javac -d . Simple.java |
اجرا : java mypack.Simple |
Output:Welcome to package
-d هم چنان برای مشخص کردن مکان استفاده می شود.
دسترسی به پکیج از پکیج های دیگر
سه راه برای اینکار وجود دارد:
- وارد کردن package.*
- وارد کردن package.classname
- استفاده از اسم کامل
استفاده از package.*
در این صورت تمام کلاس ها و اینترفیس های پکیج مورد نظر غیر از زیر پکیج ها در دسترس شما قرار میگیرن. از واژه import برای در دسترس قرار دادن این موارد استفاده می شود. به مثال زیر نگاه کنید:
ورودی:
//save by A.java package pack; public class A{ public void msg(){System.out.println("Hello");} }
//save by B.java package mypack; import pack.*; class B{ public static void main(String args[]){ A obj = new A(); obj.msg(); } }
خروجی:
Output:Hello
استفاده از package.classname
در این صورت تنها کلاس موردنظر وارد می شود.
ورودی:
/save by A.java package pack; public class A{ public void msg(){System.out.println("Hello");} }
//save by B.java package mypack; import pack.A; class B{ public static void main(String args[]){ A obj = new A(); obj.msg(); } }
خروجی:
Output:Hello
استفاده از نام کامل
در صورتی که از این روش استفاده کنید، تنها کلاسی که مشخص کردید در دسترس خواهد بود و هر موقع که با آن کلاس کار داشته باشید، مجبور به استفاده از نام کامل آن خواهید شد. این روش زمانی به کار گرفته می شود که دو پکیج دارای کلاس های هم نام باشند، برای مثال پکیج java.util و java.sql دارای کلاس Date می باشند.
ورودی:
//save by A.java package pack; public class A{ public void msg(){System.out.println("Hello");} }
//save by B.java package mypack; class B{ public static void main(String args[]){ pack.A obj = new pack.A();//using fully qualified name obj.msg(); } }
خروجی:
Hello
باز هم تکرار می کنیم که در صورت import کردن یک پکیج، کلاس و اینترفیس زیرپکیجها در دسترس نیستند و باید جداگانه فراخوانی شوند.
زیرپکیج در جاوا
به پکیجی که خود در داخل پکیجی دیگر باشد، زیرپکیج می گویند.
برای مثال در نظر بگیرید که شرکت سان یک پکیج به نام java ایجاد کرده است، با اینحال مجددا پکیج هایی به نام lang یا io را در پکیج جاوا ایجاد کرده است تا کلاسهای مختلفی را در آنها بسازد. برای مثال کلاس های Reader و Writer در پکیج io هستند و کلاس Socket در پکیج net. به مثال زیر دقت کنید:
ورودی:
package com.javatpoint.core; class Simple{ public static void main(String args[]){ System.out.println("Hello subpackage"); } }
کامپایل: javac -d . Simple.java |
اجرا: java com.javatpoint.core.Simple |
خروجی:
Hello subpackage
چگونه فایل کلاس را به یک دایرکتوری دیگر منتقل کنیم؟
در صورتی که بخواهید به عنوان مثال فایل کلاس، A.java را در فولدر classes در درایو C بریزید آنگاه به این ترتیب عمل می شود:
//save as Simple.java package mypack; public class Simple{ public static void main(String args[]){ System.out.println("Welcome to package"); } }
برای کامپایل:
e:\sources> javac -d c:\classes Simple.java
برای اجرا:
e:\sources> set classpath=c:\classes;.; |
e:\sources> java mypack.Simple |
راه دیگر اجرای این برنامه استفاده از سویچ classpath می باشد. از این سویچ برای نشان دادن مسیری که برای پیدا کردن فایل کلاس باید جستجو شود استفاده می شود. دقت کنید:
راه های لود فایل های کلاس یا jar
دو روش برای انجام اینکار به شکل دائمی و موقتی است:
موقتی:
- با استفاده از سویچ classpath
- با مشخص کردن classpath از طریق cmd
دائمی
- با مشخص کردن classpath در System Variables
- با ساختن فایل jar که شامل تمام فایل های کلاس می باشد و کپی کردن آن در فولدر jre/lib/ext
دقت کنید که تنها یک کلاس عمومی را می توان در فایل منبع جاوا نگه داشت و آنرا با همان نام کلاس باید ذخیره کرد. دقت کنید به مثال زیر:
//save as C.java otherwise Compilte Time Error class A{} class B{} public class C{}
چگونه دو کلاس عمومی را در یک پکیج قرار دهیم؟
اگر می خواهید دو کلاس عمومی را داشته باشید آنگاه دو فایل منبع جاوا دارای کلاس عمومی داشته باشید اما نام پکیج را تغییر ندهید. برای مثال:
//save as A.java package javatpoint; public class A{}
//save as B.java package javatpoint; public class B{}
تنظیم کنندگان سطح دسترسی یا Access modifiers در جاوا
به طور کلی دو نوع تنظیم کننده در جاوا وجود دارد، تنظیم کنندگان سطح دسترسی و آن دسته که به سطح دسترسی ارتباطی ندارند. تنظیم کنندگان سطح دسترسی محدوده یک متغیر، کلاس یا متد را مشخص میکند.
4 تنظیم کننده سطح دسترسی وجود دارد که عبارتند از:
- Public
- Private
- Default
- Protected
از تنظیم کنندگانی که به دسترسی مرتبط نیستند می توان به abstract، transient و static اشاره کرد.
Private
در صورتی که سطح دسترسی private تعریف شود، تنها در همان کلاس در دسترس است. به مثال زیر دقت کنید که با ارور موقع کامپایل مواجه می شویم:
class A{ private int data=40; private void msg(){System.out.println("Hello java");} } public class Simple{ public static void main(String args[]){ A obj=new A(); System.out.println(obj.data);//Compile Time Error obj.msg();//Compile Time Error } }
در صورتی که یک کانستراکتور یا سازنده جاوا را خصوصی تعریف کنیم، آنگاه نمی توانیم نمونه ای از آن کلاس ساخت، دقت کنید:
class A{ private A(){}//private constructor void msg(){System.out.println("Hello java");} } public class Simple{ public static void main(String args[]){ A obj=new A();//Compile Time Error } }
نکته ای که وجود دارد این است که نمی توان کلاس های غیر داخلی را به شکل protected و default تعریف کرد.
Default
در صورتی که از هیچ تنظیم کننده دسترسیای استفاده نشود، آنگاه default در نظر گرفته می شود.
به مثال زیر دقت کنید که از انجایی که کلاس به شکل عمومی تعریف نشده است، نمی توان از آن در خارج از پکیج استفاده کرد.
//save by A.java package pack; class A{ void msg(){System.out.println("Hello");} }
//save by B.java package mypack; import pack.*; class B{ public static void main(String args[]){ A obj = new A();//Compile Time Error obj.msg();//Compile Time Error } }
Protected
از این تنظیم کننده در صورتی استفاده می شود که بخواهیم در داخل یک پکیج و خارج از آن به شرط استفاده از وراثت استفاده کنیم. دقت کنید که از این تنظیم کننده نمی توان بر روی کلاس ها استفاده کرد.
به مثال زیر که مشابه مثال قبل می باشد دقت کنید. از آنجایی که وراثت استفاده شده است، امکان استفاده از متد msg از طریق وراثت وجود دارد.
//save by A.java package pack; public class A{ protected void msg(){System.out.println("Hello");} }
//save by B.java package mypack; import pack.*; class B extends A{ public static void main(String args[]){ B obj = new B(); obj.msg(); } }
خروجی:
Hello
Public
این تنظیم کننده باعث می شود که دسترسی از همه جا برقرار باشد و بازترین محدوده ممکن را دارد.
مثال:
//save by A.java package pack; public class A{ public void msg(){System.out.println("Hello");} }
//save by B.java package mypack; import pack.*; class B{ public static void main(String args[]){ A obj = new A(); obj.msg(); } }
خروجی:
Hello
در جدول زیر مقایسه سریع تمامی این access modifier ها رو می بینیم:
تنظیم کننده | در کلاس | در پکیج | خارج از پکیج توسط کلاس فرزند | خارج از پکیج |
Private | بله | خیر | خیر | خیر |
Default | بله | بله | خیر | خیر |
Protected | بله | بله | بله | خیر |
Public | بله | بله | بله | بله |
دقت کنید در صورتی که یک متد را اورراید (Override) کنید، آنگاه متد اورراید (Override) شده نمیتواند محدود تر باشد. به مثال زیر دقت کنید:
class A{ protected void msg(){System.out.println("Hello java");} } public class Simple extends A{ void msg(){System.out.println("Hello java");}//C.T.Error public static void main(String args[]){ Simple obj=new Simple(); obj.msg(); } }
در این مثال از آنجایی که default از protected محدودتر است، به ارور کامپایل برخورد می کنیم.