CodeGym /جاوا بلاگ /Random-UR /حاصل کرنے والے اور سیٹ کرنے والے
John Squirrels
سطح
San Francisco

حاصل کرنے والے اور سیٹ کرنے والے

گروپ میں شائع ہوا۔
ہیلو! پچھلے لیکشنز میں، آپ پہلے ہی سیکھ چکے ہیں کہ طریقوں اور فیلڈز کے ساتھ اپنی مکمل کلاسز کا اعلان کیسے کریں۔ آج کے سبق میں، ہم جاوا میں Getters اور Setters کے بارے میں بات کریں گے۔ یہ سنجیدہ پیش رفت ہے، شاباش! لیکن اب مجھے آپ کو ایک ناخوشگوار سچ بتانا ہے۔ ہم نے اپنی کلاسوں کا صحیح اعلان نہیں کیا! کیوں؟ پہلی نظر میں، درج ذیل کلاس میں کوئی غلطی نہیں ہے:
public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}
لیکن یہ کرتا ہے. تصور کریں کہ آپ کام پر بیٹھے ہیں اور بلیوں کی نمائندگی کے لیے یہ کیٹ کلاس لکھیں۔ اور پھر تم گھر جاؤ۔ جب آپ چلے جاتے ہیں، ایک اور پروگرامر کام پر آتا ہے۔ وہ اپنی مین کلاس بناتا ہے، جہاں وہ آپ کی لکھی ہوئی کیٹ کلاس کو استعمال کرنا شروع کر دیتا ہے۔
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
اس سے کوئی فرق نہیں پڑتا کہ اس نے ایسا کیوں کیا اور یہ کیسے ہوا (شاید وہ لڑکا تھکا ہوا ہو یا کافی نیند نہ آئی ہو)۔ کچھ اور اہم ہے: ہماری موجودہ کیٹ کلاس فیلڈز کو بالکل پاگل اقدار تفویض کرنے کی اجازت دیتی ہے۔ نتیجے کے طور پر، پروگرام میں ایک غلط حالت والی اشیاء ہیں (جیسے یہ بلی جو -1000 سال پرانی ہے)۔ تو ہم نے اپنی کلاس کا اعلان کرتے وقت کیا غلطی کی؟ ہم نے اپنی کلاس کا ڈیٹا بے نقاب کیا۔ نام، عمر اور وزن کے شعبے عوامی ہیں۔ ان تک پروگرام میں کہیں بھی رسائی حاصل کی جا سکتی ہے: بس ایک کیٹ آبجیکٹ بنائیں اور کسی بھی پروگرامر کو ڈاٹ ( . ) آپریٹر کے ذریعے اپنے ڈیٹا تک براہ راست رسائی حاصل ہوتی ہے۔
Cat cat = new Cat();
cat.name = "";
یہاں ہم براہ راست نام کی فیلڈ تک رسائی حاصل کر رہے ہیں اور اس کی قدر کو ترتیب دے رہے ہیں۔ ہمیں کسی نہ کسی طرح اپنے ڈیٹا کو غیر مناسب بیرونی مداخلت سے بچانے کی ضرورت ہے۔ ہمیں ایسا کرنے کی کیا ضرورت ہے؟ سب سے پہلے، تمام مثال کے متغیرات (فیلڈز) کو پرائیویٹ موڈیفائر کے ساتھ نشان زد کیا جانا چاہیے۔ پرائیویٹ جاوا میں سب سے سخت رسائی ترمیم کنندہ ہے۔ ایک بار جب آپ یہ کر لیتے ہیں، تو کیٹ کلاس کے فیلڈز کلاس سے باہر قابل رسائی نہیں ہوں گے۔
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";//error! The Cat class's name field is private!
   }
}
مرتب کرنے والا اسے دیکھتا ہے اور فوری طور پر ایک غلطی پیدا کرتا ہے۔ اب کھیت ایک طرح سے محفوظ ہیں۔ لیکن یہ پتہ چلتا ہے کہ ہم نے رسائی کو شاید بہت سختی سے بند کر دیا ہے: آپ پروگرام میں موجود بلی کا وزن حاصل نہیں کر سکتے، چاہے آپ کو ضرورت ہو۔ یہ بھی آپشن نہیں ہے۔ جیسا کہ یہ ہے، ہماری کلاس بنیادی طور پر ناقابل استعمال ہے۔ مثالی طور پر، ہمیں کسی قسم کی محدود رسائی کی اجازت دینے کی ضرورت ہے:
  • دوسرے پروگرامرز کو بلی کی اشیاء بنانے کے قابل ہونا چاہئے۔
  • انہیں موجودہ اشیاء سے ڈیٹا پڑھنے کے قابل ہونا چاہئے (مثال کے طور پر، موجودہ بلی کا نام یا عمر حاصل کریں)
  • فیلڈ ویلیوز کو تفویض کرنا بھی ممکن ہونا چاہیے۔ لیکن ایسا کرنے میں، صرف درست اقدار کی اجازت ہونی چاہیے۔ ہماری اشیاء کو غلط اقدار سے محفوظ کیا جانا چاہئے (جیسے عمر = -1000، وغیرہ)۔
یہ ضروریات کی ایک مہذب فہرست ہے! حقیقت میں، یہ سب آسانی سے حاصل کیا جاتا ہے خاص طریقوں سے جسے گیٹرز اور سیٹرز کہتے ہیں۔
حاصل کرنے والے اور ترتیب دینے والے - 2
یہ نام "get" (یعنی "کسی فیلڈ کی ویلیو حاصل کرنے کا طریقہ") اور "set" (یعنی "کسی فیلڈ کی ویلیو سیٹ کرنے کا طریقہ") سے آتے ہیں۔ آئیے دیکھتے ہیں کہ وہ ہماری کیٹ کلاس میں کیسے نظر آتے ہیں :
public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       this.weight = weight;
   }
}
جیسا کہ آپ دیکھ سکتے ہیں، وہ کافی سادہ لگتے ہیں :) ان کے نام اکثر "get"/"set" کے علاوہ متعلقہ فیلڈ کے نام پر مشتمل ہوتے ہیں۔ مثال کے طور پر، getWeight() طریقہ اس چیز کے لیے ویٹ فیلڈ کی قدر لوٹاتا ہے جس پر اسے بلایا جاتا ہے۔ یہاں یہ ہے کہ یہ ایک پروگرام میں کیسا لگتا ہے:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       String smudgeName = smudge.getName();
       int smudgeAge = smudge.getAge();
       int smudgeWeight = smudge.getWeight();

       System.out.println("Cat's name: " + smudgeName);
       System.out.println("Cat's age: " + smudgeAge);
       System.out.println("Cat's weight: " + smudgeWeight);
   }
}
کنسول آؤٹ پٹ:
Cat's name: Smudge
Cat's age: 5
Cat's weight: 4
اب ایک اور کلاس ( Main ) Cat فیلڈز تک رسائی حاصل کر سکتی ہے، لیکن صرف گیٹرز کے ذریعے۔ نوٹ کریں کہ حاصل کرنے والوں کے پاس عوامی رسائی میں ترمیم کرنے والا ہوتا ہے، یعنی وہ پروگرام میں کہیں سے بھی دستیاب ہوتے ہیں۔ لیکن اقدار کو تفویض کرنے کے بارے میں کیا خیال ہے؟ سیٹر کے طریقے یہی ہیں۔
public void setName(String name) {
   this.name = name;
}
جیسا کہ آپ دیکھ سکتے ہیں، وہ بھی سادہ ہیں. ہم Cat آبجیکٹ پر setName() طریقہ کو کال کرتے ہیں، ایک سٹرنگ کو دلیل کے طور پر پاس کرتے ہیں، اور اسٹرنگ کو آبجیکٹ کے نام کی فیلڈ میں تفویض کیا جاتا ہے۔
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);

       System.out.println("Cat's original name: " + smudge.getName());
       smudge.setName("Mr. Smudge");
       System.out.println("Cat's new name: " + smudge.getName());
   }
}
یہاں ہم گیٹرز اور سیٹرز دونوں استعمال کر رہے ہیں۔ سب سے پہلے، ہم بلی کا اصل نام حاصل کرنے اور ظاہر کرنے کے لیے گیٹر کا استعمال کرتے ہیں۔ پھر، ہم ایک نیا نام ("مسٹر سمج") تفویض کرنے کے لیے سیٹر کا استعمال کرتے ہیں۔ اور پھر ہم نام حاصل کرنے کے لیے ایک بار پھر گیٹر کا استعمال کرتے ہیں (یہ چیک کرنے کے لیے کہ آیا یہ واقعی بدل گیا ہے)۔ کنسول آؤٹ پٹ:
Cat's original name: Smudge
Cat's new name: Mr. Smudge
تو کیا فرق ہے؟ ہم اب بھی فیلڈز کو غلط اقدار تفویض کر سکتے ہیں چاہے ہمارے پاس سیٹٹرز ہوں:
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
کنسول آؤٹ پٹ:
Smudge's age: -1000 years
فرق یہ ہے کہ سیٹر ایک مکمل طریقہ ہے۔ اور فیلڈ کے برعکس، ایک طریقہ آپ کو ناقابل قبول اقدار کو روکنے کے لیے ضروری تصدیقی منطق لکھنے دیتا ہے۔ مثال کے طور پر، آپ آسانی سے منفی نمبر کو عمر کے طور پر تفویض ہونے سے روک سکتے ہیں:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age can't be negative!");
   }
}
اور اب ہمارا کوڈ صحیح طریقے سے کام کرتا ہے!
public class Main {

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5, 4);
       smudge.setAge(-1000);

       System.out.println("Smudge's age: " + smudge.getAge());
   }
}
کنسول آؤٹ پٹ:
Error! Age can't be negative!
Smudge's age: 5 years
سیٹر کے اندر، ہم نے ایک پابندی بنائی جس نے ہمیں غلط ڈیٹا سیٹ کرنے کی کوشش سے محفوظ رکھا۔ Smudge کی عمر تبدیل نہیں ہوئی تھی۔ آپ کو ہمیشہ گیٹرز اور سیٹرز بنانے چاہئیں۔ یہاں تک کہ اگر اس بات پر کوئی پابندی نہیں ہے کہ آپ کے فیلڈز کیا قدریں لے سکتے ہیں، یہ مددگار طریقے کوئی نقصان نہیں پہنچائیں گے۔ درج ذیل صورت حال کا تصور کریں: آپ اور آپ کے ساتھی مل کر ایک پروگرام لکھ رہے ہیں۔ آپ عوامی شعبوں کے ساتھ کیٹ کلاس بناتے ہیں۔ تمام پروگرامرز ان کا استعمال کر رہے ہیں جیسا کہ وہ چاہتے ہیں۔ اور پھر ایک اچھا دن آپ کو احساس ہو گا: "غلطی، جلد یا بدیر کوئی غلطی سے وزن کو منفی نمبر تفویض کر سکتا ہے! ہمیں سیٹرز بنانے اور تمام شعبوں کو نجی بنانے کی ضرورت ہے!" آپ ایسا ہی کرتے ہیں، اور اپنے ساتھیوں کے لکھے ہوئے تمام کوڈ کو فوری طور پر توڑ دیتے ہیں۔ سب کے بعد، انہوں نے پہلے سے ہی کوڈ کا ایک گروپ لکھا ہے جو براہ راست بلی کے شعبوں تک رسائی حاصل کرتا ہے.
cat.name = "Behemoth";
اور اب فیلڈز پرائیویٹ ہیں اور کمپائلر غلطیوں کا ایک گروپ پیش کرتا ہے!
cat.name = "Behemoth";//error! The Cat class's name field is private!
اس صورت میں، یہ بہتر ہو گا کہ کھیتوں کو چھپایا جائے اور شروع سے ہی گیٹر اور سیٹرز بنائے جائیں۔ آپ کے تمام ساتھیوں نے انہیں استعمال کیا ہوگا۔ اور اگر آپ نے تاخیر سے محسوس کیا کہ آپ کو کسی نہ کسی طرح فیلڈ ویلیوز کو محدود کرنے کی ضرورت ہے، تو آپ سیٹر کے اندر ہی چیک لکھ سکتے تھے۔ اور کسی کا کوڈ نہیں توڑا جائے گا۔ بلاشبہ، اگر آپ کسی فیلڈ تک رسائی صرف "صرف پڑھنے" کے لیے چاہتے ہیں، تو آپ اس کے لیے صرف ایک گیٹر بنا سکتے ہیں۔ صرف طریقے بیرونی طور پر دستیاب ہونے چاہئیں (یعنی آپ کی کلاس سے باہر)۔ ڈیٹا کو چھپایا جانا چاہئے۔ ہم موبائل فون سے موازنہ کر سکتے ہیں۔ تصور کریں کہ عام بند موبائل فون کے بجائے، آپ کو ایک کھلا کیس والا فون دیا گیا تھا، جس میں ہر طرح کی پھیلی ہوئی تاریں، سرکٹس وغیرہ شامل تھے۔ لیکن فون کام کرتا ہے: اگر آپ واقعی سخت کوشش کرتے ہیں اور سرکٹس کو تھپتھپاتے ہیں، تو ہو سکتا ہے آپ کال کرنے کے قابل۔ لیکن آپ شاید اسے توڑ دیں گے۔
حاصل کرنے والے اور ترتیب دینے والے - 3
اس کے بجائے، مینوفیکچرر آپ کو ایک انٹرفیس دیتا ہے: صارف آسانی سے صحیح ہندسے داخل کرتا ہے، سبز کال کا بٹن دباتا ہے، اور کال شروع ہوجاتی ہے۔ اسے اس بات کی کوئی پرواہ نہیں کہ سرکٹس اور تاروں کے اندر کیا ہوتا ہے، یا وہ اپنا کام کیسے انجام دیتے ہیں۔ اس مثال میں، کمپنی فون کے "اندر" (ڈیٹا) تک رسائی کو محدود کرتی ہے اور صرف ایک انٹرفیس (طریقے) کو ظاہر کرتی ہے۔ نتیجے کے طور پر، صارف کو وہی ملتا ہے جو وہ چاہتی تھی (کال کرنے کی صلاحیت) اور یقینی طور پر اندر سے کچھ نہیں ٹوٹے گا۔ جو کچھ آپ نے سیکھا ہے اس کو تقویت دینے کے لیے، ہم تجویز کرتے ہیں کہ آپ ہمارے جاوا کورس سے ایک ویڈیو سبق دیکھیں
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION