سرفصل‌های آموزشی
آموزش جاوا
آشنایی با کلیدواژۀ static و کاربردهای آن در قالب پروژۀ  ثبت‌نام متقاضیان در باشگاه در زبان جاوا

آشنایی با کلیدواژۀ static و کاربردهای آن در قالب پروژۀ ثبت‌نام متقاضیان در باشگاه در زبان جاوا

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

استفاده از کلیدواژۀ static جهت تعریف متغیرها

استفاده از کیورد static پیش از نام متغیر مد نظر منجر بدین می‌گردد تا مقدار منتسب به آن متغیر صرفاً یک مرتبه مقداردهی شود بدین معنی که تنها یک مکان از حافظه به چنین متغیرهایی اختصاص داده می‌شود و از همین روی در سایر نقاط برنامه نمی‌توان متغیر مذکور را مجدداً مقداردهی کرد بلکه اجرای یکسری دستورات مرتبط با این متغیر منجر به تغییر مقدار منتسب به آن می‌گردد.

به منظور درک بهتر مفهوم کیورد static در تعریف متغیرها، ابتدا سناریویی تعریف می‌کنیم و در آن فرض می‌کنیم که در یک باشگاه بدنسازی یا ایروبیک تمرین می‌کنیم و قصد داریم تا برنامه‌ای برای این باشگاه طراحی کنیم تا وظیفۀ ثبت اطلاعات مربوط به ورزشکارانی که در آن ثبت‌نام می‌کنند را بر عهده داشته باشد. برای این منظور، یک پروژۀ جدید در محیط اکلیپس تحت عنوان SportClub ایجاد کرده و کلاسی به نام Athlete در آن می‌سازیم (به خاطر داشته باشیم که در حین ساخت این کلاس نیاز نیست تا تیک گزینۀ public static void main را بزنیم.) به طوری که در ابتدا کدی به صورت خواهیم داشت:

public class Athlete {

}

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

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    int registrationNumber;
}

همان‌طور که ملاحظه می‌شود، در کد فوق دو آبجکت از روی کلاس String تحت عناوین name و lastName ایجاد کرده سپس با استفاده از دیتا تایپ int دو متغیر دیگر به نام‌های dateOfBirth و registrationNumber تعریف کرده‌ایم.

پیش‌تر گفتیم در صورتی که یک ورزشکار جدید در باشگاه ثبت‌نام کند، مسلماً دارای نام، نام خانوادگی و تاریخ تولد مختص به خود است اما شمارۀ عضویت ایشان به هیچ وجه تحت کنترل وی نبوده و به طور مثال نمی‌تواند برای خود شمارۀ عضویت 7 را در نظر بگیرد. همچنین به منظور ثبت اطلاعات هر یک از ورزشکاران نیاز به ساخت آبجکتی جدید از روی این کلاس به ازای هر فرد داریم تا بدین ترتیب مقادیری به هر یک از متغیرهای dateOfBirth ،lastName ،name و registrationNumber اختصاص داده شده و در حافظۀ سیستم ذخیره شوند. 

با توجه به اینکه شمارۀ عضویت ورزشکاران تحت کنترل ایشان نبوده بلکه به صورت خودکار شماره‌ای منحصربه‌فرد به ایشان اختصاص داده می‌شود، از همین روی به منظور اِعمال چنین محدودیتی روی متغیر registrationNumber آن را از جنس متغیری استاتیک تعریف می‌کنیم بدین صورت که کلیدواژۀ static را پیش از نام متغیر مذکور قرار داده و آن را متغیری با مقدار اولیه‌ای ثابت تعریف می‌کنیم تا بدین ترتیب مقدار متغیر registrationNumber در همهٔ آبجکت‌های ساخته‌شده از روی کلاس متناظرش ثابت باشد. بنابراین در ساخت آبجکت از روی کلاس Athlete نمی‌توان مقداری را برای متغیر مذکور در نظر گرفت بلکه مقدار اختصاص‌یافته به آن در نتیجۀ اجرای دستورات تعریف‌شده در برنامه تعیین شده و به عنوان شمارۀ عضویت منحصربه‌فرد هر کاربر در نظر گرفته می‌شود (چنین متغیرهایی در زبان برنامه‌نویسی جاوا به اصطلاح Static Field نیز نامیده می‌شوند.) حال برای تعریف متغیر registrationNumber به صورت استاتیک کد فوق را به روش زیر تکمیل می‌کنیم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber;
}

همان‌طور که در کد فوق ملاحظه می‌کنیم، پیش از کلیدواژۀ int کیورد static را نوشته‌ایم و در ادامه مقدار اولیه‌ای به این متغیر اختصاص می‌دهیم تا در صورت ثبت‌نام افراد در باشگاه مقدار منتسب به این متغیر افزایش یافته و به هر یک از ایشان شمارۀ عضویتی منحصربه‌فرد اختصاص داده شود. بنابراین در کد زیر مقدار اولیۀ  متغیر registrationNumber را برابر با عدد 0 قرار می‌دهیم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber = 0;
}

در کد فوق، مقدار اولیۀ منتسب به متغیر registrationNumber را برابر با 0 قرار دادیم چرا که در حال حاضر هیچ فردی در باشگاه ثبت‌نام نکرده است. در ادامه، نیاز به تعریف یک اصطلاحاً Constructor داریم تا بدین ترتیب بتوانیم متغیرهای تعریف‌شده در کد فوق را به نحوی مقداردهی نماییم تا در صورت ساخت آبجکتی از روی کلاس Athlete کانستراکتور کلاس فراخوانی شده و مقادیر مد نظر برای نام، نام خانوادگی و تاریخ تولد متقاضیان را به هر یک از متغیرهای فوق‌الذکر منتسب نموده و در ادامه نیز به صورت خودکار شمارۀ عضویتی منحصربه‌فرد برای ایشان اختصاص دهد (در آموزش‌ آشنایی با مفهوم Constructor در زبان برنامه‌نویسی جاوا به طور کامل به بررسی مفهوم کانستراکتور،‌ نحوۀ تعریف و همچنین کاربرد آن در تعریف کلاس‌ها پرداخته‌ایم.) بنابراین به صورت زیر کانستراکتوری برای کلاس Athlete تعریف می‌کنیم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber = 0;
    public Athlete(String nameOfAthlete, String lastNameOfAthlete, int dateOfBirthOfAthlete) {
        name = nameOfAthlete;
        lastName = lastNameOfAthlete;
        dateOfBirth = dateOfBirthOfAthlete;
        registrationNumber++;
    }
}

در کد فوق، متدی هم‌نام با کلاس‌مان تحت عنوان ()Athlete تعریف کرده‌ایم که به منزلۀ کانستراکتور این کلاس می‌باشد و برای آن سه پارامتر ورودی تحت عناوین lastNameOfAthlete ،nameOfAthlete و dateOfBirthOfAthelte در نظر گرفته‌‌ایم و همان‌طور که می‌بینیم، برای تعریف دو پارامتر اول از کلاس String استفاده کرده و پارامتر سوم را با استفاده از دیتا تایپ int تعریف کرده‌ایم بدین معنی که مقادیر نام و نام خانوادگی مورد نظر برای هر ورزشکار می‌باید دیتایی از جنس استرینگ و تاریخ تولد وی نیز دیتایی از جنس عدد صحیح باشد.

در ادامه، داخل کانستراکتور تعریف‌شده برای این کلاس هر یک از پارامترهای ورودی را به متغیرهای تعریف‌شدۀ متناظرشان در کلاس Athlete منتسب کرده‌ایم که بدین ترتیب می‌توانیم در صورت ساخت آبجکتی از روی کلاس Athlete مقادیر مربوط به نام، نام خانوادگی و تاریخ تولد هر متقاضی را به عنوان دیتای ورودی برای آبجکت مد نظر تعریف نماییم که در چنین شرایطی کانستراکتور کلاس فراخوانی شده و مقادیر تعریف‌شده برای نام، نام خانوادگی و تاریخ تولد هر یک از ورزشکاران که در متغیرهای lastNameOfAthlete ،nameOfAthlete و dateOfBirthOfAthlete ذخیره شده‌اند را به ترتیب به متغیرهای lastName ،name و dateOfBirth اختصاص می‌دهد و در دستور سطر دهم گفته‌ایم که در هر بار ساخت آبجکتی جدید از روی این کلاس، یک واحد به مقدار اولیۀ متغیر registrationNumber اضافه شود و بدین ترتیب آخرین مقدار منتسب به این متغیر به عنوان شمارۀ عضویت متقاضیِ جدید در نظر گرفته می‌شود.

در ادامه، نیاز داریم تا متدی تعریف کنیم که با ساخت آبجکت از روی کلاس Athlete و ثبت اطلاعات مربوط به نام، نام خانوادگی، تاریخ تولد و شمارۀ عضویت هر متقاضی به متد مورد نظر دسترسی داشته و آن را فراخوانی کنیم تا اطلاعات هر یک از ورزشکاران که به متغیرهای dateOfBirth ،lastName ،name و registrationNumber منتسب شده را در کنسول چاپ نماید که برای این منظور کد فوق را به صورت زیر تکمیل می‌کنیم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber = 0;
    public Athlete(String nameOfAthlete, String lastNameOfAthlete, int dateOfBirthOfAthlete) {
        name = nameOfAthlete;
        lastName = lastNameOfAthlete;
        dateOfBirth = dateOfBirthOfAthlete;
        registrationNumber++;
    }
    public void showAthleteInfo() {
        System.out.println("Your name is " + name);
        System.out.println("Your last name is " + lastName);
        System.out.println("Your date of birth is " + dateOfBirth);
        System.out.println("Your registration No is " + registrationNumber);
    }
}

در کد فوق، متدی به نام ()showAthleteInfo از جنس void تعریف کرده‌ایم و دلیل تعریف آن به صورت void این است که متد مذکور قرار نیست تا دیتایی را در خروجی ریترن کند بلکه صرفاً یکسری مقادیر را در کنسول چاپ می‌نماید. بنابراین دستورات داخلی این متد را بدین صورت تعریف کرده‌ایم تا در هنگام فراخوانی با استفاده از متد ()println به ترتیب مقادیر منتسب به هر یک از متغیرهای dateOfBirth ،lastName ،name و registrationNumber را به همراه استرینگ متناظرشان در کنسول چاپ کند.

تا به این مرحله، سناریوی مطرح‌شده در این آموزش را به نحوی پیاده‌سازی نمودیم که با ساخت آبجکت از روی کلاس می‌توانیم داده‌های مربوط به اطلاعات ورزشکاران را به عنوان دیتای ورودی به آن پاس دهیم و در ادامه کانستراکتور تعریف‌شده در این کلاس فراخوانی شده و هر یک از مقادیر پاس داده‌شده به آبجکت جدید را به ترتیب به متغیرهای lastName ،name و dateOfBirth اختصاص می‌دهد به علاوه اینکه در هر بار ساخت آبجکت از روی این کلاس نیز مقدار registrationNumber یک واحد افزایش یافته و به عنوان شمارۀ عضویتی منحصربه‌فرد برای هر یک از ورزشکاران در نظر گرفته می‌شود.

حال در ادامه قصد داریم تا نحوۀ ساخت آبجکت از روی کلاس Athlete و چگونگی پاس دادن مقادیر مورد نظر به عنوان اطلاعات هر فرد را به آن مورد بررسی قرار دهیم و ببینیم که چگونه می‌توان آبجکت‌های دیگری از روی این کلاس ساخت که برای این منظور نیاز است تا کلاس دیگری تعریف کنیم تا در آن آبجکتی از روی کلاس Athlete ساخته و مقادیر مربوط به اطلاعات هر فرد را به عنوان دیتای ورودی به آبجکت مذکور بدهیم و در ادامه متد تعریف‌شده در کلاس Athlete را روی آبجکت ساخته‌شده از روی این کلاس و در کلاس جدید فراخوانی کنیم تا اطلاعات هر فرد را در معرض دیدمان قرار دهد.

در همین راستا، داخل پروژۀ SportClub کلاس جدیدی به نام ActionClass می‌سازیم (توجه داشته باشیم که در حین ساخت کلاس حتماً می‌باید تیک گزینۀ public static void main را بزنیم چرا که قصد داریم تا این کلاس را به عنوان نقطۀ شروع برنامۀ خود قرار دهیم.) و پس از ساخت کلاس در ابتدا کدی به صورت زیر خواهیم داشت:

public class ActionClass {
    public static void main(String[] args) {
      
    }
}

اکنون داخل متد ()main می‌خواهیم یک آبجکت از روی کلاس Athlete ایجاد کنیم و برای این منظور کد فوق را به شکل زیر تکمیل می‌کنیم:

public class ActionClass {
	public static void main(String[] args) {
		Athlete personOne = new Athlete;
    }
}

همان‌طور که مشاهده می‌کنیم، برای ساخت آبجکتی جدید از روی کلاس Athlete ابتدا نام کلاس را نوشته سپس نامی دلخواه برای آبجکت مذکور در نظر می‌گیریم که در اینجا personOne را انتخاب کرده‌ایم سپس با استفاده از کیورد new و مجدداً ذکر نام کلاس آبجکتی جدید از روی کلاس Athlete ساخته و با استفاده از عملگر = آن را به personOne منتسب می‌نماییم. در این مرحله با اروری مبنی بر عدم تعریف مقادیر اولیه برای کانستراکتور کلاس Athlete مواجه می‌شویم بدین معنی که می‌باید مقابل نام کلاس در کد فوق علائم (‌‌ ) را قرار داده و داخل آن‌ها مقادیر مد نظر جهت اختصاص به هر یک از متغیرهای تعریف‌شده در کلاس Athlete را تعریف نماییم اما پیش از تعریف دیتای ورودی برای آبجکت personOne نشانگر ماوس خود را روی ارور مشخص‌شده قرار داده و به صورت هم‌زمان کلیدهای Ctrl + Space را فشار می‌دهیم و بدین ترتیب کدی همچون زیر خواهیم داشت:

Athlete personOne = new Athlete(String nameOfAthlete, String lastNameOfAthlete, int dateOfBirthOfAthlete)

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

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
    }
}

همان‌طور که در کد فوق مشاهده می‌کنیم، نام و نام خانوادگی ورزشکار اول را دیتایی از جنس استرینگ در نظر گرفته و مابین علائم " " به آبجکت personOne پاس داده‌ایم و سال تولد وی را نیز به عنوان دیتایی از جنس عدد صحیح معادل عدد 1362 به آبجکت مذکور داده‌ایم. اکنون نیاز داریم تا به متد تعریف‌شده در کلاس Athlete دسترسی پیدا کنیم تا بتوانیم آن را به منظور نمایش اطلاعات آبجکت personOne فراخوانی نماییم و برای این منظور کد فوق را به صورت زیر تکمیل می‌کنیم:

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
        personOne.showAthleteInfo();
    }
}

در کد فوق، ابتدا نام آبجکت را نوشته و در ادامه یک علامت . قرار داده سپس نام متد مد نظر را نوشته‌ایم و بدین ترتیب با اجرای برنامۀ فوق در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1

همان‌طور که می‌بینیم، دیتای ورودی به آبجکت personOne به عنوان اطلاعات ورزشکار اول در کنسول نمایش داده شده است. نکتۀ قابل‌توجه در ارتباط با شمارۀ عضویت ورزشکار بدین صورت می‌باشد که مقدار اولیۀ منتسب به متغیر registrationNumber برابر با عدد 0 بوده و از همین روی با ساخت آبجکت اول از روی کلاس Athlete (ثبت‌نام اولین کاربر) کانستراکتور این کلاس مقدار منتسب به متغیر مذکور را به عدد 1 افزایش می‌دهد. در ادامه، دو آبجکت دیگر از روی کلاس Athlete به صورت زیر می‌سازیم:

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
        personOne.showAthleteInfo();
        Athlete personTwo = new Athlete("Ahmad", "Sohrabi", 1346);
        personTwo.showAthleteInfo();
        Athlete personThree = new Athlete("Ramin", "Jafari", 1371);
        personThree.showAthleteInfo();
    }
}

در کد فوق، دو آبجکت جدید تحت عناوین personTwo و personThree از روی کلاس Athlete ساخته‌ و اطلاعات مربوط به نام، نام خانوادگی و سال تولد هر یک را تعریف کرده‌ایم و در ادامه مجدداً برنامه را اجرا می‌کنیم:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1
Your name is Ahmad
Your last name is Sohrabi
Your date of birth is 1346
Your registration No is 2
Your name is Ramin
Your last name is Jafari
Your date of birth is 1371
Your registration No is 3

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

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
        personOne.showAthleteInfo();
     // Athlete personTwo = new Athlete("Ahmad", "Sohrabi", 1346);
     // personTwo.showAthleteInfo();
        Athlete personThree = new Athlete("Ramin", "Jafari", 1371);
        personThree.showAthleteInfo();
    }
}

حال پس از حذف آبجکت personTwo به همراه اطلاعات تعریف‌شده برای این آبجکت، مجدداً برنامه را اجرا می‌کنیم و در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1
Your name is Ramin
Your last name is Jafari
Your date of birth is 1371
Your registration No is 2

همان‌طور که ملاحظه می‌کنیم، اطلاعات مربوط به دو آبجکت personOne و personThree به نمایش درآمده اما این در حالی است که شمارۀ عضویت مربوط به آبجکت personThree به صورت خودکار یک واحد کاهش یافته است چرا که با اجرای مجدد برنامه اکنون دو آبجکت جدید تحت عناوین personOne و personThree از روی کلاس Athlete ساخته‌ایم و بدین ترتیب شمارۀ عضویت 1 به آبجکت personOne و شمارۀ عضویت 2 به آبجکت personThree اختصاص یافته است.

حال فرض می‌کنیم که 100 نفر از قبل در این باشگاه فرضی حضور داشته‌اند و می‌خواهیم تا شمارۀ عضویت نفرات جدید ثبت‌نامی بر اساس شمارۀ عضویت افراد پیشین اختصاص داده شود و بدین ترتیب به اولین فرد ثبت‌نامیِ جدید شماره‌ای معادل عدد 101 اختصاص داده می‌شود. بنابراین نیاز است تا مقدار اولیۀ منتسب به متغیر registrationNumber را به عدد 100 تغییر دهیم و برای این منظور کد مربوط به کلاس Athlete را به صورت زیر بازنویسی می‌نماییم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber = 100;
    public Athlete(String nameOfAthlete, String lastNameOfAthlete,
    int dateOfBirthOfAthlete) {
        name = nameOfAthlete;
        lastName = lastNameOfAthlete;
        dateOfBirth = dateOfBirthOfAthlete;
        registrationNumber++;
    }
    public void showAthleteInfo() {
        System.out.println("Your name is " + name);
        System.out.println("Your last name is " + lastName);
        System.out.println("Your date of birth is " + dateOfBirth);
        System.out.println("Your registration No is " + registrationNumber);
    }
    public static int showAllAthletes() {
        return registrationNumber;
    }
}

اکنون کامنت‌های مربوط به کلاس ActionClass را حذف کرده و مجدداً برنامه را اجرا می‌کنیم که در چنین شرایطی در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 101
Your name is Ahmad
Your last name is Sohrabi
Your date of birth is 1346
Your registration No is 102
Your name is Ramin
Your last name is Jafari
Your date of birth is 1371
Your registration No is 103

همان‌طور که می‌بینیم، به دلیل استاتیک بودن متغیر registrationNumber هر گونه تغییری که در آن ایجاد کنیم در کلیۀ آبجکت‌های ساخته‌شده از روی آن کلاس نیز اِعمال می‌گردد. 

استفاده از کیورد static به منظور تعریف متدها

کیورد static در زبان برنامه‌نویسی جاوا به منظور تعریف متدها نیز مورد استفاده قرار می‌گیرد که برای درک بهتر کاربرد این کیورد در تعریف متدها مجدداً به کلاس Athlete بازگشته و در آن متدی از جنس استاتیک تعریف می‌کنیم تا تعداد کل افرادی که در باشگاه ثبت‌نام نموده‌اند (آخرین مقدار منتسب به متغیر registrationNumber) را در خروجی ریترن کند که برای این منظور کد مربوط به این کلاس را به صورت زیر تکمیل می‌نماییم:

public class Athlete {
    String name;
    String lastName;
    int dateOfBirth;
    static int registrationNumber = 0;
    public Athlete(String nameOfAthlete, String lastNameOfAthlete,
    int dateOfBirthOfAthlete) {
        name = nameOfAthlete;
        lastName = lastNameOfAthlete;
        dateOfBirth = dateOfBirthOfAthlete;
        registrationNumber++;
    }
    public void showAthleteInfo() {
        System.out.println("Your name is " + name);
        System.out.println("Your last name is " + lastName);
        System.out.println("Your date of birth is " + dateOfBirth);
        System.out.println("Your registration No is " + registrationNumber);
    }
    public static int showAllAthletes() {
        return registrationNumber;
    }
}

در سطر نوزدهم از کد فوق، اقدام به تعریف متدی جدید تحت عنوان ()showAllAtheltes از جنس int نموده‌ایم چرا که قرار است تا این متد دیتایی از جنس عدد صحیح را در خروجی ریترن کند و از همین روی در تعریف آن به جای کیورد void از کیورد int استفاده کرده‌ایم به علاوه اینکه دستور return را در دستورات داخلی آن به منظور ریترن کردن مقدار مورد نظر نوشته و در ادامه نام متغیری را می‌نویسیم که قصد داریم تا مقدار منتسب به آن در خروجی بازگردانده شود. بنابراین در کد فوق داخل دستورات متد ()showAllAtheltes دستور return و در مقابل آن نیز نام متغیر registrationNumber را درج نموده‌ایم.

اکنون مجدداً به کلاس ActionClass باز می‌گردیم و قصد داریم تا آبجکتی از روی کلاس Athlete در این کلاس ساخته و در ادامه متدهای تعریف‌شده در کلاس مذکور همچون ()showAthleteInfo و ()showAllAtheltes را فراخوانی کنیم تا ابتدا اطلاعاتی را به عنوان ورودی برای هر یک از ورزشکاران تعریف کرده و در ادامه اطلاعات ثبت‌شده و همچنین تعداد افرادی که در باشگاه ثبت‌نام کرده‌اند را در کنسول چاپ نماییم. بنابراین کد مربوط به کلاس ActionClass را به صورت زیر تکمیل می‌کنیم:

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
        personOne.showAthleteInfo();
        Athlete personTwo = new Athlete("Ahmad", "Sohrabi", 1346);
        personTwo.showAthleteInfo();
        Athlete personThree = new Athlete("Ramin", "Jafari", 1371);
        personThree.showAthleteInfo();
        System.out.println("The number of all registrations is " + personOne.showAllAthletes());
    }
}

در کد فوق، ابتدا سه آبجکت از روی کلاس Athlete ساخته و دیتای مربوط به اطلاعات هر یک را به عنوان ورودی به آن‌ها داده‌ایم و متد ()showAthleteInfo را به ازای هر یک از آبجکت‌ها فراخوانی کرده‌ایم تا اطلاعات افراد به همراه استرینگ مربوطه در کنسول نمایش داده شوند و در نهایت هم با استفاده از متد ()println قصد داریم تا نتیجۀ حاصل از فراخوانی متد ()showAllAthletes روی آبجکت personOne را با به‌کارگیری عملگر + با استرینگ «The number of all registrations is» کانکت کرده و در کنسول نمایش دهیم. 

در واقع، نحوۀ عملکرد متد ()showAllAthletes بدین صورت است که از جنس استاتیک بوده و به آخرین مقدار منتسب به متغیر استاتیکِ registrationNumber مابین تمامی آبجکت‌های ساخته‌شده از روی کلاس مربوطه دسترسی داشته و آن را در خروجی ریترن می‌کند. حال با اجرای برنامۀ فوق در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1
Your name is Ahmad
Your last name is Sohrabi
Your date of birth is 1346
Your registration No is 2
Your name is Ramin
Your last name is Jafari
Your date of birth is 1371
Your registration No is 3
The number of all registrations is 3

همان‌طور که می‌بینیم، تعداد کل افرادی که ثبت‌نام کرده‌اند معادل عدد 3 در کنسول چاپ شده است. در واقع، متد ()showAllAthletes روی آبجکت personOne فراخوانی شده و انتظار داشتیم که مقدار منتسب به متغیر registrationNumber از این آبجکت معادل عدد 1 در کنسول نمایش داده شود اما این در حالی است که متد استاتیکِ ()showAllAthletes به جدیدترین مقدار منتسب به این متغیر در میان تمامی آبجکت‌ها دسترسی داشته و از همین روی مقداری معادل عدد 3 را در خروجی ریترن می‌کند. اکنون برای تست کردن بیشتر برنامه، کد مربوط به سطر نهم را به صورت زیر تغییر می‌دهیم:

System.out.println("The number of all registrations is " + personTwo.showAllAthletes());

در دستور فوق، متد ()showAllAthletes را روی آبجکت personTwo فراخوانی نموده‌ایم و با اجرای مجدد برنامه در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1
Your name is Ahmad
Your last name is Sohrabi
Your date of birth is 1346
Your registration No is 2
Your name is Ramin
Your last name is Jafari
Your date of birth is 1371
Your registration No is 3
The number of all registrations is 3

همان‌طور که می‌بینیم، فراخوانی متد ()showAllAthletes روی آبجکت personTwo نیز منجر به ریترن شدن عدد 3 در خروجی شده است چرا که متد ()showAllAthletes از جنس استاتیک بوده و آخرین مقدار اختصاص‌یافته به متغیر registrationNumber در میان تمامی آبجکت‌ها را در خروجی ریترن می‌کند.

در واقع، با استفاده از کلیدواژۀ static برای تعریف متد ()showAllAthletes توانستیم تا این متد را در میان تمامی آبجکت‌ها اصطلاحاً Share کنیم. حال برای تست مجدد برنامۀ فوق، یکی از آبجکت‌های ساخته‌شده در کلاس ActionClass را به صورت زیر کامنت می‌کنیم:

public class ActionClass {
    public static void main(String[] args) {
        Athlete personOne = new Athlete("Behzad", "Moradi", 1362);
        personOne.showAthleteInfo();
        Athlete personTwo = new Athlete("Ahmad", "Sohrabi", 1346);
        personTwo.showAthleteInfo();
     // Athlete personThree = new Athlete("Ramin", "Jafari", 1371);
     // personThree.showAthleteInfo();
        System.out.println("The number of all registrations is " + personOne.showAllAthletes());
    }
}

پس از کامنت کردن آبجکت personThree در کد فوق، برنامه را مجدداً اجرا می‌کنیم و در خروجی خواهیم داشت:

Your name is Behzad
Your last name is Moradi
Your date of birth is 1362
Your registration No is 1
Your name is Ahmad
Your last name is Sohrabi
Your date of birth is 1346
Your registration No is 2
The number of all registrations is 2

همان‌طور که پیش‌تر توضیح دادیم، با اجرای برنامۀ فوق دو آبجکت تحت عناوین personOne و personTwo از روی کلاس Athlete ساخته شده و از همین روی مقادیر مربوط به شمارۀ عضویت هر یک به ترتیب برابر با اعداد 1 و 2 می‌باشد که در چنین شرایطی متد استاتیکِ ()showAllAthletes به مقادیر منتسب به هر دو آبجکت نیز دسترسی داشته و از همین روی آخرین مقدار اختصاص‌یافته به آن معادل عدد 2 را در خروجی ریترن می‌کند.

همچنین اگر توجه کرده باشیم، آی‌دی‌ای اکلیپس در تمامی دستورات مربوط به فراخوانی متد ()showAllAthletes هشداری در قالب عبارت زیر را ارائه می‌دهد:

The static method showAllAthletes() from the type Athlete should be accessed in a static way

در واقع، هشدار فوق حاکی از آن است که متدهای استاتیک تعریف‌شده در یک کلاس مرتبط با کل آن کلاس بوده و محدود به هر یک از آبجکت‌های ساخته‌شده از روی آن نمی‌باشند و همان‌طور که اشاره کردیم متد استاتیکِ ()showAllAthletes نیز مرتبط با کلاس Athlete بوده و به مقادیر منتسب به تمامی آبجکت‌های ساخته‌شده از روی آن دسترسی دارد بدین معنی که متد مذکور مرتبط با کل کلاس Athlete می‌باشد و از همین روی بهتر است تا متد مذکور را روی نام کلاس به صورت زیر فراخوانی نماییم:

System.out.println("The number of all registrations is " + Athlete.showAllAthletes());

با توجه به آنچه که در بالا بدان اشاره کردیم، بهتر است تا دستور فوق را جایگزین تمامی دستورات مربوط به فراخوانی متد استاتیکِ ()showAllAthletes روی تمامی آبجکت‌های ساخته‌شده از روی کلاس همچون آبجکت‌های personTwo ،personOne و personThree نماییم.

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

online-support-icon