آموزش برنامه نویسی جاوا
آموزش برنامه نویسی جاوا (بخش بیستم: سازنده و مخرب در جاوا)
سازنده یا Constructor
در هنگام ساخت یک شی از یک نمونه کلاس، می توان متغیر های یک شی را مقداردهی اولیه کرد.
تابع سازنده (Constructor) تابعی است که در حین نمونه گرفتن از یک کلاس یک مرتبه اجرا می شود. زیرا بسیار ساده تر و دقیق تر آن است که کلیه تنظیمات در زمان ایجاد اولیه شی انجام شود.
از این تابع بیشتر برای مقداردهی کردن متغییر ها و فیلدهای یک کلاس در هنگام ساخت یک شی، استفاده می شود.
معمولا بعضی از اعضای کلاس قبل از استفاده نیاز به مقداردهی دارندکه همان طور که گفته شد، اين عمل توسط سازنده (constractor) انجام می گیرد که به شیء اين امکان را می دهد که هنگام ايجاد مقداردهی شود.
سازنده تابعی است هم اسم کلاس که وقتی یک نمونه از کلاس گرفته می شود اتوماتیک فراخوانی می شود.
سازنده نام همان کلاسی را که در آن قرار گرفته اختیار نموده و از نظر صرف و نحو مشابه یک روش است.
وقتی یکبار سازنده ای را تعریف نمایید، بطور خودکار بلافاصله پس از ایجاد یک شی و قبل از اینکه عملگر new تکمیل شود، فراخوانی خواهد شد.
سازندگان کمی بنظر عجیب می آیند زیرا فاقد نوع برگشتی و حتی فاقد void هستند.
در زبان های شی گرا مثل سی شارپ و جاوا چون همه چیز بر پایه شی گرایی و کلاس هست شما وقتی یک کلاس می سازید میتونید با استفاده از سازنده ها متغیر ها رو مقدار دهی کنید.
وقتی شما یکی شی از کلاس مورد نظرتون می سازین(new می کنید!) کامپایلر به سراغ سازنده ی شما می رود که اگه نباشه سازنده ی پیش فرض فراخونی میشه که بدون پارامتره و شما میتونید از سازنده استفاده کرده و اونطوری که دلتون می خواد متغیر هاتون رو مقدار دهی کنید و از همون اول برای شی ساخته شدتون بفرستید .
تابع سازنده می تواند دارای پارامتر باشد بنابراين زمان ايجاد شیء می توان به متغيرهای عضو مقادير اوليه داد. برای ارسال آرگومان به تابع سازنده بايد هنگام تعريف شیء مقدار آرگومان بعد از نام شیء درون پرانتز قرار گيرد.
یک کلاس می تواند دارای چند سازنده با پارامترهای مختلف باشد. بهتر است همیشه حداقل یک سازنده حتی اگر خالی باشد ساخته شود.
برای تابع سازنده مقدار برگشتی ذکر نمی شود (حتی Void).
برای درک بیشتر به مثال زیر توجه نمایید:
public class JavaApplication1 { static class myClass{ private int a; private char b; // تابع سازنده myClass(){ this.a=1; // مقدار دهی به متغیر در تابع سازنده this.b='a'; // مقدار دهی به متغیر در تابع سازنده } } public static void main(String[] args) { myClass newObject = new myClass(); // ایجاد شی System.out.print(newObject.a); System.out.print(newObject.b); } }
خروجی کد بالا، 1a می باشد. زیرا شی به هنگام ساخت توسط سازنده ی خودش مقدار دهی می شود.
همچنین سازنده می تواند مقادیری را نیز به صورت پارامتر ورودی در هنگام ساخت شی ، از شی بگیرد.
برای این کار کافیست، در تابع سازنده، پارامتر ورودی در داخل پرانتز، بنویسیم. سپس در هنگام ساخت شی، مقادیر ورودی به آن پارامتر ها را بدهیم تا سازنده بتواند مقدار دهی متغیرهای شی را انجام دهد.
مثال زیر، چگونگی ساخت سازنده با استفاده از پارامتر ورودی را به شما نشان می دهد:
public class JavaApplication1 { static class myClass{ int a; char b; // ساخت تابع سازنده myClass(int m, char n){ a = m; b = n; } } public static void main(String[] args) { myClass newObject = new myClass(5,'m'); // مقدار دهی اولیه فیلدهای شی با استفاده از سازنده System.out.print(newObject.a); // خروجی مقدار 5 را نشان می دهد System.out.print(newObject.b); را نشان می دهد m خروجی مقدار } }
constructor مشخص می کند که هنگام ایجاد شیئی از نوع کلاس ، چه اتفاقی رخ می دهد . constructor های خاص خودشان را در تعریف کلاس مشخص می کنند. اما ، اگر constructor به طور صریح مشخص نشود ، در آن صورت جاوا آن را به طور خودکار تامین می کند. در خصوص کلاس ذکر شده در بخش قبل نیز، همین طور است.
مخرب یا Destructor
تابع مخرب کلاس (destructor) کم و بیش عکس سازنده عمل می کند. یک مخرب وقتی فراخوانی می شود که یک شی از بین می رود.
در ++C یک مخرب مشابه سازنده ساخته می شود فقط قبل از اسم آن علامت مد (~)قرار می گیرد.
تابع مخرب اتوماتیک وقتی متغیر شیء از حوزه دسترسی خارج می شود (برای متغیرهای سراسری وقتی از تابع اصلی خارج می شود و برای متغیر محلی هنگام خروج از بلاک تابع) فراخوانی می شود.
مشابه سازنده ها تابع مخرب نيز نوع برگشتی ندارد.
توابع مخرب یا destructor کاربرد زیادی در مدیریت حافظه برنامه های نوشته شده در ++C دارند.
عموما در مورد کلاسهای طراحی شده، با استفاده از این متد به آزاد سازی حافظه پرداخته میشود.
اما در زبانی مانند جاوا که مدیریت حافظه در اختیار ماشین مجازی میباشد، استفاده از این تابع چندان منطقی نیست، با این حال امکان پیاده سازی آن با استفاده از تابع finalize فراهم شده است.
برای انجام این کار در کلاس مربوطه یک تابع به نام finalize پیاده سازی گشته و سیستم Garbage Collector در زمان اتمام استفاده از کلاس و آزاد سازی تمام ارجاعات آن، تابه finalize را فراخوانی مینماید.
از آنجا که زمان عملکرد Grabage Collector نا مشخص است، با استفاده از دستورات gc و runFinalization میتوان ماشین مجازی را ملزم به آزاد سازی حافظه (جمع آوری زباله ها از حافظه) نمود.
مثال زیر نحوه انجام این کار را نشان میدهد:
import java.util.ArrayList; public class Samples { public static void main(String[] args){ long mem = Runtime.getRuntime().freeMemory(); SampleClass c1 = new SampleClass(); SampleClass c2 = new SampleClass(); SampleClass c3 = new SampleClass(); System.out.println(String.format("Used memory: %d KB", (mem - Runtime.getRuntime().freeMemory())/1024)); mem = Runtime.getRuntime().freeMemory(); c1 = c2 = c3 = null; System.gc(); System.runFinalization(); System.out.println(String.format("Released memory: %d KB", (Runtime.getRuntime().freeMemory() - mem)/1024)); } } class SampleClass { private ArrayList<Double> _obj; public SampleClass() { _obj = new ArrayList<Double>(); for (int i=0; i<1000000; i++) _obj.add(Math.random()); System.out.println("Created"); } public void finalize() { _obj.clear(); _obj = null; System.out.println("Finalized"); } }