معرفی کلید واژه final در زبان برنامه نویسی جاوا


پس از آشنایی با کلید واژه ی static در دو آموزش قبل، در این آموزش قصد داریم تا کلید واژه ی final را مورد بررسی قرار دهیم. به طور کلی می توان گفت که از کلید واژه final می توان در سه موقعیت متفاوت بهره مند شد:

- مورد اول استفاده از این کلید واژه برای کلاس ها است. در واقع زمانی که یک کلاس را final کنیم، دیگر امکان ایجاد Subclass از آن کلاس وجود نخواهد داشت. به عبارت دیگر، با استفاده از final به یکی از مهم ترین قابلیت های زبان برنامه نوسی جاوا که یک زبان شیء گرا است را از دست خواهیم داد و آن Inheritance است.

- مورد دوم استفاده از کلید واژه ی final به همراه متدها است. در واقع زمانی که یک متد final شود، دیگر به هیچ وجه امکان Override آن متد برای ما وجود نخواهد داشت. به عبارت دیگر نوع کاری که آن متد انجام می دهد را نمی توانیم تغییر دهیم.

- مورد سوم استفاده از کلید واژه final در ارتباط با Local Variable ها، Instance Variable ها و پارامترها است. در حقیقت زمانی که کلیدواژه ی final را در کنار یک متغیری بنویسیم که دارای مقدار اولیه است، مقدار اولیه آن متغیر نهایی شده و دیگر به هیچ وجه امکان اختصاص یک مقدار جدید به آن را نخواهیم داشت.

به منظور درک بهتر مطالب تئوری فوق، پروژه ای تحت عنوان Final ایجاد کرده و کلاسی در آن تحت عنوان WhatIsFinal به معنی "کلید واژه ی final چیست؟" ایجاد می کنیم. به خاطر داشته باشیم که در حین ساخت این کلاس گزینه public static void main را تیک نزنیم چرا که این کلاس به منزله کلاس اجرایی ما نخواهد بود:

public class WhatIsFinal {

}

در ادامه می بایست متدی در این کلاس ایجاد کنیم که وظیفه آن به نمایش در آوردن نام، نام خانوادگی و تاریخ تولد ما باشد. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

public class WhatIsFinal {
    public void showData() {
        String name = "Behzad";
        String lastName = "Moradi";
        int dateOfBirth = 1362;
        System.out.println(name + "\n" + lastName + "\n" + dateOfBirth);
    }
}

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

سپس به منظور نمایش دادن این اطلاعات روی صفحه مانیتور از دستور ;()System.out.println استفاده کرده به این صورت که اول name را نوشته سپس n\ را می نویسیم (کاری که این دستور انجام می دهد این است که ادامه اطلاعات را به خط بعد منتقل می کند.) به همین منوال مابقی اسامی را هم داخل دستور ;()System.out.println قرار می دهیم. در ادامه ی کدنویسی، کلاس دیگری تحت عنوان ActionClass به معنی "کلاس عملیاتی" ایجاد کرده و در حین ساخت آن گزینه public static void main را تیک دار می کنیم چرا که این کلاس قرار است به عنوان نقطه شروع برنامه ما باشد:

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

در این مرحله نیاز است تا آبجکتی از روی کلاس WhatIsFinal تحت عنوان objectOne به معنی "شیء اول" ایجاد کنیم و سپس با استفاده از آن شیء متد موجود در کلاس را فرا بخوانیم. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

public class ActionClass {
    public static void main(String[] args) {
        WhatIsFinal objectOne = new WhatIsFinal();
        objectOne.showData();
    }
}

اکنون در صورتی که برنامه خود را اجرا کنیم، با خروجی زیر مواجه خواهیم شد:

می بینیم که متد showData که وظیفه داشت اطلاعات ما را نشان دهد کار خود را به درستی انجام داد. حال نیاز است تا یک کلاس دیگر تحت عنوان Change به معنی "تغییر" ایجاد کنیم اما این در حالی است که این کلاس می بایست از کلاس WhatIsFinal ارث بری کند. برای این منظور کد خود را به شکل زیر تکمیل می کنیم (برای آشنایی بیشتر با مفهوم وراثت در زبان برنامه نویسی جاوا به آموزش های مرتبط قبلی مراجعه نمایید):

public class Change extends WhatIsFinal {

}

همان طور که قبلاً توضیح داده شد، به منظور ارث بری یک کلاس از کلاس دیگر در زبان برنامه نویسی جاوا می بایست پس از نام کلاس خود کلید واژه extends را نوشته سپس نام کلاسی را بنویسیم که می خواهیم از آن ارث بری کنیم. در ادامه کار خود نیاز داریم تا در کلاس Change متدی که قبلا ایجاد کرده بودیم را Override یا "رونویسی" کنیم. برای این منظور کد فوق را به شکل زیر تکمیل می کنیم:

public class Change extends WhatIsFinal {
    @Override
    public void showData() {
        String name = "Iman";
        String lastName = "Ahmadi";
        int dateOfBirth = 1364;
        System.out.println(name + "\n" + lastName + "\n" + dateOfBirth);
    }
}

برای رونویسی یک متد نیاز است تا ابتدا دستور Override@ را نوشته سپس نام متد خود را بنویسیم. تغییری که در این متد انجام داده ایم این است که مقادیر شیء ساخته شده از روی کلاس String و متغیر int را به مقادیر جدیدی تغییر داده ایم. مجدد به کلاس ActionClass بازگشته و یک آبجکت جدید از روی کلاس Change ایجاد می کنیم:

public class ActionClass {
    public static void main(String[] args) {
        WhatIsFinal objectOne = new WhatIsFinal();
        objectOne.showData();
        System.out.println();
        Change objectTwo = new Change();
        objectTwo.showData();
    }
}

می بینیم پس از آبجکت اولی که ساختیم دستور ;()System.out.println را نوشته ایم. در حقیقت این دستور هیچ تاثیری در روند اجرای برنامه ما نداشته و صرفا جهت خوانایی بیشتر خروجی برنامه اضافه شده است چرا که مابین خروجی آبجکت اول و خروجی آبجکت دوم یک خط فاصله ایجاد خواهد کرد. همان طور که آبجکت اول را از روی کلاس WhatIsFinal ایجاد کردیم، اکنون یک آبجکت جدید تحت عنوان objectTwo به معنی "شیء دوم" از روی کلاس Change ایجاد می کنیم. مجدد برنامه را اجرا می کنیم:

می بینیم که هر دو آبجکت ساخته شده در برنامه اجرا شده اند. اکنون می خواهیم تاثیر کلید واژه ی final را در روند اجرای برنامه تست کنیم. برای این منظور به کلاس WhatIsFinal بازگشته و آن را به صورت زیر تغییر می دهیم:

public class WhatIsFinal {
    public final void showData() {
        String name = "Behzad";
        String lastName = "Moradi";
        int dateOfBirth = 1362;
        System.out.println(name + "\n" + lastName + "\n" + dateOfBirth);
    }
}

در بخش نام متد، پس از کلید واژه ی public، کلید واژه ی final را نوشته ایم. به طور خلاصه final این معنی را می رساند که ما به هیچ وجه امکان ایجاد تغییری را در این متد نخواهیم داشت و به عبارت دیگر نمی توانیم این متد را Override کنیم. در واقع، به محض آن که فایل خود را Save کنیم، با تصویر زیر مواجه خواهیم شد:

همان طور که در تصویر فوق می بینیم، یک علامت ضربدر کنار نام کلاس Change قرار گرفته است و این بدان معنی است که این کلاس دارای مشکلی است. حال اگر به مرور کد خود بپردازیم می بینیم که دور نام متد showData یک نقطه چین قرار گرفته است که همین نقطه چین بخشی از کد ما که داری مشکل است را نشان می دهد. با قرار دادن نشانگر موس خود روی نقطه چین، با تصویر زیر مواجه خواهیم شد:

می بینیم که در این باکس زرد رنگ نوشته شده است که "ما نمی توانیم یک متد final که در کلاس WhatIsFinal قرار دارد را Override کنیم" و راه کاری هم که به ما پیشنهاد می شود این است که کلید واژه ی final را از کنار نام متد showData حذف کنیم که با انجام این کار مشکل برنامه ما هم رفع خواهد شد. اکنون اگر با وجود این ایراد در برنامه اقدام به اجرای آن نماییم با تصویر زیر رو به رو خواهیم شد:

در این پنجره اکلیپس به ما اخطار می دهد که در پروژه خود دارای مشکلی هستیم اما امکان ادامه کار را نیز باوجود این مشکل برای ما فراهم کرده است. در واقع با کلیک بر روی کلید Proceed، می توانیم برنامه ی خود را Compile کنیم که در این صورت اجرای برنامه ما به این شکل خواهد بود:

می بینیم که آبجکت ساخته شده ی اول به خوبی نمایش داده شده است اما آبجکت دوم ما که در آن یک متد final را Override کرده بودیم با مشکل مواجه شده است.

دانلود فایل‌های تمرین
لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
کاربر میهمان
کاربر میهمان
سلام
ببخشید فرقprivateوfinallدر چیه؟
اگر ماهر دورو استفاده کنیم امکان دسترسی بقیه کلاس ها از اون متوقف میشه
ممنون
yazdang33
yazdang33
سلام. private باعث میشه که متد یا فیلد یا کانستراکتور تو هیج جای برنامه قابل دسترسی نباشه مگر یک جا که اون هم کلاس خودش هست. برای مثال کلاس Math دارای کانستراکتور private هست یعنی شما نمیتونید این کانستراکتور رو در جاهای مختلف برنامه فراخوانی یا استفاده کنین مثلا برای شی ساختن از روی یک کلاس نیاز به متد کانستراکتور اون کلاس دارید ولی وقتی متد کانستراکتور private باشه پس نمیتونید از روی اون کلاس مثل همین کلاس Math شی بسازید و ازتون ارور میگیره.
ولی بحث final جداست. با قرار دادن کلیدواژه فاینال قبل از فیلد یا متغیر مورد نظر شما فقط میتوانید یک بار فیلدتان یا متغیرتان را برای همیشه مقداردهی کنید و دیگر در طول برنامه نمیتوانید این مقدار را تغییر دهید. برای مثال کلاس Math یک فیلد به نام PI برای ذخیره سازی عدد پی داره . این فیلد final هست. چرا این فیلد final هست. چون عدد پی 3.14 هست و چیزی به غیر از 3.14 که نیست پس میایم فاینال تعریفش میکنیم که دیگه مقدارش تغییر نکنه و تا ابد 3.14 بمونه.
روش نام گذاری فاینال ها هم تمام حروف به صورت بزرگ هستش.
امیدورام متوجه تفاوت private و final شده باشید.

در پاسخ به

yazdang33
yazdang33
موارد استفاده final در کلاس ها ، متد ها و متغیر ها هم در این آموزش که گفته شده. با دقت بخونید متوجه میشید.

در پاسخ به

کاربر میهمان
کاربر میهمان
سلام😃
میشه گفت final در جاوا، همون const در C یا define در php هستش؟
ممنون
کاربر میهمان
کاربر میهمان
سلام
ممنون از آموزش عالیتون امیدوارم که همیشه موفق باشید
فقط یه مشکل کوچیک تو بده کدهاییک هنوشتین هست و اونم اینه که به جای "n" نوشته شده "n" لطفا تصحیح کنید.
ادمین سایت
ادمین سایت
سلام و با تشکر از تذکر به جای شما
اصلاح گردید


با تشکر
ارادتمند
تیم سکان آکادمی

در پاسخ به