JavaRush /جاوا بلاگ /Random-UR /کلاس کنسٹرکٹرز۔ Java JDK 1.5
articles
سطح

کلاس کنسٹرکٹرز۔ Java JDK 1.5

گروپ میں شائع ہوا۔
کلاس کنسٹرکٹرز۔  Java JDK 1.5 - 1

کنسٹرکٹرز کے بارے میں عمومی معلومات

Конструкторایک طریقہ کار کی طرح ایک ڈھانچہ ہے، جس کا مقصد کلاس کی مثال بنانا ہے۔ ڈیزائنر کی خصوصیات:
  • کنسٹرکٹر کا نام کلاس کے نام سے مماثل ہونا چاہیے (کنونشن کے مطابق، پہلا حرف بڑا ہوتا ہے، عام طور پر ایک اسم)؛
  • کسی بھی کلاس میں ایک کنسٹرکٹر ہوتا ہے۔ یہاں تک کہ اگر آپ ایک نہیں لکھتے ہیں، تو جاوا کمپائلر ایک ڈیفالٹ کنسٹرکٹر بنائے گا، جو خالی ہوگا اور سپر کلاس کنسٹرکٹر کو کال کرنے کے علاوہ کچھ نہیں کرے گا۔
  • ایک کنسٹرکٹر ایک طریقہ کی طرح ہے، لیکن یہ ایک طریقہ نہیں ہے، اسے کلاس کا رکن بھی نہیں سمجھا جاتا ہے. لہذا، اسے ذیلی طبقے میں وراثت یا اوور رائڈ نہیں کیا جا سکتا۔
  • تعمیر کنندگان کو وراثت میں نہیں ملا۔
  • ایک کلاس میں کئی کنسٹرکٹر ہو سکتے ہیں۔ اس صورت میں، کنسٹرکٹرز کو اوورلوڈ کہا جاتا ہے۔
  • اگر کوئی کلاس کنسٹرکٹر کی وضاحت نہیں کرتی ہے، تو کمپائلر خود بخود کوڈ میں پیرامیٹر لیس کنسٹرکٹر کو شامل کرتا ہے۔
  • کنسٹرکٹر کے پاس واپسی کی قسم نہیں ہوتی ہے؛ یہ ایک قسم بھی نہیں ہوسکتی ہے void؛ اگر ایک قسم کو واپس کیا جاتا ہے void، تو کلاس کے نام کے ساتھ اتفاق کے باوجود یہ اب کنسٹرکٹر نہیں بلکہ ایک طریقہ ہے۔
  • آپریٹر کو کنسٹرکٹر میں اجازت ہے return، لیکن صرف خالی، بغیر کسی واپسی کی قیمت کے؛
  • کنسٹرکٹر رسائی موڈیفائر کے استعمال کی اجازت دیتا ہے؛ آپ ترمیم کرنے والوں میں سے ایک سیٹ کر سکتے ہیں: public, protected, privateیا بغیر کسی ترمیم کنندہ کے۔
  • ایک کنسٹرکٹر میں ترمیم کرنے والے نہیں ہو سکتے abstract, final, native, staticor synchronized;
  • کلیدی لفظ thisاسی کلاس میں کسی دوسرے کنسٹرکٹر کا حوالہ دیتا ہے۔ اگر استعمال کیا جاتا ہے، تو اس کی کال کنسٹرکٹر کی پہلی لائن ہونی چاہیے۔
  • کلیدی لفظ superپیرنٹ کلاس کے کنسٹرکٹر کو کہتے ہیں۔ اگر استعمال کیا جائے تو، اس کا حوالہ کنسٹرکٹر کی پہلی لائن ہونا چاہیے۔
  • اگر کنسٹرکٹر آبائی طبقے کے کنسٹرکٹر کو کال نہیں کرتا ہے super(دلائل کے ساتھ یا اس کے بغیر)، کمپائلر خود بخود کوڈ کو شامل کر دیتا ہے تاکہ اسٹیسٹر کلاس کے کنسٹرکٹر کو بغیر کسی دلیل کے کال کیا جا سکے۔

ڈیفالٹ کنسٹرکٹر

کسی بھی کلاس میں ایک کنسٹرکٹر ہوتا ہے۔ یہاں تک کہ اگر آپ ایک نہیں لکھتے ہیں، جاوا کمپائلر ایک ڈیفالٹ کنسٹرکٹر بنائے گا۔ یہ کنسٹرکٹر خالی ہے اور سپر کلاس کنسٹرکٹر کو کال کرنے کے علاوہ کچھ نہیں کرتا ہے۔ وہ. اگر آپ لکھتے ہیں:
public class Example {}
پھر یہ لکھنے کے مترادف ہے:
public class Example
{
     Example()
     {
          super;
     }
}
اس صورت میں، آباؤ اجداد کی کلاس واضح طور پر متعین نہیں کی گئی ہے، اور بطور ڈیفالٹ، تمام جاوا کلاسز کلاس کی وارث ہوتی ہیں، 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۔ اس صورت میں، پیرامیٹر کی فہرست کے بغیر ایک کنسٹرکٹر استعمال کیا جاتا ہے۔

اوورلوڈنگ کنسٹرکٹرز

ایک ہی کلاس کے کنسٹرکٹرز کا ایک ہی نام اور مختلف دستخط ہو سکتے ہیں۔ اس خاصیت کو امتزاج یا اوور لوڈنگ کہا جاتا ہے۔ اگر ایک کلاس میں ایک سے زیادہ کنسٹرکٹرز ہیں، تو کنسٹرکٹر اوورلوڈنگ موجود ہے۔

پیرامیٹرائزڈ کنسٹرکٹرز

کنسٹرکٹر کے دستخط پیرامیٹرز کی تعداد اور اقسام کے ساتھ ساتھ کنسٹرکٹر پیرامیٹرز کی فہرست میں ان کی اقسام کی ترتیب ہے۔ واپسی کی قسم کو مدنظر نہیں رکھا گیا ہے۔ کنسٹرکٹر کوئی پیرامیٹرز واپس نہیں کرتا ہے۔ یہ بیان ایک لحاظ سے وضاحت کرتا ہے کہ جاوا کس طرح اوورلوڈ کنسٹرکٹرز یا طریقوں کے درمیان فرق کرتا ہے۔ Java اوور لوڈ شدہ طریقوں کو ان کی واپسی کی قسم سے نہیں بلکہ ان پٹ پیرامیٹرز کی قسموں کی تعداد، اقسام اور ترتیب سے ممتاز کرتا ہے۔ ایک کنسٹرکٹر ایک قسم کو بھی واپس نہیں کر سکتا 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۔ اور مثال اب اس طرح نظر آئے گی: فائلVoidDemo2.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

کنسٹرکٹر کو بھیجے گئے پیرامیٹرز کو تبدیل کرنا۔

کنسٹرکٹر بنیادی اقسام کے منظور شدہ پیرامیٹرز میں ترمیم نہیں کر سکتا۔ تاہم، کنسٹرکٹر پیرامیٹر کے طور پر پاس کردہ آبجیکٹ کی حالت میں ترمیم کر سکتا ہے۔ مثال کے طور پر، درج ذیل پروگرام پر غور کریں: فائلSalary1.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، غلط، یا کالعدم) پر شروع کیا جاتا ہے۔
  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()جو SuperClassDemoکلاس کے علاوہ کلاس کی ایک مثال بناتا ہے Child۔ کیونکہ superیہ سب کلاس کنسٹرکٹر میں پہلا بیان ہونا چاہیے، یہ آرڈر ہمیشہ ایک جیسا ہوتا ہے اور اس پر منحصر نہیں ہوتا ہے کہ آیا super()۔ اگر اسے استعمال نہیں کیا جاتا ہے، تو ہر سپر کلاس کا ڈیفالٹ (کوئی پیرامیٹر نہیں) کنسٹرکٹر، جو کہ بیس کلاس سے شروع ہوتا ہے، سب سے پہلے عمل میں لایا جائے گا۔ مندرجہ ذیل پروگرام ظاہر کرتا ہے جب کنسٹرکٹرز کو پھانسی دی جاتی ہے۔ فائل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.
تعمیر کنندگان کو طبقاتی ماتحتی کی ترتیب سے بلایا جاتا ہے۔ یہ کچھ معنی رکھتا ہے۔ چونکہ سپر کلاس کو کسی بھی ذیلی طبقے کا کوئی علم نہیں ہے، اس لیے اسے انجام دینے کے لیے کوئی بھی ابتدا الگ ہے۔ اگر ممکن ہو تو، اسے ذیلی طبقے کے ذریعہ انجام دی جانے والی کسی بھی ابتداء سے پہلے ہونا چاہئے۔ اس لیے اسے پہلے کرنا چاہیے۔

مرضی کے مطابق کنسٹرکٹرز

رن ٹائم قسم کی شناخت کا طریقہ کار جاوا زبان کے طاقتور بنیادی اصولوں میں سے ایک ہے جو پولیمورفزم کو نافذ کرتا ہے۔ تاہم، اس طرح کا طریقہ کار کچھ معاملات میں ڈویلپر کو غیر مطابقت پذیر قسم کے کاسٹنگ سے محفوظ نہیں رکھتا ہے۔ سب سے عام معاملہ اشیاء کے گروپ کی ہیرا پھیری ہے، جن کی مختلف اقسام پہلے سے معلوم نہیں ہوتیں اور رن ٹائم پر طے کی جاتی ہیں۔ چونکہ قسم کی عدم مطابقت سے وابستہ غلطیاں صرف رن ٹائم مرحلے پر ظاہر ہو سکتی ہیں، اس لیے انہیں تلاش کرنا اور ختم کرنا مشکل ہو جاتا ہے۔ Java 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