آموزش جاوا (فصل ۱۱)

آشنایی با متغیرهای Local و Field در زبان برنامه‌نویسی جاوا


در این آموزش قصد داریم تا متغیرهای Local و Field در زبان برنامه‌نویسی جاوا را معرفی کرده و به بررسی تفاوت‌های مابین آن‌ها بپردازیم. در واقع، متغیرهای لوکال داخل متدِ تعریف‌شده در کلاس ایجاد می‌شوند و صرفاً داخل همان متد در دسترس می‌باشند اما متغیرهای فیلد خارج از تمامی متدها در کلاس تعریف شده و با ساخت آبجکت از روی کلاس مربوطه می‌توان از طریق سایر نقاط برنامه به آن‌ها دسترسی داشت.

به منظور درک مفاهیم تئوری فوق، پروژه‌ای تحت عنوان LocalVariablesvsFields در محیط اکلیپس ایجاد کرده و کلاسی تحت عنوان Constructor در آن می‌سازیم که در ابتدا کدی به صورت زیر خواهیم داشت:

public class Constructor {

}

همان‌طور که در ابتدای آموزش اشاره کردیم، متغیرهای تعریف‌شدهِ داخل یک متد متغیرهای لوکال می‌باشند و فقط از داخل متد مربوطه می‌توان به آن‌ها دسترسی پیدا کرد که برای روشن شدن این مطلب، مثال زیر را مد نظر قرار می‌دهیم:

public class Constructor {
    public void testMethodOne() {
        int number;
    }
}

در کد فوق، متدی تحت عنوان ()testMethodOne تعریف کرده‌ و در آن با استفاده از دیتا تایپ int متغیری به نامnumber ایجاد کرده‌ایم. در حقیقت، متغیر number یک متغیر لوکال یا متغیر داخلی است که تنها از داخل متدِ ()testMethodOne می‌توان به آن دسترسی پیدا کرد. از سوی دیگر، اگر فرض کنیم که یک کلاس جدید ایجاد می‌کنیم تا از کلاس Constructor ارث‌بری کند، در چنین شرایطی صرفاً می‌توانیم به متد ()testMethodOneدسترسی داشته باشیم و نمی‌توانیم کنترل متغیر number در این متد را در دست بگیریم که برای درک بهتر این مطلب یک کلاس دیگر به نام ActionClass ایجاد می‌کنیم که از کلاس Constructor ارث‌بری می‌کند سپس آبجکتی از روی کلاس Constructor تحت عنوان objectOne می‌سازیم:

public class ActionClass extends Constructor {
    public static void main(String[] args) {
        Constructor objectOne = new Constructor();
    }
}

حال می‌خواهیم تا به متغیر number تعریف‌شدهِ در متد ()testMethodOne داخل کلاس Constructor دست پیدا کنیم که برای این منظور آبجکت objectOne را نوشته سپس یک علامت . قرار می‌دهیم و به محض درج علامت .نرم‌افزار اکلیپس به صورت خودکار نام مواردی را نمایش می‌دهد که برای این آبجکت قابل‌دسترسی هستند که از کلاسConstructor نیز صرفاً متد ()testMethodOne در دسترس می‌باشد و به هیچ وجه نام متغیر number در میان موارد مذکور نمایش داده نمی‌شود.

حال اگر بخواهیم تا متغیری را خارج از یک متد و در بدنهٔ کلاس تعریف کنیم، این متغیر به مثابۀ یک متغیر فیلد خواهد بود که از سایر بخش‌های برنامه نیز در دسترس می‌باشد که در ادامه به منظور درک بهتر تفاوت متغیرهای فیلد و لوکال، کد فوق را به صورت زیر بازنویسی می‌کنیم:

public class Constructor {
    int number;
    public void testMethodOne() {
    }
}

در کد فوق، خارج از متد ()testMethodOne در کلاس Constructor و با استفاده از دیتا تایپ int متغیری به نام number تعریف کرده‌ایم که این متغیر برای کلیۀ متدهای داخل کلاس مذکور قابل‌دسترسی می‌باشد. حال مجدداً به کلاس ActionClass بازگشته و این بار به محض درج علامت . پس از نام آبجکت ساخته‌شده از روی کلاسConstructor می‌بینیم که نرم‌افزار اکلیپس علاوه بر متد ()testMethodOne نام متغیر number از کلاسConstructor را نیز نمایش می‌دهد.

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

public class ActionClass extends Constructor {
    public static void main(String[] args) {
        Constructor objectOne = new Constructor();
        objectOne.number = 12;
        Constructor objectTwo = new Constructor();
        objectTwo.number = 20;
    }
}

همان‌طور که در کد فوق ملاحظه می‌کنیم، دو آبجکت تحت عناوین objectOne و objectTwo از روی کلاسConstructor ساخته‌ایم سپس از طریق آبجکت اول به متغیر فیلد number از کلاس ActionClass دسترسی پیدا کرده و مقدار آن را معادل با 12 قرار می‌دهیم و در ادامه از طریق آبجکت دوم نیز به فیلد مذکور دسترسی پیدا کرده و عدد 20 را بدان منتسب می‌کنیم.

همان‌طور که ملاحظه می‌کنیم، دو مقدار متفاوت را به یک متغیر منتسب کرده‌ایم که این موضوع منجر به بروز اروری نشده است چرا که هر آبجکت ساخته‌شدهِ از روی کلاس Constructor به طور مجزا مورد استفاده قرار گرفته‌ است و شاید به همین دلیل باشد که نام دیگر متغیرهای فیلد Instance Variables است که به منزلۀ متغیرهایی می‌باشند که در هر Instance یا «نمونه» از یک کلاس مورد استفاده قرار می‌گیرند. دانلود فایل‌های تمرین

آشنایی با مفهوم Constructor در زبان برنامه‌نویسی جاوا


به طور خلاصه می‌توان گفت که کانستراکتور به منزلۀ متدی در کلاس است که دقیقاً هم‌نام با کلاس مربوطه بوده با این تفاوت که هرگز دیتایی را در خروجی ریترن نمی‌کند؛ به علاوه اینکه کانستراکتور را می‌توان بدون پارامتری ورودی یا با پارامتری ورودی به تعداد دلخواه تعریف نمود (به منظور آشنایی با دستور return به آموزش‌ آشنایی با متدهایی با مقادیر برگشتی در زبان برنامه‌نویسی جاوا مراجعه نمایید.) 

در واقع، زمانی که آبجکتی از روی یک کلاس می‌سازیم، کانستراکتور آن کلاس فراخوانی شده و متغیرهای فیلد تعریف‌شدهِ در کلاس مربوطه را مقداردهی می‌کند. به علاوه، توجه داشته باشیم که برای ساخت آبجکتی جدید از روی یک کلاس نیاز به یک کانستراکتور داریم و در صورتی که کانستراکتوری برای کلاس تعریف نکنیم، خود کامپایلر به صورت خودکار و در حین ساخت آبجکت از روی کلاس مورد نظر کانستراکتوری فاقد پارامتر ورودی می‌سازد که تحت عنوان Default Constructor یا «کانستراکتور پیش‌فرض» شناخته می‌شود که در چنین شرایطی تمامی متغیرهای فیلد در کلاس مذکور با مقادیر پیش‌فرض مقداردهی می‌شوند به طوری که مقدار صفر برای متغیرهای تعریف‌شده با دیتا تایپ‌های int ،double و غیره در نظر گرفته می‌شود، مقدار false برای متغیرهای تعریف‌شده با دیتا تایپ boolean و در نهایت مقدار null برای آبجکت‌های ساخته‌شده از روی کلاس String اختصاص داده می‌شود. در عین حال، چنانچه کانستراکتوری برای کلاس خود بنویسیم، کامپایلر هیچ گونه کانستراکتور پیش‌فرضی به صورت خودکار برای کلاس مذکور نمی‌سازد. 

اکنون به منظور درک نحوۀ کار کانستراکتورها، پروژه‌ای تحت عنوان Constructor در آی‌دی‌ای اکلیپس ایجاد کرده و کلاسی به نام MyClass در آن می‌سازیم و در ادامه کد مربوط به این کلاس را به صورت زیر تکمیل می‌کنیم:

public class MyClass {
    String name;
    int age;
    boolean trueOrFalse;
    public void dispaly() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(trueOrFalse);
    }
}

در کد فوق، سه متغیر از جنسِ فیلد تحت عناوین age ،name و trueOrFalse تعریف کرده‌ایم که برای تعریف آن‌ها نیز به ترتیب از کلاس String، دیتا تایپ int و boolean استفاده نموده‌ایم و در ادامه متدی به نام ()displayساخته و در آن گفته‌ایم که در صورت فراخوانی، متغیرهای فیلد تعریف‌شده در داخل کلاس را در بخش کنسول چاپ نماید.

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

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

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

null
0
false

همان‌طور که مشاهده می‌کنیم، کامپایلر به صورت خودکار یک کانستراکتور پیش‌فرض برای آبجکت ساخته‌شده از روی کلاس MyClass ایجاد کرده و در ادامه کانستراکتور مذکور مقادیری پیش‌فرض را به متغیرهای فیلد تعریف‌شده در این کلاس اختصاص می‌دهد (البته توجه داشته باشیم که کانستراکتور پیش‌فرض در حین کامپایل شدن ساخته می‌شود و از همین روی از دید ما مخفی می‌باشد.) همان‌طور که می‌بینیم، مقدار پیش‌فرض null برای آبجکت name ساخته‌شده از روی کلاس String، مقدار صفر برای متغیر age بوده و مقدار بولین false نیز برای متغیر trueOrFalse در نظر گرفته شده است.

در ادامه نحوۀ تعریف کانستراکتور در کلاس را مورد بررسی قرار می‌دهیم و برای این منظور کد کلاس MyClass را به صورت زیر تکمیل می‌کنیم:

public class MyClass {
    String name;
    int age;
    boolean trueOrFalse;
    MyClass() {
        name = null;
        age = 0;
        trueOrFalse = false;
    }
    public void dispaly() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(trueOrFalse);
    }
}

همان‌طور در کد فوق می‌بینیم، کانستراکتوری تحت عنوان MyClass ساخته‌ایم و داخل آن به متغیرهای فیلد تعریف‌شده در کلاس تحت عناوین age ،name و trueOrFalse به ترتیب مقادیر اولیۀ null، عدد صفر و مقدار بولین falseرا اختصاص داده‌ایم و توجه داشته باشیم که تعریف کانستراکتور فوق هیچ تفاوتی با عدم تعریف آن برای کلاس ندارد چرا که کامپایلر جاوا به صورت خودکار کانستراکتوری بدین صورت را برای آبجکت ساخته‌شده از روی این کلاس ساخته و آن را فراخوانی می‌نماید که این فرآیند را در تصویر زیر آورده‌ایم:

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

public class MyClass {
    String name;
    int age;
    boolean trueOrFalse;
    MyClass(String myName, int myAge, boolean myTrueOrFalse) {
        name = myName;
        age = myAge;
        trueOrFalse = myTrueOrFalse;
    }
    public void dispaly() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(trueOrFalse);
    }
}

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

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

public class MyClass {
    String name;
    int age;
    boolean trueOrFalse;
    MyClass(String name, int age, boolean trueOrFalse) {
        this.name = name;
        this.age = age;
        this.trueOrFalse = trueOrFalse;
    }
    public void dispaly() {
        System.out.println(name);
        System.out.println(age);
        System.out.println(trueOrFalse);
    }
}

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

اکنون پس از تعیین مقدار اولیۀ متغیرهای فیلدِ کلاس MyClass از طریق پارامترهای ورودی کانستراکتور، برنامۀ فوق را اجرا می‌کنیم و برای این منظور نیز در کلاس ActionClass به صورت زیر آبجکتی از روی کلاس MyClass می‌سازیم:

public class ActionClass {
    public static void main(String[] args) {
        MyClass objectOne = new MyClass("Sahand", 27, true);
        objectOne.dispaly();
    }
}

اکنون در صورت ساخت آبجکت جدید از روی کلاس MyClass کانستراکتور این کلاس فراخوانی می‌شود و به خاطر داریم که برای کانستراکتور مذکور سه پارامتر ورودی تعریف کرده‌ایم که به ترتیب از جنس استرینگ، عدد صحیح و بولین بودند. حال به منظور ساخت آبجکت از روی کلاس MyClass در کلاس ActionClass می‌توانیم مقادیری را به عنوان ورودی برای آبجکت جدید در نظر بگیریم که بدین ترتیب کانستراکتور آن‌ها را به متغیرهای فیلد تعریف‌شده در کلاس و مرتبط با آبجکت مربوطه اختصاص می‌دهد. همان‌طور که در کد فوق مشاهده می‌کنیم، با اجرای برنامه مقدار استرینگ «Sahand» به متغیر name، عدد 27 به متغیر age و مقدار بولین true نیز به متغیر trueOrFalse اختصاص داده می‌شود به طوری که پس از اجرای برنامه در خروجی خواهیم داشت:

Sahand
27
true

همان‌طور که می‌بینیم، با موفقیت توانستیم مقدار اولیۀ متغیرهای فیلد کلاس MyClass را مقداردهی نماییم. اکنون فرض کنیم که دو آبجکت تحت عناوین objectOne و objectTwo از روی کلاس MyClass می‌سازیم و برای مقداردهی هر دوی آن‌ها کد فوق را به صورت زیر تکمیل می‌کنیم:

public class ActionClass {
    public static void main(String[] args) {
        MyClass objectOne = new MyClass("Sahand", 27, true);
        objectOne.dispaly();
        MyClass objectTwo = new MyClass("Mohammad Ali", 31, false);
        objectTwo.dispaly();
    }
}

در کد فوق، دو آبجکت از روی کلاس MyClass تحت عناوین objectOne و objectTwo ساخته‌ایم و برای آبجکت دوم نیز مقادیر اولیۀ فوق را اختصاص داده‌ایم به طوری که در صورت اجرای برنامۀ فوق در خروجی خواهیم داشت:

Sahand
27
true
Mohammad Ali
31
false

همان‌طور که می‌بینیم، هر دو آبجکت ساخته‌شده از روی کلاس MyClass با مقادیر اختصاصی خودشان در پنجرۀ کنسول نمایش داده شده‌اند. دانلود فایل‌های تمرین


استفاده از Constructor زبان برنامه‌نویسی جاوا در قالب پروژه‌ای عملی


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

public class FuelConsumption {
    String name;
    String carName;
}

در کد فوق، دو آبجکت از نوع فیلد تحت عناوین name و carName از روی کلاس String ساخته‌ایم که قرار است تا به ترتیب نام کاربر و نام خودروی وی را نگهداری کنند. این بخش از محتوا مخصوص کاربرانی است که ثبت‌نام کرده‌اند.
جهت مشاهدهٔ این بخش از محتوا لاگین نمایید.

به طور کلی، در این آموزش کانستراکتوری برای کلاس FuelConsumption پیاده‌سازی کردیم و دیدیم که چگونه می‌توان مقادیر مورد نظر خود را به آبجکت جدید ساخته‌شده از روی کلاس داد تا کانستراکتور در حین فراخوانی آن‌ها را متغیرهای فیلد تعریف‌شده اختصاص دهد. به علاوه، به منظور دریافت دیتای ورودی به صورت دینامیک، از کلاس Scannerاستفاده کرده و متدهای تعبیه‌شده در آن از جمله ()next و ()nextDouble را به منظور خواندن دیتای ورودیِ کاربر فراخوانی نمودیم. دانلود فایل‌های تمرین

مطالب مرتبط

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *