انجمن فرفره - اولین انجمن تخصصی نرم افزار های رایگان (Freeware) و متن باز (Open Source)

نسخه کامل: آموزش جاوا- جلسه‌ی ویژه
شما در حال مشاهده نسخه تکمیل نشده می باشید. مشاهده نسخه کامل با قالب بندی مناسب.
سلام!
ما زباد از جاوا صحبت کردیم ولی خیلی از جنبه ها را درست توضیح ندادیم و تعدادی دیگر از یادمون رفت توضیح بدیم! خب حالا وقتشه! (این یک بخش ویژه‌ است٬ به همراه منابعی است که برای مطالعه‌ی بیشتر لطفا به آنها مراجعه نمایید)
بخش اول : تفاوت ها با زبان سی / سی++ :
یکی زبان‌هایی که جاوا از آن تاثیر پذیرفته است زبان سی ++ است. 1 بسیاری از ساختار های این زبان سی++ گرفته شده ٬ حتی کلمات کلیدی استفاده شده. اما بالاخره تفاوت‌های بین آنها وجود دارد. یکی از این موارد شیوه‌ی تخصیص حافظه برای آرایه است.
به کد توجه بفرمایید:
    C++ Programming
  1. #include <iostream.h>
  2. #include <conio.h>
  3. void main(){
  4. int y[9];
  5. y[3]=10;
  6. cout<<y[3]<<endl;
  7. getch();
  8. }


خب یک آرایه به اندازه‌ی ۹ واحد ایجاد شده و بعد خانه‌ی شماره‌ی چهارم مقدار دهی و بعد چاپ شده ( توجه : شروع آرایه در سی++ و جاوا از صفر است). حال اگر همین بخش از کد را در جاوا مقایسه نماییم به این شکل در می‌آید:
    JAVA5 Programming
  1. public class ClassName { // در جاوا وجود یک کلاس که شمال متد اصلی (main باشد الزامی است.)
  2. public void main(String[]argv){ //تعریف متد اصلی
  3. int y[]=new int[9]; // یک متغیر آرایه‌ای با اندازه‌ دلخواه تعریف می نماییم.
  4. y[3]=10; // و خانه‌ی مورد نظر را مقدار دهی می‌نماییم.
  5. System.out.print(y[3]); //چاپ خانه‌ی دلخواهِ آرایه
  6. } // پایان متد اصلی
  7. } //پایان کلاس


مشاهده می‌نمایید که برای ایجاد آرایه نمی‌توان مستقیما در بخش تعریف متغیر اندازه وارد شود. ابتدا باید نوع سپس نام متغیر و بعد علامت آرایه یعنی [ ] آورده شود. بعد از علامت انتساب (یعنی = ) و سپس نوع متغیر و بعد اندازه‌ی آرایه آورده شود. می‌توان این برنامه را به صورت زیر هم نوشت :
    JAVA5 Programming
  1. public class ClassName {
  2. public void main(String[]argv){
  3. <span style="font-weight: bold;"> int []y;</span>
  4. <span style="font-weight: bold;">y=new int[9];</span>
  5. y[3]=10;
  6. System.out.print(y[3]);
  7. }
  8. }


در خط سه مشاهده می‌فرمایید که فقط نام و نوع متغیر به همراه علامت آرایه ذکر شده. در هنگام تعریف می توان علامت آرایه را در سمت راست یا چپ متغیر قرار داد. همچنین لزومی به مقدار دهی برای اندازه‌ی آرایه نیست و بعدا ٬ پیش از استفاده می‌توان آن را مقدار دهی نمود٬ مانند همین مثال.
این موضوع متبادر کننده‌ی شیوه‌ای مشابه در سی++ است چیزی شبیه این کد :
    C++ Programming
  1. int *a;
  2. a=new int[9];
  3. a[8]=10;
  4. cout<<a[8]<<endl;


ابتدا یک اشاره‌گر با نام a ایجاد شده و سپس اندازه تعیین می‌شود. به این روش تخصیص آرایه به روش پویا گفته می‌شود.
از این روش برای ایجاد آرایه‌هایی با دو یا چند بعد استفاده می‌شود. برای ایجاد یک ماتریس (آرایه‌ای دو بعدی ) به این روش عمل می‌نماییم:
    C++ Programming
  1. #include <iostream.h>
  2. #include <conio.h>
  3. void main(){
  4. int **a; //اشاره ‌گری به اشاره‌گری دیگر!
  5. a=new int *[10]; //اشاره به مکانی از حافظه برای ایجاد ارایه از ۱۰ واحد
  6. for(int i=0;i<10;i++) // در طی یک حلقه‌ی ۱۰تایی هر یک از ۱۰ خانه‌ی آرایه به عنوان اشاره‌گری به آرایه ۸ واحدی //استفاده می شود.
  7. a[i]=new int[8];
  8. for(int i=0;i<10;i++)
  9. for(int j=0;j<8;j++)
  10. a[i][j]=i*j; //مقداردهی ماتریس!
  11. for(int i=0;i<10;i++)
  12. { //چاپ ماتریس
  13. for(int j=0;j<8;j++)
  14. cout<<a[i][j]<<"\t";
  15. cout<<endl;
  16. }
  17. getch();
  18. }


نکته‌ی جالب در سی++ آن است که شما می توانید برای هر یک از سطرها اندازه‌ی تفاوت قایل شوید(اگرجه در اینجا همه اندازه مساوی ۸ دارند.)
همین قطعه کد در جاوا به صورت :
    JAVA5 Programming
  1. public class Matrix {
  2. private int a[][];
  3. int width,h;
  4. Matrix(int w,int h){
  5. width=w;
  6. this.h=h;
  7. }
  8. public void init(){
  9. a = new int[width][h];
  10. for(int i=0;i<width;i++)
  11. for(int j=0;j<h;j++)
  12. a[i][j]=i*j;
  13. }
  14. public void Print(){
  15. for(int i=0;i<width;i++)
  16. {
  17. for(int j=0;j<h;j++)
  18. System.out.print(a[i][j]+"\t");
  19. System.out.print("\n");
  20. }
  21. }
  22. public static void main(String[]argv){
  23. Matrix m=new Matrix(10,4);
  24. m.init();
  25. m.Print();
  26. }
  27. }


البته طولانی شدن برنامه به خاطر پیروی (کمی بیشتر !) از اصول شی‌گرایی است!
خط دوم ایجاد یک متغیر برای ایجاد ماتریس است.
خط سوم دو متغیر کلاس برای اندازه‌ی طول و عرض ماتریس است که از طریق متد سازنده (خط چهارم )مقدار دهی می‌شود.
در متد مقدار دهی مشاهده می نمایید که ماتریس به راحتی ایجاد می شود! فقط قرار دادن اعداد در نمادها آرایه!
و باقی کد هم شامل مقداردهی عددی و چاپ آن‌هاست.

شاید این سوال پیش آید که تفاوت شیوه‌ی پویا در سی++ و شیوه‌ی معمولی در جاوا در همان علامت * پیش از نام متغیر است؟
جواب خیر است. در اینجا باید به یکی از مهمترین تفاوت‌های بین سی++ و جاوا اشاره نماییم-------> اشاره گر!
در زبان سی برای تخصیص حافظه و ارسالبه توابع و متدها از اشاره‌گر و ارجاع استفاده می شود. منظور از اشاره را می‌توانید در اینجا و اینجا مشاهده کنید و با آن بیشتر آشنا شوید.
در در زبان سی++ شما می‌توانید این اشاره‌گر را به هرکجا خواستید اشاره بدهید و همین طور پیش بروید! مشکل از زمانی شروع می‌شود که کنترل اشاره گر را در برنامه به هر نحوی ( مثلا در یک حلقه که به اشتباه مقدار دهی شده و می‌خواهید در جایی که متعلق به برنامه‌ی شما نیست اطلاعاتی بنویسید یا بخوانید) از دست شما خارح شود! یاد کابوس های بورلند بخیر!
در جاوا این موضوع با استفاده از درست از اشاره‌گر حل شده. در واقع شما به همان شکل سی++ آرایه ایجاد می‌نمایید ولی شما دیگر به صورت صریح از اشاره‌گر استفاده نمی‌نمایید بلکه برنامه‌ خودش این کار را برای شما انجام می‌دهد و دیگر شما را از مشکلات سی++ رها می کند.
lموضوع دیگر ارسال‌هاست. زمانی که شما یک تابع را فرخوانی می نمایید باید به نوعی داده‌ی مورد نظر خود را به آن ارسال نمود. چند راه برای این کار وجود دارد:
* ارسال با استفاده از مقدار
* ارسال با استفاده از ارجاع
* ارسال با استفاده از اشاره‌گر
از آنجا که اختیار استفاده از اشاره‌گر را در جاوا نداریم٬ آخرین موضوع در جاوا بی‌معنی است. از این رو فقط دو مورد باقی می‌ماند. اما یک سوال آیا می توان متد تغییر دو متغیر را در جاوا با استفاده از ارجاع (Reference) اجرایی کرد؟ به کد زیر توجه بفرمایید :
    JAVA5 Programming
  1. void swap(int & arg1, int & arg2) {
  2. int temp = arg1;
  3. arg1 = arg2;
  4. arg2 = temp;
  5. }
  6. int var1 = ...; // مقدار "الف"
  7. intvar2 = ...; // مقدار "ب"
  8. swap(var1, var2); // جابجایی مقادیر آنها!


این یک کد در سی++ است. آیا امکان اجرایی در جاوا دارد؟
جواب خیر است. ارسال در این تابع به صورت "Passing by Reference" صورت گرفته است. و مقادیر در داخل تابع با یکدیگر عوض شده‌اند.
در جاوا شما نمی‌توانید این کار را انجام دهید! ارسال در جاوا به صورت Passing by Value است! حتی reference ها!
راه حل : شی‌گرایی است..

خب آخرین موضوع جالب مقدادهی متغیرهای کلاس است!
فرض کنید در همین ماتریس که در بالا ذکر شد می خواهیم مقدار دهی اولیه داشته باشیم. چند راه وجود دارد.
یکی اینکه در متد سازنده یا متدی مشابه (در همین مثال از متد مقداردهی init ) استفاده شود.
راه دیگر و جالب تر استفاده از بلوکی به نام استاتیک است به این قطعه کد نگاه کنید :
    JAVA5 Programming
  1. static int width,h;
  2. static {
  3. width=10;
  4. h=6;
  5. }


تنها مورد آن است که متغیرها باید به شکل استاتیک تعریف شده باشند. منظور از استاتیک آن است که این متغیرها به عنوان بخشی از شی‌ِ کلاسی هستند! در این مورد در جلسات بعد صحبت خواهیم نمود!

لطفا نظرات خود را به صورت پیغام برای نویسنده ارسال نمایید. و در صورتی که موضوع خاصی در جاوا برای یادگیری مد نظر دارید٬ بفرمایید تا در اولویتِ بالاتر قرار گیرد.
با عرض سلام وخسته نباشيد و سپاس فراوان از آموزشهای مفيدتون.
اگر توضيح مختصری راجع به استفاده ازاشاره گر this كه در خط ششم كد مربوط به آرايه های دوبعدی انجام شد بدين ممنون ميشم.
در واقع منطورم توضيحی راجع به نحوه ی استفاده از this در جاواست.
بازم ممنون.
(۱۳۸۹/۷/۹ ۰۳:۱۳ صبح)mozhgan نوشته شده توسط: [ -> ]اگر توضيح مختصری راجع به استفاده ازاشاره گر this كه در خط ششم كد مربوط به آرايه های دوبعدی انجام شد بدين ممنون ميشم.
در واقع منطورم توضيحی راجع به نحوه ی استفاده از this در جاواست.
خب ٬ ابتدا بیایید ببنیم this در زبان‌های دیگر به چه صورت است. در زبان سی++٬ این کلمه‌یِ کلیدی یک اشاره‌گر است.(برای اطلاع بیشتر به اینجا و اینجا).
هنگامی که از this به شکل بالا استفاده می‌کنیم میتوانیم (برایِ همین مثال) چنین چیزی را مشاهده کنیم.
[تصویر: thisp.png?psid=1]
یعنی this به متدها و متغیرهای این شی از کلاس ارجاع (reference ) می‌دهد. ما می‌توانیم از این کلمه‌یِ کلید در داخل سازنده و متد‌های مربوط به کلاس برای اشاره به آنچه در این کلاس تعریف شده استفاده کنیم.
نمی‌توان از این کلمه٬ this ٬ برای اشاره به اجزا کلاس در متد اصلی (main) یا ارجاع به این کلاس در سایر کلاس‌ها استفاده نماییم.

کاربردهای که this دارد می‌تواند کاربردی ساده٬ مثل همین مثال ٬ باشد. در اینجا چون یک متغیر کلاسی به نام h وجود دارد و سازنده نیز دارای یک متغیر ارسال شده با نام h است. برای آنکه میان این دو تقاوت وجود داشته باشد با نمایش this.h مشخص می‌شود که عمل انتساب به صورت ِ انتسابِhِ ِارسال شده به سازنده به h مربوط به کلاس است.
یکی دیگر از کاربردهای this ٬ ارجاع به نمونه‌ای از کلاس است. مثلا در اینجا اگر داشته باشیم :
کد:
public class Matrix {
    private int a[][];
    static int width,h;
    static {
        width=10;
        h=6;
    }
    
    Matrix(int w,int h){
        width=w;
        Matrix.h=h;
    }
    public void init(){
        a = new int[width][h];
        for(int i=0;i<width;i++)
            for(int j=0;j<h;j++)
                a[i][j]=i*j;
    }
    public void Print(){
        for(int i=0;i<width;i++)
        {
            for(int j=0;j<h;j++)
                System.out.print(a[i][j]+"\t");
            System.out.print("\n");
        }
    }
    
  [b]  public Matrix me(){
        return this;
    }[/b]
    public static void main(String[]argv){
        Matrix m=new Matrix(10,4);
        m.init();
        m.Print();
    }

}
 
قسمتی از کد که تدرشت شده٬ نشان می دهد که متدی به نام me مقداری بازگشتی از نوع ماتریس داشته و خود این شی را برمی‌گرداند.
لازم به ذکر است که همانطور مه در بالا٬ متد سازنده٬ مشاهده می‌شود٬ نمی‌توان از this برای ارجاع به متغیرهای استاتیک استفاده نمود.
باسلام
از آموزش های شما ممنونم
امکان داره در باره ی
swing,awt,....
با مثالهای بیشتری توضیح بدید.
پیشتر از لطف شماکمال تشکررادارم.
سربلندباشید.
سلام من جاوا بلد نیستم ولی همین طوری داشتم نگاه می کردم خیلی شبیه به C و PHP اگر اینه که خیلی زود می تونم یادش بگیرم چون اون دوتارو بلدم.
فقط همینه ؟
(۱۳۸۹/۷/۸ ۱۰:۳۱ عصر)ehsan نوشته شده توسط: [ -> ]ارسال در جاوا به صورت Passing by Value است! حتی reference ها!
راه حل : شی‌گرایی است..

خب آخرین موضوع جالب مقدادهی متغیرهای کلاس است!
.
.
.
تنها مورد آن است که متغیرها باید به شکل استاتیک تعریف شده باشند. منظور از استاتیک آن است که این متغیرها به عنوان بخشی از شی‌ِ کلاسی هستند! در این مورد در جلسات بعد صحبت خواهیم نمود!
با عرض سلام و خسته نباشید.
ضمن اینکه میخواستم عرض کنم ما مشتاقانه منتظر جلسه ی آینده ای که قولش رو دادید هستیم خواهش دارم راجع به اینکه فرمودید: ارسال در جاوا به صورت Passing by Value است! حتی reference ها! و راه حلش رو شی گرایی معرفی کردید هم توضیح بدید.
ممنون.
برنامه اشکال داره!!!
کلاس Matrix هم باید static معرفی بشه وگرنه وقتی تو متد Main می خوایم یه Object بسازیم ازش این Error رو می ده:
Inner classes cannot have static declaration
non-static variable this cannot be refrenced from a static contex
لینک مرجع