ارتباط اینترنتی

سازندگان سازنده های پیش فرض فراخوانی سازنده کلاس از سازنده های دیگر. چرا سازندگان مورد نیاز هستند؟ استفاده از آرگومان های خط فرمان

حقیقت این هست که:

1. اگر یک کلاس ایجاد کنید و سازنده ای را با آرگومان ها در آن تعریف کنید (کلاس AClass که فقط یک سازنده دارد که int i را می گیرد)، کامپایلر دیگر سازنده پیش فرض ایجاد نخواهد کرد. زیرا این امر باعث شکسته شدن قرارداد AClass می شود که بدون استدلال نمی توان آن را مقداردهی اولیه کرد. اگر می‌خواهید یک سازنده پیش‌فرض نیز داشته باشید، اکنون آن را به صراحت تنظیم کنید.

در غیر این صورت، جلوگیری از ایجاد یک سازنده پیش فرض غیرممکن خواهد بود، که بد خواهد بود.

2. هنگام ایجاد سازنده های یک کلاس BClass که از کلاس دیگری به ارث برده می شود، کامپایلر نیاز دارد که خط اول سازنده یک فراخوانی به سازنده دیگری (به ارث برده شده یا در این کلاس) باشد.

چرا؟ زیرا از آنجایی که شما از یک کلاس مشتق شده اید، می خواهید از منطق آن دوباره استفاده کنید. سازنده نمونه ای از کلاس را به حالت انتگرال اولیه می آورد. در مورد شما، AClass برای مقداردهی اولیه به آرگومان نیاز دارد که بدون آن JVM نمی داند چگونه نمونه ای از کلاس را مقداردهی اولیه کند.

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

کلاس عمومی AClass1 ( )

از آنجایی که هیچ سازنده ای به صراحت در اینجا تعریف نشده است و کلاس از کلاس های دیگر به ارث برده نمی شود، کامپایلر یک سازنده پیش فرض تولید می کند.

این معادل این تعریف است:

کلاس عمومی AClass1 ( عمومی AClass1() ( ))

حالا بیایید به BClass1 نگاه کنیم:

کلاس عمومی BClass1 AClass1 را گسترش می دهد ( )

در اینجا نیز سازنده ها به صراحت تعریف نشده اند و کامپایلر سعی می کند یک سازنده پیش فرض ایجاد کند. از آنجایی که کلاس AClass1 یک سازنده پیش فرض دارد، یک سازنده پیش فرض ایجاد می کند که سازنده AClass1 را فراخوانی می کند. این کد معادل این است:

کلاس عمومی BClass1 AClass1 را گسترش می دهد ( عمومی BClass1() (super();))

در مورد شما، یک کلاس بدون سازنده پیش‌فرض ایجاد می‌شود:

کلاس عمومی (کلاس عمومی (int i) ( ))

از آنجایی که (حداقل یک) سازنده در اینجا اعلان شده است، سازنده پیش فرض دیگر ایجاد نمی شود. یعنی چنین کدی دیگر کامپایل نخواهد شد:

AClass a = new AClass(); // کار نمی کند

نیاز به چیزی شبیه

AClass a = جدید AClass(1);

بر این اساس، هر سازنده BClass به یک سازنده AClass یا BClass نیاز دارد. با این توضیحات، کامپایلر سوگند یاد می کند:

عمومی BClass AClass() را گسترش می دهد

زیرا تلاشی برای فراخوانی سازنده پیش‌فرض کلاس AClass انجام می‌شود که تعریف نشده است:

عمومی BClass AClass را گسترش می دهد ( عمومی BClass () (super(); // خطا؛ چنین سازنده ای در AClass وجود ندارد)

با این حال، می توان با تنظیم سازنده AClass روی مقداری، یک BClass با سازنده پیش فرض ایجاد کرد:

کلاس عمومی BClass AClass را گسترش می دهد ( عمومی BClass () ( super(1); ))

این کامپایل خواهد شد.

متد در جاوامجموعه ای از عبارات است که مجموع آنها به شما امکان می دهد عملیات خاصی را انجام دهید. بنابراین، برای مثال، هنگامی که متد System.out.println() فراخوانی می شود، سیستم یک سری دستورات را برای چاپ یک پیام در کنسول اجرا می کند.

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

یک روش ایجاد کنید

در زیر مثالی برای توضیح نحو یک متد، نحوه ایجاد یک متد در جاوا آورده شده است.

نحو

متد int استاتیک عمومیName(int a, int b) ( // body )
  • استاتیک عمومی - اصلاح کننده.
  • int - نوع بازگشت؛
  • روش نام - نام روش.
  • a، b - پارامترهای رسمی؛
  • int a، int b - لیستی از پارامترها.

تعریف یک متد با سربرگ و بدنه متد نشان داده می شود. ما می توانیم همین موضوع را در نحو ایجاد متد زیر مشاهده کنیم.

نحو

اصلاح کننده returnType nameOfMethod (فهرست پارامترها) ( // بدنه روش )

نحو فوق شامل:

  • اصلاح کننده - نوع دسترسی به روش و امکان استفاده از آن را تعیین می کند.
  • returnType - متد می تواند مقداری را برگرداند.
  • nameOfMethod - نام متد را مشخص می کند. امضای یک متد شامل نام متد و لیستی از پارامترها است.
  • فهرست پارامترها - لیست پارامترها با نوع، ترتیب و تعداد پارامترهای روش نشان داده می شود. این گزینه به صورت دلخواه تنظیم می شود، ممکن است یک پارامتر null در متد وجود داشته باشد.
  • متد بدن - بدنه متد روش کار با دستورات را تعریف می کند.

مثال

/* قطعه کد حداقل بین دو عدد را برمی گرداند */ عمومی static int minFunction(int n1, int n2) (int min; if (n1 > n2) min = n2; other min = n1; return min; )

فراخوانی روش

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

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

  • یک دستور بازگشت اجرا می شود.
  • بریس مجعد بسته شدن انتهای روش رسیده است.

روش بازگشت void دستور را فراخوانی می کند. به یک مثال توجه کنید:

System.out.!");

روش بازگشت ارزش را می توان با مثال زیر نشان داد:

int result = sum(6, 9);

مثال زیر نحوه تعریف و فراخوانی یک متد در جاوا را نشان می دهد.

مثال

کلاس عمومی ExampleMinNumber ( public void main(string args) (int a = 11; int b = 6; int c = minFunction(a, b); System.out.println(" حداقل ارزش= " + c); ) /* حداقل دو عدد را برمی گرداند */ public static int minFunction(int n1, int n2) ( int min; if (n1 >

حداقل مقدار = 6

کلمه کلیدی void

کلمه کلیدی voidدر جاوا به ما اجازه می دهد تا متدهایی ایجاد کنیم که مقداری را بر نمی گرداند. در مثال زیر، روشی از نوع void در نظر گرفته ایم - methodRankPoints. متدهای جاوا void هیچ مقداری را بر نمی گرداند. فراخوانی یک متد نوع void توسط یک دستور انجام می شود، i.e. متدRankPoints(255.7);. این یک عبارت جاوا است که با یک نقطه ویرگول به پایان می رسد، همانطور که در مثال زیر نشان داده شده است:

مثال

کلاس عمومی ExampleVoid ( public static void main(String args) ( methodRankPoints(255.7); ) public static void methodRankPoints(double points) ( if (points >= 202.5) ( System.out.println ("Rank A1"); ) other if (امتیاز >= 122.4) ( System.out.println ("رتبه A2"); )دیگر ( System.out.println ("رتبه A3"); ) )

در نتیجه نتیجه زیر حاصل خواهد شد:

رتبه A1

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

هنگامی که فرآیند فراخوانی اجرا می شود، جاوا آرگومان هایی را ارسال می کند. این روش باید طبق ترتیب ارائه شده توسط پارامترهای مربوطه در مشخصات روش انجام شود. پارامترها را می توان با مقدار یا مرجع ارسال کرد.

در جاوا، عبور پارامترها توسط مقدار به معنای فراخوانی یک متد با یک پارامتر است. با توجه به این، مقدار آرگومان به پارامتر ارسال می شود.

مثال

برنامه زیر نمونه ای از ارسال یک پارامتر بر اساس مقدار را نشان می دهد. مقادیر آرگومان حتی پس از فراخوانی متد بدون تغییر باقی می مانند.

swapping کلاس عمومی مثال ( public static void main (string args) ( int a = 30; int b = 45; System.out.println ("قبل از عبور، مقادیر آرگومان های a = " + a + " و b = " + b )؛ // فراخوانی روش انتقال swapFunction(a, b)؛ System.out.println("\nاکنون، قبل و بعد از ارسال مقدار آرگومان ها")؛ System.out.println("بدون تغییر باقی ماند، a = " + a + " و b = " + b)؛ ) عمومی استاتیک swapfunction (int a, int b) ( System. out. println ("قبل از تعویض: a = " + a + " b = " + b )؛ // ارسال پارامترهای int c = a؛ a = b؛ b = c; System.out.println("پس از جایگزینی: a = " + a + " b = " + b); ) )

نتیجه زیر را می گیریم:

قبل از عبور، مقادیر آرگومان های a = 30 و b = 45 قبل از جایگزینی: a = 30 b = 45 پس از جایگزینی: a = 45 b = 30 اکنون، قبل و بعد از انتقال، مقادیر آرگومان ها بدون تغییر باقی ماندند، a = 30 و b = 45

روش اضافه بار

روش اضافه بار در جاوا- موردی که در کلاس دو یا چند متد با نام یکسان، اما پارامترهای متفاوت وجود دارد. این فرآیند با روش های فراگیر متفاوت است. هنگامی که متدها لغو می شوند، متد با همان نام، نوع، تعداد پارامترها و غیره مشخص می شود.

مثالی را که در بالا هنگام تعریف حداقل اعداد یک نوع عدد صحیح ارائه شد در نظر بگیرید. بنابراین فرض کنید می خواهیم حداقل تعداد یک نوع دوگانه را تعریف کنیم. در این صورت مفهوم اضافه بار برای ایجاد دو یا چند روش با نام یکسان اما پارامترهای متفاوت معرفی خواهد شد.

مثال بالا موارد فوق را نشان می دهد.

مثال

کلاس عمومی ExampleOverloading ( public static void main (string args) ( int a = 7; int b = 3; double c = 5.1; double d = 7.2; int result1 = minFunction(a, b); // تابع مشابه با پارامترهای دیگر double result2 = minFunction(c, d)؛ System.out.println ("حداقل مقدار = " + result1)؛ System.out.println("حداقل مقدار = " + result2); ) // برای int minFunction عمومی static ( int n1, int n2) ( int min; if (n1 > n2) min = n2; other min = n1; return min; ) // برای دو تابع دوگانه ثابت عمومی (double n1, double n2) ( double min; if ( n1 > n2) min = n2؛ در غیر این صورت min = n1؛ بازگشت حداقل؛ ))

در نتیجه نتیجه زیر حاصل خواهد شد:

حداقل مقدار = 3 حداقل مقدار = 5.1

روش های بارگذاری بیش از حد یک برنامه را خوانا می کند. بنابراین دو روش با نام یکسان اما پارامترهای متفاوت وجود دارد. در نتیجه، حداقل عدد int و عدد دوبل را دریافت کردیم.

استفاده از آرگومان های خط فرمان

در طول برنامه، ممکن است نیاز به انتقال اطلاعات خاصی داشته باشید. این را می توان در جاوا با ارسال آرگومان های خط فرمان به main() انجام داد.

در جاوا، یک آرگومان خط فرمان اطلاعاتی را نشان می دهد که بلافاصله پس از نام برنامه در خط فرمان هنگام اجرا می آید. دسترسی به آرگومان های خط فرمان در یک برنامه جاوا دشوار نیست. آنها به عنوان یک رشته در آرایه رشته ای که به main() منتقل می شوند ذخیره می شوند.

مثال

برنامه زیر تمام آرگومان های خط فرمان فراخوانی شده را نمایش می دهد.

CommandLine کلاس عمومی ( public static void main (string args) ( for(int i = 0; i

سعی کن اجرا کنی این برنامه، همانطور که در زیر نشان داده شده است:

$java CommandLine است خط فرمان 300 -200

در نتیجه نتیجه زیر حاصل خواهد شد:

args: این args است: خط فرمان args: args رشته: 300 args: -200

سازنده در جاوا

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

به طور معمول، یک سازنده در جاوا می تواند برای تنظیم مقدار اولیه برای متغیرهای نمونه تعریف شده توسط یک کلاس یا برای انجام هر روش راه اندازی دیگر لازم برای ایجاد یک شی کاملاً تشکیل شده استفاده شود.

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

مثال

مثال زیر استفاده از سازنده کلاس بدون پارامتر را نشان می دهد.

// سازنده ساده. کلاس MyClass (int x; // بعد سازنده MyClass() می آید (x = 10; ))

برای مقداردهی اولیه اشیا، باید مانند مثال زیر یک فراخوانی سازنده برقرار کنید.

کلاس عمومی ConsDemo ( عمومی استاتیک void main(String args) ( MyClass t1 = جدید MyClass(؛ MyClass t2 = New MyClass(); System.out.println(t1.x + " " + t2.x); ))

نتیجه را می گیریم:

سازنده پارامتری شده

اغلب، شما به سازنده ای نیاز دارید که یک یا چند پارامتر را بگیرد. افزودن پارامترها به سازنده مانند افزودن آنها به یک متد است، فقط باید آنها را بعد از نام سازنده در پرانتز قرار دهید.

مثال

// سازنده ساده. کلاس MyClass (int x; // زیر سازنده MyClass(int i) (x = i; ))

برای مقداردهی اولیه اشیا، باید سازنده را مانند مثال زیر فراخوانی کنید.

کلاس عمومی ConsDemo ( اصلی خالی ثابت عمومی (String args) ( MyClass t1 = MyClass جدید (10)؛ MyClass t2 = MyClass جدید (20); System.out.println (t1.x + " " + t2.x)؛ ) )

نتیجه زیر را می گیریم:

کلمه کلیدی این

کلمه کلیدی این- برای ارجاع به کلاس فعلی با یک متد نمونه یا سازنده استفاده می شود. با استفاده از این در جاوا، می توانید به نمونه های کلاس مانند سازنده ها، متغیرها و متدها مراجعه کنید.

توجه داشته باشید: کلمه کلیدیاین فقط در متدهای نمونه یا سازنده ها استفاده می شود.

به طور معمول، این کلمه کلیدی در جاوا برای موارد زیر استفاده می شود:

  • تمایز بین متغیرهای نمونه و متغیرهای محلی در صورتی که نام یکسانی داشته باشند، به عنوان بخشی از یک سازنده یا متد.
کلاس دانشجو (سن بین‌المللی؛ دانش‌آموز (سن بین‌المللی) (این سن = سن؛ ))
  • فراخوانی سازنده ای از یک نوع (سازنده پارامتری یا سازنده پیش فرض) از دیگری در یک کلاس. به این فرآیند فراخوانی سازنده صریح نیز می گویند.
کلاس دانش آموز ( سن دانش آموز () ( این (20); ) دانش آموز (سن بین سنی) (این. سن = سن؛ ) )

مثال

کلاس عمومی This_Example ( // مقدار اولیه متغیر num int num = 11; This_Example() ( System. out. println("این یک برنامه نمونه با کلمه کلیدی این است"); ) This_Example(int num) ( // فراخوانی پیش فرض سازنده this(); // اختصاص دادن متغیر محلی num به متغیر نمونه num this.num = num; ) public void greet() ( System.out.println ("سلام! به ProgLang خوش آمدید!")؛ ) public void print() (// متغیر محلی num int num = 20 // روش کلاس فراخوانی سلام این.greet() // چاپ متغیر محلی System.out.println("مقدار متغیر محلی num: " + num); // چاپ متغیر نمونه سیستم .out.println("مقدار متغیر نمونه num: " + this.num); ) public static void main(string args) (// Initialize This_Example class obj1 = new This_Example(); // فراخوانی روش چاپ obj1.print() // انتقال مقدار جدید متغیر num از سازنده پارامتر This_Example obj2 = new This_Example(30)؛ // فراخوانی مجدد متد print obj2.print(); ))

در نتیجه نتیجه زیر حاصل خواهد شد:

این یک برنامه نمونه با کلمه کلیدی this Hello است! به پروگلانگ خوش آمدید! مقدار متغیر محلی num: 22 مقدار متغیر نمونه num: 11 این یک برنامه نمونه با کلمه کلیدی this Hello! به پروگلانگ خوش آمدید! مقدار متغیر محلی num: 22 مقدار متغیر نمونه num: 30

آرگومان های متغیر (var-args)

JDK 1.5 و بالاتر به شما امکان می دهد تعداد متغیری از آرگومان های هم نوع را به یک متد ارسال کنید. یک پارامتر در یک متد به صورت زیر اعلام می شود:

TypeName... پارامترName

هنگام اعلان یک متد، نوع آن را با یک بیضی (...) مشخص می کنید. فقط یک پارامتر طول متغیر را می توان در یک متد مشخص کرد و این پارامتر باید آخرین پارامتر باشد. هر پارامتر منظم باید قبل از آن باشد.

مثال

کلاس عمومی VarargsDemo ( public static void main(string args) (// روش فراخوانی با متغیر args printMax(27, 11, 11, 5, 77.1); printMax(new double(10, 11, 12, 77, 71)); ) public static void printMax(double... اعداد) ( if (numbers.length == 0) ( System.out.println ("هیچ آرگومان تصویب نشد")؛ بازگشت؛ ) double result = اعداد؛ برای (int i = 1 ؛ i نتیجه) نتیجه = اعداد[i]؛ System.out.println("حداکثر مقدار" + نتیجه)؛ ) )

در نتیجه نتیجه زیر حاصل خواهد شد:

حداکثر مقدار 77.1 حداکثر مقدار 77.0

متد finalize().

متد finalize().- روشی که بلافاصله قبل از تخریب نهایی شی توسط زباله جمع کن فراخوانی می شود. (نهایی کننده). در جاوا می توان از finalize() برای اطمینان از تکمیل تمیز یک شی استفاده کرد.

به عنوان مثال، ما می توانیم از finalize() برای اطمینان از آن استفاده کنیم باز کردن فایل، متعلق به این شی، بسته شد.

برای افزودن نهایی کننده به یک کلاس، کافی است یک متد ()finalize در جاوا تعریف کنید. محیط اجرای جاوا این متد را درست قبل از پردازش یک شی از این کلاس فراخوانی می کند.

به عنوان بخشی از متد ()finalize، اقداماتی را که باید قبل از تخریب شیء انجام شود را مشخص می کنید.

به طور کلی، متد ()finalize به شکل زیر است:

Protected void finalize() (// نهایی‌سازی کد در اینجا)

در اینجا، کلمه کلیدی محافظت شده نشان دهنده یک مشخص کننده است که از دسترسی ()finalize توسط کد تعریف شده خارج از کلاس آن جلوگیری می کند.

این نشان می دهد که شما نمی توانید بدانید که ()finalize چگونه یا چه زمانی اجرا می شود. به عنوان مثال، اگر برنامه شما قبل از جمع آوری زباله خاتمه یابد، ()finalize اجرا نخواهد شد.

سازنده یک ساختار متد مانند است که هدف آن ایجاد یک نمونه از یک کلاس است. ویژگی های طراح:
  • نام سازنده باید با نام کلاس مطابقت داشته باشد (طبق قرارداد، حرف اول بزرگ است، معمولاً یک اسم).
  • یک سازنده در هر کلاس وجود دارد. حتی اگر یکی را ننوشتید، کامپایلر جاوا یک سازنده پیش‌فرض ایجاد می‌کند که خالی خواهد بود و کاری جز فراخوانی سازنده سوپرکلاس انجام نمی‌دهد.
  • سازنده مانند متد است، اما متد نیست، حتی عضوی از کلاس نیز در نظر گرفته نمی شود. بنابراین، نمی توان آن را در یک زیر کلاس به ارث برد یا لغو کرد.
  • سازندگان به ارث نمی رسند.
  • در یک کلاس چند سازنده وجود دارد. در این مورد گفته می شود که سازنده ها بیش از حد بارگذاری شده اند.
  • اگر کلاس سازنده ای را اعلام نکند، کامپایلر به طور خودکار یک سازنده بدون پارامتر به کد اضافه می کند.
  • سازنده نوع برگشتی ندارد، حتی نمی تواند نوع void باشد، اگر نوع void برگردانده شود، این دیگر یک سازنده نیست، بلکه یک متد است، با وجود همزمانی با نام کلاس.
  • دستور بازگشت در یک سازنده مجاز است، اما فقط خالی، بدون هیچ مقدار بازگشتی.
  • سازنده اجازه استفاده از اصلاح کننده های دسترسی را می دهد، می توانید یکی از اصلاح کننده ها را تنظیم کنید: عمومی، محافظت شده، خصوصی یا بدون اصلاح کننده.
  • یک سازنده نمی تواند اصلاح کننده های انتزاعی، نهایی، بومی، ایستا یا هماهنگ داشته باشد.
  • کلمه کلیدی this به سازنده دیگری در همان کلاس اشاره دارد. در صورت استفاده، ارجاع به آن باید اولین خط سازنده باشد.
  • کلمه کلیدی 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 ...)"); ) */اصلی خالی استاتیک عمومی (Args رشته) (DefaultDemo dd = DefaultDemo جدید () ;) ) نتیجه خروجی برنامه زمانی که سازنده بدون نظر است: DefaultDemo (int . . . . ) با این حال، در حالت رایج زمانی که سازنده در در کل کلاس، فراخوانی یک سازنده پیش‌فرض (بدون پارامتر) ضروری است، زیرا جایگزینی سازنده پیش‌فرض به صورت خودکار اتفاق می‌افتد.

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

اضافه بار سازنده

سازنده های یک کلاس می توانند نام یکسان و امضای متفاوتی داشته باشند. به این خاصیت همپوشانی یا اضافه بار می گویند. اگر یک کلاس چندین سازنده داشته باشد، آنگاه بار سازنده بیش از حد وجود دارد.

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

امضای سازنده تعداد و انواع پارامترها و توالی انواع آنها در لیست پارامترهای سازنده است. نوع بازگشت در نظر گرفته نشده است. سازنده هیچ پارامتری را بر نمی گرداند. این عبارت به نوعی توضیح می دهد که چگونه جاوا بین سازنده ها یا متدهای بارگذاری شده تمایز قائل می شود. جاوا روش های بارگذاری شده را نه بر اساس نوع بازگشتی، بلکه با تعداد، انواع و توالی انواع پارامترهای ورودی متمایز می کند. یک سازنده حتی نمی‌تواند یک نوع void را برگرداند، در غیر این صورت به یک متد معمولی تبدیل می‌شود، حتی اگر شبیه یک نام کلاس باشد. مثال زیر این موضوع را نشان می دهد. فایل VoidDemo.java کلاس VoidDemo ( /** * این یک سازنده است */ VoidDemo () ( System. out. println ("Constructor") ; ) void VoidDemo () ( System. out. println ("روش") ;) public static void main (String s) ( VoidDemo m = new VoidDemo () ; ) ) در نتیجه برنامه نمایش داده می شود: سازنده این یک بار دیگر ثابت می کند که سازنده یک متد بدون پارامترهای بازگشتی است. با این حال، یک سازنده را می‌توان یکی از سه اصلاح‌کننده عمومی، خصوصی یا محافظت شده در نظر گرفت. و مثال اکنون به این شکل خواهد بود: File VoidDemo2.java class VoidDemo2 ( /** * این یک سازنده است */عمومی VoidDemo2() ( System.out.println("Constructor") ;) /** * و این در حال حاضر یک روش عادی است، حتی با وجود شباهت با نام کلاس *، زیرا یک نوع بازگشتی باطل وجود دارد */ Private void VoidDemo2 () ( System. out. println ("روش" ) ; ) public static void main (String s ) ( VoidDemo2 m = new VoidDemo2 () ; ) ) مجاز به نوشتن دستور بازگشت در سازنده است، اما فقط خالی، بدون هیچ مقدار بازگشتی. فایل ReturnDemo.java کلاس ReturnDemo( /** * استفاده از دستور * return بدون پارامتر در سازنده مجاز است. */عمومی ReturnDemo () ( System. out. println ("Constructor") ; return; ) public void main (String s) (ReturnDemo r = ReturnDemo جدید () ; ) )

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

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

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

اساساً دو نوع پارامتر در زبان های برنامه نویسی وجود دارد:
  • انواع اولیه (اولیه)؛
  • ارجاعات شی
اصطلاح فراخوانی با مقدار به این معنی است که سازنده مقدار ارسال شده توسط ماژول فراخوان را دریافت می کند. در مقابل، فراخوانی با مرجع به این معنی است که سازنده آدرس متغیر را از ماژول فراخوان دریافت می کند. جاوا فقط از call by value استفاده می کند. بر اساس مقدار پارامتر و بر اساس مقدار مرجع پارامتر. جاوا از تماس با مرجع برای اشیا استفاده نمی کند (اگرچه بسیاری از برنامه نویسان و برخی از نویسندگان کتاب این ادعا را دارند). پارامترها هنگام ارسال اشیا در جاوا پیاده سازی می شوند نه از طریق لینک، آ با مقدار مرجع شی! در هر صورت، سازنده کپی هایی از مقادیر تمام پارامترها را دریافت می کند. یک سازنده نمی تواند با پارامترهای ورودی خود انجام دهد:
  • سازنده نمی تواند مقادیر پارامترهای ورودی انواع پایه (اولیه) را تغییر دهد.
  • سازنده نمی تواند مراجع پارامترهای ورودی را تغییر دهد.
  • سازنده نمی تواند ارجاعات پارامتر ورودی را دوباره به اشیاء جدید اختصاص دهد.
یک سازنده می تواند با پارامترهای ورودی خود انجام دهد:
  • وضعیت شی ارسال شده به عنوان پارامتر ورودی را تغییر دهید.
مثال زیر ثابت می کند که در جاوا، پارامترهای ورودی برای یک سازنده با مقدار یک مرجع شی ارسال می شود. این مثال همچنین نشان دهنده این واقعیت است که سازنده نمی تواند مراجع پارامترهای ورودی را تغییر دهد، اما در واقع مراجع کپی های پارامترهای ورودی را تغییر می دهد. File 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 همچنان به اشیاء قدیمی اشاره می کنند.

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

سازنده نمی تواند پارامترهای تصویب شده انواع پایه را تغییر دهد. با این حال، سازنده می تواند وضعیت شی ارسال شده به عنوان یک پارامتر را تغییر دهد. برای مثال، برنامه زیر را در نظر بگیرید: File Salary1.java class Salary1 ( Salary1 (int x) ( x = x * 3 ; System. out. println ("x=" + x) ; ) public static void main (String args ) ( مقدار int = 1000 ; Salary1 s1 = New Salary1 (value) ; System.out.println ("value=" + value) ; )) نتیجه خروجی برنامه: x= 3000 value= 1000 بدیهی است که این روش پارامتر نوع پایه را تغییر نخواهد داد. بنابراین، پس از فراخوانی سازنده، مقدار مقدار متغیر برابر با 1000 باقی می ماند. اساساً سه چیز اتفاق می افتد:
  1. متغیر x با یک کپی از مقدار پارامتر مقدار (یعنی عدد 1000) مقداردهی اولیه می شود.
  2. مقدار متغیر x سه برابر شده است - اکنون برابر با 3000 است. با این حال، مقدار مقدار متغیر 1000 باقی می ماند.
  3. سازنده خارج می شود و x دیگر استفاده نمی شود.
در مثال زیر، حقوق کارمند با ارسال مقدار مرجع شی به عنوان پارامتر به روش، با موفقیت سه برابر شده است. فایل Salary2.java class Salary2 ( مقدار int = 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. ارزش)؛ سیستم. بیرون println("s2.value="+ s2. ارزش)؛ )) نتیجه خروجی برنامه: s1. مقدار = 3000 s2. value= 1000 مقدار مرجع شی به عنوان پارامتر استفاده می شود. هنگام اجرای خط Salary2 s2 = 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 داشته باشد، سازنده با پارامتر ورودی دوگانه کار خواهد کرد. قبل از فراخوانی سازنده، متغیر i از نوع int به نوع double گسترش می‌یابد. در حالت مخالف، زمانی که متغیر i از نوع double باشد و سازنده فقط یک پارامتر int داشته باشد، در این وضعیت منجر به خطای کامپایل می شود.

تماس سازنده و اپراتور جدید

یک سازنده همیشه با عملگر جدید فراخوانی می شود. هنگامی که یک سازنده با عملگر جدید فراخوانی می شود، سازنده همیشه یک مرجع به یک شی جدید تولید می کند. غیرممکن است که سازنده را مجبور کنیم به جای ارجاع به یک شی جدید، یک مرجع به یک شی از قبل موجود تشکیل دهد، به جز جایگزینی شیء در حال بی‌سریال کردن. و با عملگر جدید، به جای ارجاع به یک شی جدید، نمی توان به یک شی از قبل موجود اشاره کرد. به عنوان مثال: فایل Salary3.java کلاس Salary3 ( مقدار int = 1000 ; Salary3 () ( ) Salary3 (Salary3 x) ( x. value = x. value * 3 ; ) public static void main (String args ) ( Salary3 s1 = new Salary3 () ; System. out. println ("اولین شیء ایجاد: " + s1. value) ; Salary3 s2 = New Salary3 (s1) ; System. out. println ("Second building: " + s2. value) ; System . out.println(+ s1.value) ;Salary3 s3 = Salary3(s1) جدید ;System.out.println("سومین ایجاد شی: " + s3.value) ;System.out.println( "چه اتفاقی افتاد با اولین شی؟:"+ s1. ارزش)؛ )) نتیجه خروجی برنامه:اولین ایجاد شی: 1000 ایجاد شی دوم: 1000 با اولین شی چه اتفاقی افتاده است؟ : 9000 ابتدا با خط Salary3 s1 = new Salary3(); یک شی جدید ایجاد می شود. علاوه بر این، در صورت استفاده از خط Salary3 s2 = Salary3(s1) جدید ; یا خطوط Salary3 s3 = New Salary3(s1) ; اگر بتوانیم یک مرجع به یک شی از قبل موجود ایجاد کنیم، s1.value s2.value و s3.value همان مقدار 1000 را ذخیره می کنند. در واقع در خط Salary3 s2 = Salary3(s1) جدید ; یک شی جدید برای متغیر s2 ایجاد می شود و وضعیت شی برای متغیر s1 با عبور مقدار مرجع شی آن در پارامتر سازنده تغییر می کند. این را می توان از نتایج خروجی مشاهده کرد. و هنگام اجرای خط Salary3 s3 = New Salary3(s1) ; یک شی جدید برای متغیر s3 ایجاد می شود و وضعیت شی برای متغیر s1 دوباره تغییر می کند.

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

بخش Creating an Object and Constructors اقدامات کلی را که هنگام ایجاد یک شی انجام می شود فهرست می کند. از جمله آنها فرآیندهای اولیه سازی فیلدهای کلاس و کار کردن سازنده کلاس هستند که به نوبه خود دارای یک نظم داخلی هستند:
  1. تمام فیلدهای داده با مقادیر پیش فرض خود (0، false یا null) مقداردهی اولیه می شوند.
  2. تمام اولیه سازهای فیلد و بلوک های اولیه به ترتیبی که در اعلان کلاس فهرست شده اند اجرا می شوند.
  3. اگر سازنده دیگری در خط اول یک سازنده فراخوانی شود، سازنده فراخوانی شده اجرا می شود.
  4. بدنه سازنده اجرا می شود.
سازنده باید با مقداردهی اولیه کار کند، زیرا در جاوا سه راه برای مقداردهی اولیه یک فیلد در یک کلاس وجود دارد:
  • یک مقدار در اعلان تعیین کنید.
  • تخصیص مقادیر در بلوک اولیه؛
  • مقدار آن را در سازنده تنظیم کنید.
به طور طبیعی، شما باید کد اولیه را طوری سازماندهی کنید که درک آن آسان باشد. کلاس زیر یک مثال است: کلاس 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 void sayHi () ( system. out. println ("Hi") ;) ) کلاس عمومی SubClass Example ( ) کلاس SubClass به طور خودکار متد sayHi() تعریف شده را به ارث می برد. کلاس والدین در عین حال، سازنده Example() کلاس والد توسط SubClass فرزند آن به ارث نمی رسد.

این کلمه کلیدی در سازنده ها

سازنده ها از این برای ارجاع به سازنده دیگری در همان کلاس، اما با لیست پارامترهای متفاوت استفاده می کنند. اگر سازنده از این کلمه کلیدی استفاده کند، باید در خط اول باشد، نادیده گرفتن این قانون منجر به خطای کامپایلر می شود. به عنوان مثال: فایل ThisDemo.java کلاس عمومی ThisDemo ( نام رشته؛ ThisDemo (رشته s) (نام = s؛ سیستم. خارج. println (نام)؛ ) ThisDemo () (این ("جان") ؛ ) عمومی استاتیک void main ( آرگ رشته ) ( ThisDemo td1 = ThisDemo جدید ("Mary" ) ؛ ThisDemo td2 = ThisDemo جدید () ; ) ) نتیجه خروجی برنامه: Mary John در این مثال، دو سازنده وجود دارد. اولی یک رشته آرگومان دریافت می کند. دومی هیچ آرگومان نمی گیرد، فقط سازنده اول را با استفاده از نام پیش فرض "جان" فراخوانی می کند. بنابراین، با استفاده از سازنده ها، می توانید مقادیر فیلد را به طور صریح و به طور پیش فرض مقداردهی اولیه کنید، که اغلب در برنامه ها ضروری است.

کلمه کلیدی فوق العاده در سازنده ها

سازنده ها از super برای فراخوانی سازنده سوپرکلاس استفاده می کنند. اگر سازنده از super استفاده می کند، پس این فراخوانی باید در خط اول باشد، در غیر این صورت کامپایلر خطا می دهد. در زیر مثالی آمده است: کلاس عمومی فایل SuperClassDemo.java SuperClassDemo ( SuperClassDemo () ( ) ) کلاس Child SuperClassDemo را گسترش می دهد ( Child () ( super () ; ) ) در این مثال ساده، سازنده Child() حاوی فراخوانی به super است. () که نمونه ای از کلاس SuperClassDemo، علاوه بر کلاس Child است. از آنجایی که super باید اولین دستوری باشد که در سازنده زیرکلاس اجرا می شود، این ترتیب همیشه یکسان است، صرف نظر از اینکه از () super استفاده شده باشد یا خیر. اگر از آن استفاده نشود، سازنده پیش‌فرض (بدون پارامتر) هر سوپرکلاس ابتدا با کلاس پایه شروع می‌شود. برنامه زیر نشان می دهد که سازنده ها چه زمانی اجرا می شوند. فایل Call.java //سوپرکلاس A را ایجاد کنیدکلاس A (A () ( System. out. println ("Inside A constructor.") ; ) ) //یک زیر کلاس B بسط دهنده کلاس A ایجاد کنیدکلاس B A (B () را گسترش می دهد ( System. out. println ("Inside B constructor.") ; ) ) //یک کلاس (C) توسعه دهنده کلاس B ایجاد کنیدکلاس C B (C () (System. out. println ("Inside C constructor.")) را گسترش می دهد. خروجی این برنامه:داخل یک سازنده. سازنده داخل B. داخل سازنده C. سازنده ها به ترتیب تبعیت کلاس فراخوانی می شوند. یک مقدار در این وجود دارد. از آنجایی که سوپرکلاس هیچ دانشی از هیچ زیر کلاسی ندارد، هر مقدار اولیه ای که برای انجام آن نیاز دارد جدا است. در صورت امکان، باید قبل از هر مقداردهی اولیه انجام شده توسط زیر کلاس باشد. به همین دلیل است که ابتدا باید انجام شود.

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

مکانیسم شناسایی نوع زمان اجرا یکی از اصول اصلی قدرتمند زبان جاوا است که چند شکلی را پیاده سازی می کند. با این حال، چنین مکانیزمی توسعه‌دهنده را در برابر ریخته‌گری نوع ناسازگار در برخی موارد بیمه نمی‌کند. رایج ترین مورد، دستکاری گروهی از اشیاء است که انواع مختلف آنها از قبل شناخته شده نیست و در زمان اجرا مشخص می شود. از آنجایی که خطاهای ناسازگاری نوع فقط می توانند در زمان اجرا نشان داده شوند، این امر یافتن و رفع آنها را دشوار می کند. معرفی انواع سفارشی در جاوا 2 5.0 تا حدی وقوع چنین خطاهایی را از زمان اجرا به زمان کامپایل سوق می دهد و ایمنی نوع گمشده را فراهم می کند. هنگام رفتن از نوع Object به نوع بتنی، نیازی به ریخته گری نوع صریح نیست. به خاطر داشته باشید که تایپ‌ترها فقط با اشیا کار می‌کنند و برای انواع داده‌های اولیه که خارج از درخت وراثت کلاس قرار دارند، اعمال نمی‌شوند. با انواع سفارشی، همه بازیگران به صورت خودکار و مخفی هستند. این به شما امکان می دهد در برابر عدم تطابق نوع محافظت کنید و از کدها بیشتر استفاده کنید. انواع سفارشی را می توان در سازنده ها استفاده کرد. سازنده ها می توانند سفارشی شوند حتی اگر کلاس آنها یک نوع سفارشی نباشد. به عنوان مثال: کلاس GenConstructor ( خصوصی 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 = GenConstructor جدید (100 ) ;GenConstructor gc2 = new GenConstructor(123.5F ) ;gc1.printValue () ;gc2.printValue () ;) ) تماس با هر

همانطور که می دانید یک شی نمونه ای از یک کلاس خاص است. برای ایجاد آن، از کلمه کلیدی جدید استفاده کنید، به عنوان مثال:
شخص دانشجو = شخص جدید ("مایک")
این کد یک شی جدید ایجاد می کند شخصو نام او آورده شده است مایک. خط" مایک» به عنوان آرگومان به سازنده مربوطه ارسال می شود شخص:

شخص (نام رشته) ( this.name = name; )

این سازنده به شما این امکان را می دهد که هنگام ایجاد یک شی، نام شخص را مشخص کنید.

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

  • سازنده ها همان نام کلاس را دارند.
  • سازنده ها، مانند متدها، فهرستی از پارامترهای پذیرفته شده دارند، اما نوع بازگشتی ندارند (حتی باطل).

در زیر مجموعه ای از 7 قانون اساسی برای کار با سازنده به شما این امکان را می دهد که کار آنها را به طور کامل درک کنید.

  1. سازندگان می توانند بیش از حد بارگذاری شوند:

این بدان معناست که یک کلاس می تواند سازنده های مختلفی داشته باشد اگر لیست پارامترهای آنها متفاوت باشد. مثلا:

کلاس Rectangle ( عرض بین‌المللی؛ ارتفاع بین‌المللی؛ مستطیل() (عرض = 1؛ ارتفاع = 1؛) این.عرض = عرض؛ این.ارتفاع = ارتفاع؛ ))

داشتن سه سازنده مختلف مستطیلشما می توانید یک شی جدید را به سه روش مختلف ایجاد کنید:

Rectangle rect1 = new Rectangle(); Rectangle rect2 = new Rectangle(10); Rectangle rect3 = New Rectangle(10,20);

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

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

برای مثال، اگر کلاس Rectangle را به صورت زیر بنویسیم:

کلاس Rectangle (عرض int، ارتفاع؛ int area() () int perimeter() ()

سپس کامپایلر به طور خودکار یک سازنده پیش فرض را وارد می کند: ectangle() ()

  1. اگر کلاس قبلاً سازنده داشته باشد، کامپایلر سازنده پیش فرض تولید نمی کند:

به مثال زیر توجه کنید:

کلاس Rectangle ( عرض بین‌المللی؛ ارتفاع بین‌المللی؛ مستطیل (عرض int) (این. عرض = عرض؛ این. ارتفاع = عرض؛ ) )

هنگام تلاش برای ایجاد یک شی جدید: Rectangle rect1 = new Rectangle(); کامپایلر یک خطا ایجاد می کند زیرا نمی تواند سازنده ای را بدون آرگومان پیدا کند.

  1. سازندگان به ارث نمی رسند:

بر خلاف متدها، سازنده ها ارثی نیستند. مثال:

کلاس Rectangle ( Rectangle (int width, int height) ( ) ) کلاس مربع گسترش می یابد Rectangle ( )

شما نمی توانید چیزی شبیه به این انجام دهید: مربع مربع = مربع جدید (10، 10);

  1. سازندگان می توانند خصوصی باشند!

می‌توانید یک سازنده را خصوصی کنید تا از ایجاد نمونه جدیدی از کلاس جلوگیری کنید. مزیت یک سازنده خصوصی چه می تواند باشد؟

در یک الگوی طراحی به نام سینگلتون، سازنده خصوصی برای اطمینان از اینکه همیشه فقط یک نمونه از کلاس وجود دارد استفاده می شود. کلاس سینگلتونیک روش ثابت برای به دست آوردن این نمونه منحصر به فرد ارائه می دهد.

  1. سازنده پیش‌فرض همان اصلاح‌کننده دسترسی کلاس را دارد:

هنگام نوشتن کلاس زیر: کلاس عمومی Person ( )

کامپایلر، هنگام درج یک سازنده پیش فرض، اصلاح کننده دسترسی مورد نیاز را نیز مشخص می کند: public Preson();

  1. خط اول هر سازنده باید سازنده سرباردار همان کلاس یا سازنده سوپرکلاس آن را فراخوانی کند:

اگر اینطور نباشد، کامپایلر به طور خودکار یک فراخوانی به سازنده سوپرکلاس بدون آرگومان super(); این ممکن است منجر به خطا شود زیرا ممکن است چنین سازنده ای در سوپرکلاس وجود نداشته باشد. مثال:

کلاس Parent ( Parent(int number) ( ) ) class Child Parent را گسترش می دهد ( Child() ( ) )

منجر به خطا می شود زیرا کامپایلر یک فراخوانی به () super را در سازنده کلاس وارد می کند کودک:

Child() (super();// کامپایلر اضافه شده)

با این حال، کامپایلر یک سازنده پیش فرض برای کلاس تزریق نمی کند والدین، زیرا در حال حاضر سازنده های دیگری وجود دارد.

سلام! امروز ما یک موضوع بسیار مهم را که مربوط به اشیاء ما است تجزیه و تحلیل خواهیم کرد. در اینجا بدون اغراق می توان گفت که شما هر روز از این دانش در کارهای واقعی استفاده خواهید کرد! در مورد صحبت خواهیم کرد سازندگان.

شاید برای اولین بار این اصطلاح را شنیده باشید، اما در واقع احتمالاً از سازنده استفاده کرده اید، فقط خودتان متوجه آن نشده اید :) بعداً این را خواهیم دید.

سازندگان چیست و چرا به آنها نیاز است؟

بیایید دو مثال را در نظر بگیریم. خودرو کلاس عمومی (مدل رشته‌ای؛ int maxSpeed؛ خالی ثابت عمومی (String args) (بوگاتی ماشین = ماشین جدید ()؛ بوگاتی. مدل = "بوگاتی ویرون"؛ بوگاتی. maxSpeed ​​= 407؛ )) ما ماشین خود را ایجاد کردیم و برای او مدل و حداکثر سرعت نصب کرد. با این حال، در یک پروژه واقعی، شی Car بدیهی است که 2 فیلد نخواهد داشت. و مثلا 16 فیلد! کلاس عمومی خودرو ( مدل رشته ای؛ //model int maxSpeed; //حداکثر سرعت//ظرفیت موتور//نام خانوادگی مالک//تعداد صندلی های داخل کابین String SalonMaterial; // مواد داخلیبیمه بولی; //آیا بیمه شده است//کشور سازنده inttrunkVolume; // حجم صندوق عقبشتاب داخلی تا 100 کیلومتر؛ خالی ثابت عمومی (String args) ( بوگاتی ماشین = ماشین جدید () ؛ بوگاتی. رنگ = "آبی"؛ بوگاتی. شتاب تا 100 کیلومتر = 3؛ بوگاتی. حجم موتور = 6.3؛ بوگاتی. سازنده کشور = "ایتالیا"؛ بوگاتی. مالک اولین کشور آمیگو"؛ بوگاتی. yearOfIssue = 2016؛ بوگاتی. بیمه = واقعی؛ بوگاتی. قیمت = 2000000؛ بوگاتی. است جدید = نادرست؛ بوگاتی. مکانهاInTheSalon = 2؛ بوگاتی. maxSpeed ​​= 407; مدل Vegatti = "yBatti" ) ) ما یک آبجکت جدید Car ایجاد کرده ایم. یک مشکل: ما 16 فیلد داریم، اما فقط 12 فیلد را مقداردهی اولیه کردیم! اکنون با کد امتحان کنید تا مواردی را که فراموش کرده ایم پیدا کنید! چندان آسان نیست، درست است؟ در چنین شرایطی، برنامه نویس به راحتی می تواند اشتباه کند و از مقداردهی اولیه یک فیلد صرف نظر کند. در نتیجه، رفتار برنامه اشتباه خواهد شد: کلاس عمومی Car ( مدل String; //model int maxSpeed; //حداکثر سرعتچرخ های int; //عرض دیسک double engineVolume; //ظرفیت موتوررنگ رشته; //color int yearOfIssue; //سال صدور String ownerFirstName; //نام مالک رشته مالک نام خانوادگی; //نام خانوادگی مالکقیمت طولانی؛ //قیمت بولی جدید است. //new or non int placesInTheSalon; //تعداد صندلی های داخل کابین String SalonMaterial; // مواد داخلیبیمه بولی; //آیا بیمه شده استتولید کننده رشته کشور; //کشور سازنده inttrunkVolume; // حجم صندوق عقبشتاب داخلی تا 100 کیلومتر؛ //شتاب 100 کیلومتر در ساعت در ثانیهخالی ثابت عمومی (String args) ( بوگاتی ماشین = ماشین جدید () ؛ بوگاتی. رنگ = "آبی"؛ بوگاتی. شتاب تا 100 کیلومتر = 3؛ بوگاتی. حجم موتور = 6.3؛ بوگاتی. سازنده کشور = "ایتالیا"؛ بوگاتی. مالک اولین کشور آمیگو"؛ بوگاتی. yearOfIssue = 2016؛ بوگاتی. بیمه = واقعی؛ بوگاتی. قیمت = 2000000؛ بوگاتی. است جدید = نادرست؛ بوگاتی. مکانهاInTheSalon = 2؛ بوگاتی. maxSpeed ​​= 407; مدل Vegatti = "yBatti" System. out.println( "مدل بوگاتی ویرون. اندازه موتور - "+ بوگاتی حجم موتور + "، صندوق عقب - " + بوگاتی. trunkVolume+ "، سالن ساخته شده از"+ بوگاتی salonMaterial + "، عرض دیسک - "+ بوگاتی چرخ + ". در سال 2018 توسط آقای" خریداری شد.+ بوگاتی صاحب نام)؛ ) ) خروجی کنسول: مدل بوگاتی ویرون. حجم موتور - 6.3 صندوق عقب - 0، داخل نول، عرض چرخ - 0. خریداری شده در سال 2018 توسط آقای nullخریدار شما که 2 میلیون دلار برای یک ماشین پرداخت کرده است، بدیهی است که نام بردن را دوست ندارد. آقا پوچ”! اما به طور جدی، در نتیجه، برنامه ما با یک شیء ساخته شده نادرست به پایان رسید - یک ماشین با عرض دیسک 0 (یعنی اصلا دیسکی وجود ندارد)، یک صندوق عقب گم شده، یک فضای داخلی ساخته شده از مواد ناشناخته، و حتی متعلق به به کسی که می داند فقط می توان تصور کرد که چگونه چنین خطایی می تواند هنگام اجرای برنامه "شلیک" کند! ما باید به نحوی از چنین موقعیت هایی اجتناب کنیم. لازم است که برنامه ما دارای یک محدودیت باشد: هنگام ایجاد یک شیء ماشین جدید برای آن همیشهباید مشخص شود، به عنوان مثال، مدل و حداکثر سرعت. در غیر این صورت، اجازه ایجاد شی را ندهید. این کار به راحتی قابل انجام است توابع سازنده. آنها نام خود را به دلیلی دریافت کردند. سازنده نوعی "اسکلت" کلاس را ایجاد می کند که هر شی جدید کلاس باید با آن مطابقت داشته باشد. برای راحتی، اجازه دهید به یک نسخه ساده تر از کلاس خودرو با دو فیلد بازگردیم. با توجه به نیازهای ما، سازنده کلاس Car به این صورت خواهد بود: عمومی Car (مدل رشته، int maxSpeed) (این . model = مدل؛ این . maxSpeed ​​= maxSpeed؛ ) و ایجاد شی اکنون به این شکل است: عمومی اصلی خالی ثابت (String args ) ( Car bugatti = ماشین جدید ("Bugatti Veyron" , 407 ) ;) سازنده چگونه ایجاد می شود. شبیه به یک متد معمولی است، اما نوع بازگشتی ندارد. در این حالت نام کلاس در سازنده و با حرف بزرگ نشان داده می شود. در مورد ما - ماشین. علاوه بر این، سازنده از یک کلمه کلیدی جدید برای شما استفاده می کند این. "this" در انگلیسی - "this one". این کلمه به موضوع خاصی اشاره دارد. کد موجود در سازنده: public Car (مدل رشته‌ای، int maxSpeed) (این . مدل = مدل؛ این آرگومان مدل، که در constructor.maxSpeed ​​برای این ماشین (که ما در حال ایجاد آن هستیم) مشخص شده است = به آرگومان maxSpeed ​​داده شده در سازنده." و به این ترتیب اتفاق افتاد: خودرو کلاس عمومی (مدل رشته‌ای؛ int maxSpeed؛ خودروی عمومی (مدل رشته‌ای، int maxSpeed) (این . مدل = مدل؛ این بوگاتی = خودروی جدید ("بوگاتی ویرون" , 407 ) ؛ سیستم. خروجی. println (مدل بوگاتی)؛ سیستم. بیرون. println (بوگاتی. maxSpeed)؛ ) ) خروجی کنسول: بوگاتی ویرون 407سازنده با موفقیت مقادیر مورد نظر را اختصاص داد. شاید متوجه شده باشید که یک سازنده بسیار شبیه به یک متد معمولی است! اینطور است: سازنده یک متد است، فقط کمی خاص :) درست مانند یک متد، ما پارامترهایی را به سازنده خود منتقل کردیم. و درست مانند فراخوانی یک متد، فراخوانی سازنده کار نخواهد کرد اگر آنها را مشخص نکنید: کلاس عمومی Car ( String model; int maxSpeed; public Car (String model, int maxSpeed) ( this . model = model; this . maxSpeed ​​= maxSpeed؛ ) public static void main (String args) ( Car bugatti = new car () ; //error! ) ) ببینید، سازنده کاری را انجام داد که ما می خواستیم به آن برسیم. حالا شما نمی توانید یک ماشین بدون سرعت یا بدون مدل بسازید! شباهت بین سازنده ها و متدها به همین جا ختم نمی شود. درست مانند روش ها، سازنده ها نیز می توانند باشند اضافه بار. تصور کنید که 2 گربه در خانه دارید. شما یکی از آنها را به عنوان یک بچه گربه گرفتید و خانه دوم را در بزرگسالی از خیابان آوردید و نمی دانید دقیقا چند سال دارد. این بدان معنی است که برنامه ما باید بتواند گربه های دو نوع ایجاد کند - با نام و سن برای گربه اول، و فقط با یک نام - برای گربه دوم. برای انجام این کار، سازنده را بارگذاری می کنیم: کلاس عمومی Cat ( نام رشته; int age; //برای اولین گربه //برای گربه دومعمومی گربه (نام رشته) (این . نام = نام؛ ) خلأ استاتیک عمومی اصلی (آرگس رشته) ( گربه بارسیک = گربه جدید («بارسیک» , 5 ) ؛ گربه streetCatNamedBob = گربه جدید («باب» ) ; ) ) به سازنده اصلی با پارامترهای "name" و "age"، ما یکی دیگر را فقط با نام اضافه کردیم. به همین ترتیب در درس های قبلی روش ها را اضافه بار کردیم. اکنون می توانیم هر دو نوع گربه را با موفقیت ایجاد کنیم :)

به یاد دارید، در ابتدای سخنرانی گفتیم که شما قبلاً از سازنده استفاده می کردید، اما خودتان متوجه آن نشدید؟ درست است. واقعیت این است که هر کلاس در جاوا یک به اصطلاح دارد سازنده پیش فرض. هیچ آرگومان نمی گیرد، اما هر بار که هر شیء از هر کلاس ایجاد می شود، شلیک می شود. کلاس عمومی گربه ( اصلی خالی ثابت عمومی (آرگس های رشته ای) ( لکه های گربه = گربه جدید () ؛ ) ) در نگاه اول، این نامرئی است. خوب یک شی درست کردند و ساختند، کار سازنده کجاست؟ برای مشاهده این موضوع، اجازه دهید مستقیماً یک سازنده خالی برای کلاس Cat بنویسیم و در داخل آن عبارتی را در کنسول نمایش دهیم. اگر نمایش داده شود، سازنده کار کرده است. کلاس عمومی گربه (گربه عمومی () (سیستم. خارج. println ("گربه ای ایجاد کرد!") ;) اصلی خالی ثابت عمومی (ارگ های رشته) ( لکه گیری گربه = گربه جدید () ; //این جایی است که سازنده پیش فرض کار می کرد } } خروجی کنسول: یک گربه خلق کرد! اینجا تاییدیه! سازنده پیش فرض همیشه به صورت نامرئی در کلاس های شما وجود دارد. اما باید یک ویژگی دیگر آن را بدانید. هنگامی که سازنده ای با آرگومان ایجاد می کنید، سازنده پیش فرض از کلاس ناپدید می شود.اثبات این، در واقع، ما قبلا در بالا دیده ایم. در اینجا در این کد: کلاس عمومی Cat ( نام رشته؛ سن int؛ عمومی گربه (نام رشته، سن int) (این . نام = نام؛ این . سن = سن؛ ) اصلی خالی ثابت عمومی (آرگس رشته) ( Cat barsik = new Cat () ; //error! ) ) ما نمی‌توانستیم گربه‌ای بدون نام و سن بسازیم زیرا یک سازنده برای Cat تعریف کردیم: رشته + شماره. سازنده پیش فرض درست بعد از آن ناپدید شداز کلاس بنابراین، حتما به خاطر داشته باشید: اگر به چندین سازنده در کلاس خود نیاز دارید، از جمله خالی، باید به طور جداگانه ایجاد شود. به عنوان مثال، ما در حال ایجاد یک برنامه برای یک کلینیک دامپزشکی هستیم. کلینیک ما می خواهد کارهای خوبی انجام دهد و به گربه های بی خانمان کمک کند، که ما نه نام و نه سن آنها را نمی دانیم. سپس کد ما باید شبیه این باشد: کلاس عمومی Cat ( نام رشته; int age; //برای گربه های خانگیگربه عمومی (نام رشته، سن int) (این . نام = نام؛ این . سن = سن؛ ) //برای گربه های خیابانی public Cat () ( ) public static void main (String args) ( Cat barsik = New Cat ("Barsik" , 5 ) ; Cat streetCat = New Cat () ; ) ) حالا که به صراحت سازنده پیش فرض را نوشته ایم، می توانیم ایجاد گربه از هر دو نوع :) برای یک سازنده (مانند هر روش دیگری)، ترتیب آرگومان ها بسیار مهم است.بیایید آرگومان های نام و سن را در سازنده خود عوض کنیم. کلاس عمومی گربه (نام رشته؛ سن بین‌المللی؛ گربه عمومی (سن int، نام رشته) (این . نام = نام؛ این . سن = سن؛ ) اصلی خالی ثابت عمومی (آرگس رشته) ( گربه بارسیک = گربه جدید ("بارسیک" " , 10 ) ; //error! ) ) خطا! سازنده به وضوح توضیح می دهد: هنگام ایجاد یک شی Cat، باید از آن عبور کرد شماره و رشته، به ترتیب. بنابراین، کد ما کار نمی کند. حتماً این را در نظر داشته باشید و هنگام ایجاد کلاس‌های خود این را در نظر داشته باشید: عمومی Cat (نام رشته، سن int) (این . نام = نام؛ این . سن = سن؛ ) گربه عمومی (int age، نام رشته) (این . سن = سن؛ این نام = نام؛ ) این دو سازنده کاملاً متفاوت هستند! اگر پاسخ سوال را در یک جمله بیان کنید چرا به سازنده نیاز دارید؟، می توانی بگویی: برای اطمینان از اینکه اشیاء همیشه در وضعیت صحیح قرار دارند. هنگامی که از سازنده ها استفاده می کنید، همه متغیرهای شما به درستی مقداردهی اولیه می شوند و هیچ ماشینی با سرعت 0 و سایر اشیاء "اشتباه" در برنامه وجود نخواهد داشت. استفاده از آنها در درجه اول برای خود برنامه نویس بسیار سودمند است. اگر خودتان فیلدها را مقداردهی اولیه کنید، خطر زیادی وجود دارد که چیزی را از دست بدهید و اشتباه کنید. اما در مورد سازنده این اتفاق نمی افتد: اگر همه آرگومان های مورد نیاز را به آن منتقل نکنید یا انواع آنها را با هم مخلوط نکنید، کامپایلر بلافاصله خطا می دهد. به طور جداگانه قابل ذکر است که در داخل سازنده نباید منطق برنامه خود را قرار دهید. برای این، شما در اختیار دارید مواد و روش ها، که در آن می توانید تمام عملکردهای مورد نیاز خود را شرح دهید. بیایید ببینیم که چرا منطق سازنده ایده بدی است: کلاس عمومی CarFactory (نام رشته؛ سن int؛ int carsCount؛ عمومی CarFactory (نام رشته، سن int، int carsCount) (این . نام = نام؛ این . سن = سن؛ این. carsCount = carsCount;system.out.println( "او تاسیس شد" "به طور متوسط ​​او تولید می کند"+ (this . carsCount/ this . age) + "cars in year" ) ; ) public static void main (String args) ( CarFactory ford = new CarFactory ("Ford" , 115 , 50000000 ; ) ) ما یک کلاس داریم کارخانه ماشین، در توصیف یک کارخانه خودروسازی. در داخل سازنده، تمام فیلدها را مقداردهی اولیه می کنیم و منطق را در اینجا قرار می دهیم: برخی از اطلاعات مربوط به کارخانه را در کنسول چاپ کنید. به نظر می رسد هیچ مشکلی در این مورد وجود ندارد، برنامه کاملاً کار می کرد. خروجی کنسول: کارخانه خودروسازی ما فورد نام دارد و 115 سال پیش تاسیس شد در آن زمان 50000000 خودرو تولید کرد به طور متوسط ​​سالانه 434782 خودرو تولید کرد.اما در واقع ما یک بمب ساعتی کار گذاشته ایم. و چنین کدهایی به راحتی می تواند منجر به خطا شود. تصور کنید که اکنون ما در مورد فورد صحبت نمی کنیم، بلکه در مورد کارخانه جدید "Amigo Motors" صحبت می کنیم، که کمتر از یک سال است که وجود دارد و 1000 خودرو تولید کرده است: کلاس عمومی CarFactory ( نام رشته؛ int age؛ int carsCount؛ public CarFactory (String name, int age, int carsCount) ( این . نام = نام؛ این . سن = سن؛ این . carsCount = carsCount؛ System. out. println ( "کارخانه ماشین ما نام دارد"+ این نام)؛ سیستم. بیرون println( "او تاسیس شد"+ این سن + "سال پیش" ) ; سیستم. بیرون println( "در این مدت تولید شد"+ این carsCount + "cars" ) ; سیستم. بیرون println( "به طور متوسط ​​او تولید می کند"+ (this . carsCount/ this . age) + "cars in year" ) ; ) اصلی خالی استاتیک عمومی (String args) ( CarFactory ford = new CarFactory ("Amigo Motors" , 0 , 1000 ) ) ) خروجی کنسول: کارخانه خودروسازی ما Amigo Motors Exception در موضوع "اصلی" java.lang.ArithmeticException: / توسط صفر 0 سال پیش تاسیس شد در این مدت، 1000 خودرو در CarFactory تولید کرد. (CarFactory.java:15) در CarFactory.main (CarFactory.java:23) فرآیند با کد خروج 1 به پایان رسیدما رسیدیم! این برنامه با یک خطای عجیب به پایان رسید. می توانید حدس بزنید دلیل چیست؟ دلیل آن در منطقی است که در سازنده قرار داده ایم. به طور خاص، در این خط: سیستم. بیرون println( "به طور متوسط ​​او تولید می کند"+ (this . carsCount/ this . age) + "cars in year" ) ; در اینجا ما یک محاسبه انجام می دهیم و تعداد ماشین های تولید شده را بر سن کارخانه تقسیم می کنیم. و از آنجایی که کارخانه ما جدید است (یعنی 0 ساله است) نتیجه تقسیم بر 0 است که در ریاضیات ممنوع است. در نتیجه برنامه با یک خطا خاتمه می یابد. چگونه باید انجام می دادیم؟تمام منطق را به یک متد جداگانه منتقل کنید و آن را به عنوان مثال printFactoryInfo() صدا بزنید. شما می توانید آن را به عنوان یک آبجکت CarFactory به عنوان پارامتر ارسال کنید. شما همچنین می توانید تمام منطق را در آنجا قرار دهید، و در همان زمان - پردازش خطاهای احتمالی، مانند ما با سال صفر. به هر کدام مال خودش سازندگان برای تنظیم صحیح وضعیت یک شی مورد نیاز هستند.برای منطق تجاری، ما روش هایی داریم. یکی را با دیگری مخلوط نکنید. در اینجا چند پیوند مفید وجود دارد که می توانید در مورد سازنده ها بیشتر بخوانید: