JavaRush /وبلاگ جاوا /Random-FA /سازندگان کلاس جاوا JDK 1.5
articles
مرحله

سازندگان کلاس جاوا JDK 1.5

در گروه منتشر شد
سازندگان کلاس  جاوا JDK 1.5 - 1

اطلاعات کلی در مورد سازندگان

Конструкторساختاری شبیه به یک متد است که هدف آن ایجاد یک نمونه از یک کلاس است. ویژگی های طراح:
  • نام سازنده باید با نام کلاس مطابقت داشته باشد (طبق قرارداد، حرف اول بزرگ است، معمولاً یک اسم).
  • سازنده در هر کلاسی وجود دارد. حتی اگر یکی را ننویسید، کامپایلر جاوا یک سازنده پیش‌فرض ایجاد می‌کند که خالی خواهد بود و کاری جز فراخوانی سازنده سوپرکلاس انجام نمی‌دهد.
  • سازنده شبیه متد است، اما متد نیست، حتی عضوی از کلاس محسوب نمی شود. بنابراین، نمی توان آن را در یک زیر کلاس به ارث برد یا لغو کرد.
  • سازندگان به ارث نمی رسند.
  • در یک کلاس چند سازنده وجود دارد. در این مورد گفته می شود که سازنده ها بیش از حد بارگذاری شده اند.
  • اگر کلاس سازنده ای را تعریف نکند، کامپایلر به طور خودکار یک سازنده بدون پارامتر به کد اضافه می کند.
  • سازنده نوع بازگشتی ندارد، حتی نمی‌تواند یک نوع باشد void، اگر یک نوع برگردانده شود void، با وجود همزمانی با نام کلاس، دیگر سازنده نیست، بلکه یک متد است.
  • عملگر در سازنده مجاز است return، اما فقط خالی است، بدون هیچ مقدار بازگشتی.
  • سازنده اجازه استفاده از اصلاح کننده های دسترسی را می دهد؛ می توانید یکی از اصلاح کننده ها را تنظیم کنید: public، protected، privateیا بدون اصلاح کننده.
  • یک سازنده نمی تواند اصلاح کننده های abstract, final, native, staticیا synchronized;
  • کلمه کلیدی thisبه سازنده دیگری در همان کلاس اشاره دارد. در صورت استفاده، فراخوانی آن باید اولین خط سازنده باشد.
  • کلمه کلیدی superسازنده کلاس والد را فرا می خواند. در صورت استفاده، ارجاع به آن باید اولین خط سازنده باشد.
  • اگر سازنده به سازنده کلاس اجداد (با یا بدون آرگومان) فراخوانی نکند super، کامپایلر به طور خودکار کدی را برای فراخوانی سازنده کلاس اجداد بدون آرگومان اضافه می کند.

سازنده پیش فرض

سازنده در هر کلاسی وجود دارد. حتی اگر یکی را ننویسید، کامپایلر جاوا یک سازنده پیش فرض ایجاد می کند. این سازنده خالی است و کاری جز فراخوانی سازنده سوپرکلاس انجام نمی دهد. آن ها اگر بنویسی:
public class Example {}
پس این معادل نوشتن است:
public class Example
{
     Example()
     {
          super;
     }
}
در این حالت، کلاس ancestor به طور صریح مشخص نشده است و به طور پیش فرض، تمام کلاس های جاوا کلاس را به ارث می برند، Objectبنابراین سازنده کلاس فراخوانی می شود Object. اگر یک کلاس سازنده ای را با پارامترها تعریف کند، اما سازنده بدون پارامتر اضافه بار وجود نداشته باشد، فراخوانی سازنده بدون پارامتر یک خطا است. با این حال، در جاوا از نسخه 1.5، می توان از سازنده هایی با آرگومان های طول متغیر استفاده کرد. و اگر سازنده ای وجود داشته باشد که آرگومان طول متغیر داشته باشد، فراخوانی سازنده پیش فرض خطا نخواهد بود. به این دلیل نیست که آرگومان طول متغیر می تواند خالی باشد. به عنوان مثال، مثال زیر کامپایل نخواهد شد، اما اگر سازنده را با آرگومان طول متغیر از کامنت بردارید، کامپایل شده و با موفقیت اجرا می شود و منجر به اجرای یک خط کد می شود DefaultDemo dd = new DefaultDemo(). سازنده فراخوانی خواهد شد DefaultDemo(int ... v). طبیعتاً در این مورد استفاده از JSDK 1.5 ضروری است. فایلDefaultDemo.java
class DefaultDemo
{
 DefaultDemo(String s)
 {
  System.out.print("DefaultDemo(String)");
 }
 /*
 DefaultDemo(int ... v)
 {
  System.out.println("DefaultDemo(int ...)");
 }
 */

 public static void main(String args[])
 {
  DefaultDemo dd = new DefaultDemo();
 }
}
نتیجه خروجی برنامه با سازنده بدون نظر:
DefaultDemo(int ...)
با این حال، در موارد رایج که کلاس اصلا سازنده ای را تعریف نمی کند، فراخوانی سازنده پیش فرض (بدون پارامتر) ضروری است، زیرا جایگزینی سازنده پیش فرض به طور خودکار اتفاق می افتد.

ایجاد شی و سازنده

هنگام ایجاد یک شی، اقدامات زیر به صورت متوالی انجام می شود:
  • کلاس شی در بین کلاس هایی که قبلاً در برنامه استفاده شده است جستجو می شود. اگر وجود ندارد، در تمام فهرست‌ها و کتابخانه‌های موجود در برنامه جستجو می‌شود. هنگامی که یک کلاس در یک دایرکتوری یا کتابخانه کشف شد، فیلدهای ثابت کلاس ایجاد و مقداردهی اولیه می شوند. آن ها برای هر کلاس، فیلدهای استاتیک فقط یک بار مقداردهی اولیه می شوند.
  • حافظه برای شی اختصاص داده شده است.
  • فیلدهای کلاس در حال تنظیم اولیه هستند.
  • سازنده کلاس اجرا می کند.
  • پیوندی به شی ایجاد شده و اولیه تشکیل می شود. این مرجع مقدار عبارتی است که شی را ایجاد می کند. newInstance()یک شی نیز می تواند با فراخوانی متد کلاس ایجاد شود java.lang.Class. در این حالت از سازنده بدون لیست پارامتر استفاده می شود.

بارگذاری بیش از حد سازنده ها

سازنده های یک کلاس می توانند نام یکسان و امضای متفاوتی داشته باشند. این ویژگی ترکیبی یا اضافه بار نامیده می شود. اگر یک کلاس چندین سازنده داشته باشد، بارگذاری سازنده وجود دارد.

سازندگان پارامتری

امضای سازنده تعداد و انواع پارامترها و همچنین توالی انواع آنها در لیست پارامترهای سازنده است. نوع بازگشت در نظر گرفته نشده است. سازنده هیچ پارامتری را بر نمی گرداند. این عبارت به نوعی توضیح می دهد که چگونه جاوا بین سازنده ها یا متدهای بارگذاری شده تمایز قائل می شود. جاوا روش های بارگذاری شده را نه بر اساس نوع برگشتی، بلکه با تعداد، انواع و ترتیب انواع پارامترهای ورودی متمایز می کند. یک سازنده حتی نمی تواند یک نوع را برگرداند void، در غیر این صورت به یک متد معمولی تبدیل می شود، حتی اگر شبیه به نام کلاس باشد. مثال زیر این را نشان می دهد. فایلVoidDemo.java
class VoidDemo
{
 /**
  * Это конструктор
  */
 VoidDemo()
 {
  System.out.println("Constructor");
 }

 /**
  * А это уже обычный метод, даже не смотря на сходство с
  * именем класса, поскольку имеется возвращаемый тип void
  */
 void VoidDemo()
 {
  System.out.println("Method");
 }

 public static void main(String s[])
 {
  VoidDemo m = new VoidDemo();
 }
}
در نتیجه برنامه خروجی خواهد داشت:
Constructor
این یک بار دیگر ثابت می کند که سازنده یک متد بدون پارامترهای بازگشتی است. با این حال، سازنده را می توان یکی از سه اصلاح کننده public، privateیا protected. و مثال اکنون به این شکل خواهد بود: FileVoidDemo2.java
class VoidDemo2
{
 /**
  * Это конструктор
  */
 public VoidDemo2()
 {
  System.out.println("Constructor");
 }

 /**
  * А это уже обычный метод, даже не смотря на сходство с
  * именем класса, поскольку имеется возвращаемый тип void
  */
 private void VoidDemo2()
 {
  System.out.println("Method");
 }

 public static void main(String s[])
 {
  VoidDemo2 m = new VoidDemo2();
 }
}
نوشتن یک عملگر در سازنده مجاز است return، اما فقط یک عملگر خالی، بدون هیچ مقدار بازگشتی. فایلReturnDemo.java
class ReturnDemo
{
 /**
  * В конструкторе допускается использование оператора
  * return без параметров.
  */
 public ReturnDemo()
 {
  System.out.println("Constructor");
  return;
 }

 public static void main(String s[])
 {
  ReturnDemo r = new ReturnDemo();
 }
}

سازنده ها با آرگومان های طول متغیر پارامتر بندی شده اند

Java SDK 1.5 یک ابزار مورد انتظار را معرفی کرد - آرگومان های با طول متغیر برای سازنده ها و روش ها. پیش از این، تعداد متغیری از اسناد به دو روش نامناسب پردازش می شد. اولین مورد برای اطمینان از اینکه حداکثر تعداد آرگومان ها به تعداد کمی محدود شده و از قبل شناخته شده است طراحی شده است. در این مورد، امکان ایجاد نسخه های بارگذاری شده از متد وجود داشت، یک نسخه برای هر نسخه از لیست آرگومان های ارسال شده به متد. روش دوم برای چیزی ناشناخته از قبل و تعداد زیادی استدلال طراحی شده است. در این حالت آرگومان ها در یک آرایه قرار گرفتند و این آرایه به متد ارسال شد. آرگومان های طول متغیر اغلب در دستکاری های بعدی با مقداردهی اولیه متغیر دخالت دارند. جایگزینی عدم وجود برخی از آرگومان های سازنده یا متد مورد انتظار با مقادیر پیش فرض راحت است. آرگومان طول متغیر یک آرایه است و به عنوان یک آرایه در نظر گرفته می شود. برای مثال، سازنده یک کلاس Checkingبا تعداد متغیر آرگومان به شکل زیر است:
class Checking
{
 public Checking(int ... n)
 {
 }
}
ترکیب کاراکتر ... به کامپایلر می گوید که از تعداد متغیری از آرگومان ها استفاده خواهد شد و این آرگومان ها در آرایه ای ذخیره می شوند که مقدار مرجع آن در متغیر n موجود است. سازنده را می توان با تعداد متفاوتی از آرگومان ها فراخوانی کرد، از جمله بدون هیچ آرگومان. آرگومان ها به طور خودکار در یک آرایه قرار می گیرند و از n عبور می کنند. اگر آرگومان وجود نداشته باشد، طول آرایه 0 است. فهرست پارامترها، همراه با آرگومان های طول متغیر، می تواند شامل پارامترهای اجباری نیز باشد. در این حالت، پارامتری که دارای تعداد متغیری از آرگومان ها است باید آخرین در لیست پارامترها باشد. مثلا:
class Checking
{
 public Checking(String s, int ... n)
 {
 }
}
یک محدودیت بسیار آشکار مربوط به تعداد پارامترهای طول متغیر است. باید فقط یک پارامتر طول متغیر در لیست پارامترها وجود داشته باشد. با توجه به دو پارامتر طول متغیر، برای کامپایلر غیرممکن است که تعیین کند یک پارامتر کجا به پایان می رسد و دیگری شروع می شود. مثلا:
class Checking
{
 public Checking(String s, int ... n, double ... d) //ОШИБКА!
 {
 }
}
فایل Checking.java به عنوان مثال، تجهیزاتی وجود دارد که قادر به تشخیص پلاک خودروها و به خاطر سپردن شماره مربع های منطقه ای هستند که هر یک از خودروها در طول روز از آن بازدید کرده اند. لازم است از مجموع خودروهای ثبت شده، خودروهایی که در طول روز از دو میدان مشخص شده، مثلاً 22 و 15 بازدید کرده اند، طبق نقشه منطقه انتخاب شوند. کاملاً طبیعی است که یک ماشین بتواند در طول روز از میدان های زیادی یا شاید فقط یکی را بازدید کند. بدیهی است که تعداد مربع های بازدید شده توسط سرعت فیزیکی خودرو محدود می شود. بیایید یک برنامه کوچک ایجاد کنیم که سازنده کلاس، شماره ماشین را به عنوان یک پارامتر اجباری و تعداد مربع های بازدید شده منطقه را به عنوان آرگومان در نظر بگیرد، که تعداد آنها می تواند متغیر باشد. سازنده بررسی می کند که آیا یک ماشین در دو مربع ظاهر شده است یا خیر، اگر چنین است، سپس شماره آن را روی صفحه نمایش می دهد.

انتقال پارامترها به سازنده

در زبان های برنامه نویسی عمدتا دو نوع پارامتر وجود دارد:
  • انواع اولیه (اولیه)؛
  • ارجاع به اشیا
اصطلاح فراخوانی با مقدار به این معنی است که سازنده مقدار ارسال شده توسط ماژول فراخوان را دریافت می کند. در مقابل، فراخوانی با مرجع به این معنی است که سازنده آدرس متغیر را از تماس گیرنده دریافت می کند. جاوا فقط از تماس با مقدار استفاده می کند. بر اساس مقدار پارامتر و بر اساس مقدار پیوند پارامتر. جاوا از فراخوانی با مرجع برای اشیا استفاده نمی کند (اگرچه بسیاری از برنامه نویسان و نویسندگان برخی کتاب ها این ادعا را دارند). هنگام ارسال اشیا به جاوا، پارامترها نه با مرجع ، بلکه با مقدار مرجع شیء ارسال می شوند ! در هر صورت، سازنده کپی هایی از مقادیر تمام پارامترها را دریافت می کند. یک سازنده نمی تواند با پارامترهای ورودی خود انجام دهد:
  • سازنده نمی تواند مقادیر پارامترهای ورودی انواع اصلی (اولیه) را تغییر دهد.
  • سازنده نمی تواند مراجع پارامتر ورودی را تغییر دهد.
  • سازنده نمی تواند ارجاعات پارامتر ورودی را دوباره به اشیاء جدید اختصاص دهد.
سازنده می تواند با پارامترهای ورودی خود انجام دهد:
  • وضعیت شی ارسال شده به عنوان پارامتر ورودی را تغییر دهید.
مثال زیر ثابت می کند که در جاوا، پارامترهای ورودی به یک سازنده توسط مقدار مرجع شی ارسال می شوند. این مثال همچنین نشان می‌دهد که سازنده نمی‌تواند مراجع پارامترهای ورودی را تغییر دهد، اما در واقع مراجع کپی‌های پارامترهای ورودی را تغییر می‌دهد. فایلEmpoyee.java
class Employee
{
 Employee(String x, String y)
 {
  String temp = x;
  x = y;
  y = temp;
 }
 public static void main(String args[])
 {
  String name1 = new String("Alice");
  String name2 = new String("Mary");
  Employee a = new Employee(name1, name2);
  System.out.println("name1="+name1);
  System.out.println("name2="+name2);
 }
}
خروجی برنامه این است:
name1=Alice
name2=Mary
اگر جاوا از فراخوانی با ارجاع برای ارسال اشیا به عنوان پارامتر استفاده می‌کرد، سازنده آن را تعویض می‌کرد name1و در این مثال name2. سازنده در واقع ارجاعات شی ذخیره شده در متغیرهای name1و را تعویض نمی کند name2. این نشان می دهد که پارامترهای سازنده با کپی هایی از این مراجع مقداردهی اولیه می شوند. سپس سازنده کپی ها را تعویض می کند. هنگامی که سازنده کار خود را کامل می کند، متغیرهای x و y از بین می روند و متغیرهای اصلی name1همچنان name2به اشیاء قبلی اشاره می کنند.

تغییر پارامترهای ارسال شده به سازنده.

سازنده نمی تواند پارامترهای تصویب شده انواع پایه را تغییر دهد. با این حال، سازنده می تواند وضعیت شی ارسال شده به عنوان یک پارامتر را تغییر دهد. به عنوان مثال، برنامه زیر را در نظر بگیرید: FileSalary1.java
class Salary1
{
 Salary1(int x)
 {
  x = x * 3;
  System.out.println("x="+x);
 }
 public static void main(String args[])
 {
  int value = 1000;
  Salary1 s1 = new Salary1(value);
  System.out.println("value="+value);
 }
}
خروجی برنامه این است:
x=3000
value=1000
بدیهی است که این روش پارامتر نوع اصلی را تغییر نخواهد داد. بنابراین، پس از فراخوانی سازنده، مقدار متغیر valueبرابر با 1000. اساساً سه چیز اتفاق می افتد:
  1. متغیر xبا یک کپی از مقدار پارامتر value(به عنوان مثال، یک عدد 1000) مقدار دهی اولیه می شود.
  2. مقدار متغیر xسه برابر شده است - اکنون برابر است با 3000. با این حال، مقدار متغیر valueبرابر با 1000.
  3. سازنده خاتمه می یابد و متغیر xدیگر استفاده نمی شود.
در مثال زیر، حقوق کارمند با موفقیت سه برابر شده است زیرا مقدار یک مرجع شی به عنوان پارامتری به متد ارسال می شود. فایلSalary2.java
class Salary2
{
 int value = 1000;
 Salary2()
 {
 }
 Salary2(Salary2 x)
 {
  x.value = x.value * 3;
 }
 public static void main(String args[])
 {
  Salary2 s1 = new Salary2();
  Salary2 s2 = new Salary2(s1);
  System.out.println("s1.value=" +s1.value);
  System.out.println("s2.value="+s2.value);
 }
}
خروجی برنامه این است:
s1.value=3000
s2.value=1000
مقدار مرجع شی به عنوان یک پارامتر استفاده می شود. هنگام اجرای خط Salary2 s2 = new Salary2(s1)؛ سازنده Salary2(Salary x)مقدار ارجاع به شی متغیر را دریافت می کند s1و سازنده عملاً دستمزد را سه برابر می کند s1.value، زیرا حتی کپی (Salary x)ایجاد شده در سازنده به شی متغیر اشاره می کند s1.

سازندگان با پارامترهای اولیه.

اگر پارامترهای یک سازنده بارگذاری شده از یک اولیه استفاده می کنند که می تواند باریک شود (به عنوان مثال int <- double)، فراخوانی متدی با مقدار محدود شده امکان پذیر است، علیرغم این واقعیت که هیچ روشی با چنین پارامتری اضافه بار وجود ندارد. به عنوان مثال: فایلPrimitive.java
class Primitive
{
 Primitive(double d)
 {
  d = d + 10;
  System.out.println("d="+d);
 }
 public static void main(String args[])
 {
  int i = 20;
  Primitive s1 = new Primitive(i);
 }
}
خروجی برنامه این است:
d=30.0
با وجود این واقعیت که کلاس Primitiveسازنده ای ندارد که پارامتر نوع داشته باشد int، سازنده با پارامتر ورودی کار خواهد کرد double. قبل از فراخوانی سازنده، متغیر از نوع به نوع دیگر iگسترش می یابد . گزینه مقابل، زمانی که متغیر از نوع باشد ، و سازنده فقط یک پارامتر داشته باشد ، در این شرایط منجر به خطای کامپایل می شود. intdoubleidoubleint

تماس سازنده و اپراتورnew

سازنده همیشه توسط عملگر فراخوانی می شود new. هنگامی که یک سازنده با عملگر فراخوانی می شود new، سازنده همیشه یک مرجع به یک شی جدید تولید می کند. غیرممکن است که سازنده را مجبور کنیم به جای ارجاع به یک شی جدید، به یک شیء موجود از قبل ارجاع دهد، مگر با جایگزین کردن شیء در حال بی‌ثبات شدن. و با عملگر جدید، به جای ارجاع به یک شی جدید، نمی توان به یک شی از قبل موجود اشاره کرد. به عنوان مثال: فایلSalary3.java
class Salary3
{
 int value = 1000;
 Salary3()
 {
 }
 Salary3(Salary3 x)
 {
  x.value = x.value * 3;
 }
 public static void main(String args[])
 {
  Salary3 s1 = new Salary3();
  System.out.println("First object creation: "+s1.value);

  Salary3 s2 = new Salary3(s1);
  System.out.println("Second object creation: "+s2.value);
  System.out.println("What's happend with first object?:"+s1.value);

  Salary3 s3 = new Salary3(s1);
  System.out.println("Third object creation: "+s3.value);
  System.out.println("What's happend with first object?:"+s1.value);
 }
}
خروجی برنامه این است:
First object creation: 1000
Second object creation: 1000
What's happend with first object?: 3000
Third object creation: 1000
What's happend with first object?: 9000
Salary3 s1 = new Salary3()ابتدا با استفاده از خط یک شی جدید ایجاد می شود. بعد، در صورت استفاده از خط Salary3 s2 = new Salary3(s1); یا رشته Salary3 s3 = new Salary3(s1)ها می توان پیوندی به یک شی از قبل موجود ایجاد کرد، سپس s1.value s2.valueآنها s3.valueهمان مقدار را ذخیره می کردند 1000. در واقع در خط Salary3 s2 = new Salary3(s1); یک شی جدید برای متغیر ایجاد می شود و با ارسال مقدار مرجع آن به شی در پارامتر سازنده، s2وضعیت آبجکت برای متغیر تغییر می کند . s1این را می توان با نتایج خروجی تأیید کرد. و هنگام اجرای خط Salary3 s3 = new Salary3(s1); یک شی جدید برای متغیر ایجاد می شود s3و وضعیت شی برای متغیر دوباره تغییر می کند s1.

سازنده ها و بلوک های اولیه، توالی اقدامات هنگام فراخوانی سازنده

در بخش Creating an Object and Constructors اقدامات کلی که هنگام ایجاد یک شی انجام می شود را فهرست می کند. از جمله آنها فرآیندهای اولیه سازی فیلدهای کلاس و کار کردن سازنده کلاس هستند که به نوبه خود دارای یک نظم داخلی هستند:
  1. تمام فیلدهای داده به مقادیر پیش فرض خود (0، false یا null) مقداردهی اولیه می شوند.
  2. تمام اولیه سازهای فیلد و بلوک های اولیه به ترتیبی که در اعلان کلاس فهرست شده اند اجرا می شوند.
  3. اگر سازنده دیگری در خط اول یک سازنده فراخوانی شود، سازنده فراخوانی شده اجرا می شود.
  4. بدنه سازنده اجرا می شود.
سازنده مربوط به مقداردهی اولیه است زیرا در جاوا سه راه برای مقداردهی اولیه یک فیلد در یک کلاس وجود دارد:
  • یک مقدار در اعلان تعیین کنید.
  • تخصیص مقادیر در بلوک اولیه؛
  • مقدار آن را در سازنده تنظیم کنید.
به طور طبیعی، شما باید کد اولیه را طوری سازماندهی کنید که درک آن آسان باشد. کلاس زیر به عنوان مثال آورده شده است:
class Initialization
{
 int i;
 short z = 10;
 static int x;
 static float y;
 static
 {
  x = 2000;
  y = 3.141;
 }
 Initialization()
 {
  System.out.println("i="+i);
  System.out.println("z="+z);
  z = 20;
  System.out.println("z="+z);
 }
}
در مثال بالا، متغیرها به ترتیب زیر مقداردهی اولیه می شوند: متغیرهای استاتیک ابتدا xبا yمقادیر پیش فرض مقداردهی اولیه می شوند. سپس بلوک اولیه سازی استاتیک اجرا می شود. سپس متغیر iبه مقدار پیش فرض مقداردهی اولیه می شود و متغیر مقداردهی اولیه می شود z. بعد، طراح دست به کار می شود. فراخوانی سازنده کلاس ها نباید به ترتیبی که فیلدها اعلام می شوند بستگی داشته باشد. این ممکن است منجر به خطا شود.

سازندگان و ارث

سازندگان به ارث نمی رسند. مثلا:
public class Example
{
 Example()
 {
 }
 public void sayHi()
 {
  system.out.println("Hi");
 }
}

public class SubClass extends Example
{
}
کلاس SubClassبه طور خودکار متد sayHi()تعریف شده در کلاس والد را به ارث می برد. در عین حال، سازنده Example()کلاس والد توسط نسل آن به ارث نمی رسد SubClass.

کلیدواژه thisدر سازنده ها

thisسازنده ها برای ارجاع به سازنده دیگری در همان کلاس، اما با لیست متفاوتی از پارامترها استفاده می شوند . اگر سازنده از کلمه کلیدی استفاده کند this، باید در خط اول باشد؛ نادیده گرفتن این قانون منجر به خطای کامپایلر می شود. به عنوان مثال: فایلThisDemo.java
public class ThisDemo
{
 String name;
 ThisDemo(String s)
 {
  name = s;
     System.out.println(name);
 }
 ThisDemo()
 {
  this("John");
 }
 public static void main(String args[])
 {
  ThisDemo td1 = new ThisDemo("Mary");
  ThisDemo td2 = new ThisDemo();
 }
}
خروجی برنامه این است:
Mary
John
در این مثال دو سازنده وجود دارد. اولین آرگومان رشته ای دریافت می کند. دومی هیچ آرگومان دریافت نمی کند، آن را به سادگی با استفاده از نام پیش فرض "جان" سازنده اول فراخوانی می کند. بنابراین، می‌توانید از سازنده‌ها برای مقداردهی اولیه مقادیر فیلد به‌طور صریح و پیش‌فرض استفاده کنید، که اغلب در برنامه‌ها ضروری است.

کلیدواژه superدر سازنده ها

superسازنده ها برای فراخوانی سازنده سوپرکلاس استفاده می شوند . اگر سازنده استفاده کند super، این فراخوانی باید در خط اول باشد، در غیر این صورت کامپایلر خطا می دهد. در زیر یک مثال آورده شده است: فایلSuperClassDemo.java
public class SuperClassDemo
{
 SuperClassDemo()
 {
 }
}

class Child extends SuperClassDemo
{
 Child()
 {
  super();
 }
}
در این مثال ساده، سازنده Child()شامل فراخوانی است که علاوه بر کلاس، super()نمونه ای از کلاس را ایجاد می کند . از آنجا که باید اولین دستوری باشد که در سازنده زیر کلاس اجرا می شود، این ترتیب همیشه یکسان است و به این بستگی ندارد . اگر از آن استفاده نشود، ابتدا سازنده پیش‌فرض (بدون پارامتر) هر سوپرکلاس، که با کلاس پایه شروع می‌شود، اجرا می‌شود. برنامه زیر نشان می دهد که سازنده ها چه زمانی اجرا می شوند. فایلSuperClassDemoChildsupersuper()Call.java
//Создать суперкласс A
class A
{
 A()
 {
  System.out.println("Inside A constructor.");
 }
}

//Создать подкласс B, расширяющий класс A
class B extends A
{
 B()
 {
  System.out.println("Inside B constructor.");
 }
}

//Создать класс (C), расширяющий класс В
class C extends B
{
 C()
 {
  System.out.println("Inside C constructor.");
 }
}

class Call
{
 public static void main(String args[])
 {
  C c = new C();
 }
}
خروجی این برنامه:
Inside A constructor.
Inside B constructor.
Inside C constructor.
سازنده ها به ترتیب تبعیت کلاس فراخوانی می شوند. این تا حدی منطقی است. از آنجایی که سوپرکلاس هیچ دانشی از هیچ زیر کلاسی ندارد، هر مقدار اولیه ای که برای انجام آن نیاز دارد جدا است. در صورت امکان، باید قبل از هر مقداردهی اولیه انجام شده توسط زیر کلاس باشد. به همین دلیل باید ابتدا انجام شود.

سازنده های قابل تنظیم

مکانیسم شناسایی نوع زمان اجرا یکی از اصول اصلی قدرتمند زبان جاوا است که چند شکلی را پیاده سازی می کند. با این حال، چنین مکانیزمی در برخی موارد از توسعه دهنده در برابر ریخته گری ناسازگار محافظت نمی کند. رایج ترین مورد، دستکاری گروهی از اشیاء است که انواع مختلف آنها از قبل ناشناخته بوده و در زمان اجرا مشخص می شوند. از آنجایی که خطاهای مرتبط با ناسازگاری نوع تنها می توانند در مرحله اجرا ظاهر شوند، این امر یافتن و حذف آنها را دشوار می کند. معرفی انواع سفارشی در جاوا 2 5.0 برخی از این خطاها را از زمان اجرا به زمان کامپایل منتقل می کند و برخی از ایمنی نوع گمشده را فراهم می کند. Objectهنگام انتقال از نوع به نوع بتنی، نیازی به ریخته گری نوع صریح نیست . باید در نظر داشت که ابزار سفارشی‌سازی نوع فقط با اشیا کار می‌کند و برای انواع داده‌های اولیه که خارج از درخت وراثت کلاس قرار دارند اعمال نمی‌شود. با انواع سفارشی، تمام بازیگران به صورت خودکار و پشت صحنه انجام می شوند. این به شما امکان می دهد در برابر عدم تطابق نوع محافظت کنید و از کدها بیشتر استفاده کنید. انواع سفارشی را می توان در سازنده ها استفاده کرد. سازنده ها می توانند سفارشی شوند حتی اگر کلاس آنها یک نوع سفارشی نباشد. مثلا:
class GenConstructor
{
 private double val;
 <T extends Number> GenConstructor(T arg)
 {
   val = arg.doubleValue();
 }

 void printValue()
 {
  System.out.println("val: "+val);
 }
}

class GenConstructorDemo
{
 public static void main(String args[])
 {
  GenConstructor gc1 = new GenConstructor(100);
  GenConstructor gc2 = new GenConstructor(123.5F);

  gc1.printValue();
  gc2.printValue();
 }
}
از آنجایی که سازنده GenConstructorیک پارامتر نوع سفارشی را مشخص می کند که باید یک کلاس مشتق شده از کلاس باشد Number، می توان آن را از هر کلاس فراخوانی کرد.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION