JavaRush /جاوا بلاگ /Random-UR /حاصل کرنے والے اور سیٹ کرنے والے

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

گروپ میں شائع ہوا۔
ہیلو! پچھلے لیکچرز میں، آپ پہلے ہی سیکھ چکے ہیں کہ فیلڈز اور طریقوں کے ساتھ اپنی مکمل کلاسز کیسے بنائیں۔ یہ سنجیدہ پیش رفت ہے، شاباش! لیکن اب مجھے آپ کو ایک ناخوشگوار سچ بتانا ہے۔ ہم نے اپنی کلاسیں بالکل ٹھیک نہیں بنائیں! کیوں؟ پہلی نظر میں، اس کلاس میں کوئی غلطیاں نہیں ہیں:
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!");
   }
}
اصل میں، وہاں ہے. تصور کریں کہ کام پر بیٹھے ہوئے آپ نے ایک کلاس لکھی Catجو بلیوں کی نمائندگی کرتی ہے۔ اور وہ گھر چلا گیا۔ جب آپ دور تھے، ایک اور پروگرامر کام پر آیا، اس نے اپنی کلاس بنائی Main، جہاں اس نے آپ کی لکھی ہوئی کلاس کو استعمال کرنا شروع کیا Cat۔
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
اس سے کوئی فرق نہیں پڑتا کہ اس نے ایسا کیوں کیا یا یہ کیسے ہوا: ہوسکتا ہے کہ وہ شخص تھکا ہوا تھا یا اسے کافی نیند نہیں آئی۔ ایک اور چیز اہم ہے: ہماری موجودہ کلاس Catآپ کو فیلڈز کو دیوانہ وار اقدار تفویض کرنے کی اجازت دیتی ہے۔ نتیجے کے طور پر، پروگرام میں ایک غلط حالت کے ساتھ اشیاء شامل ہیں، جیسے کہ یہ بلی -1000 سال کی عمر کے ساتھ۔ آخر ہم نے کیا غلطی کی؟ جب ہم نے کلاس بنائی تو ہم نے اس کے ڈیٹا کو بے نقاب کیا۔ فیلڈز name، ageاور weightعوامی ڈومین میں ہیں۔ ان تک پروگرام میں کہیں بھی رسائی حاصل کی جاسکتی ہے: صرف ایک آبجیکٹ بنائیں Cat- اور بس، کسی بھی پروگرامر کو اپنے ڈیٹا تک براہ راست " ." آپریٹر کے ذریعے رسائی حاصل ہوتی ہے۔
Cat cat = new Cat();
cat.name = "";
یہاں ہم براہ راست فیلڈ تک رسائی حاصل کرتے ہیں nameاور اس کی قیمت مقرر کرتے ہیں۔ ہمیں کسی نہ کسی طرح اپنے ڈیٹا کو غلط بیرونی مداخلت سے بچانے کی ضرورت ہے۔ اس کے لیے کیا ضرورت ہے؟ سب سے پہلے، تمام مثال کے متغیرات (فیلڈز) کو ایک ترمیم کنندہ کے ساتھ نشان زد کیا جانا چاہیے private۔ پرائیویٹ جاوا میں سب سے سخت رسائی ترمیم کنندہ ہے۔ اگر آپ اسے استعمال کرتے ہیں، تو کلاس کے فیلڈز Catاس سے باہر قابل رسائی نہیں ہوں گے۔
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 name field in the Cat class has private access!
   }
}
مرتب کرنے والا اسے دیکھتا ہے اور فوری طور پر ایک غلطی پیدا کرتا ہے۔ اب کھیتوں کی حفاظت ہوتی دکھائی دے رہی ہے۔ لیکن یہ پتہ چلتا ہے کہ ان تک رسائی "مضبوطی سے" بند ہے: اگر ضروری ہو تو پروگرام موجودہ بلی کا وزن بھی نہیں لے سکتا۔ یہ بھی کوئی آپشن نہیں ہے: ہماری کلاس اس شکل میں عملی طور پر ناقابل استعمال ہے۔ مثالی طور پر ہمیں ڈیٹا تک کسی قسم کی محدود رسائی کی اجازت دینے کی ضرورت ہے:
  • دوسرے پروگرامرز کو اشیاء بنانے کے قابل ہونا چاہئے۔Cat
  • انہیں پہلے سے موجود اشیاء سے ڈیٹا پڑھنے کے قابل ہونا چاہئے (مثال کے طور پر، پہلے سے موجود بلی کا نام یا عمر حاصل کریں)
  • فیلڈ ویلیوز کو تفویض کرنا بھی ممکن ہونا چاہیے۔ لیکن ایک ہی وقت میں - صرف درست اقدار. ہماری اشیاء کو غلط چیزوں سے محفوظ رکھا جانا چاہیے (کوئی "عمر = -1000 سال" اور اس طرح کی نہیں)۔
ضروریات کی فہرست مہذب ہے! لیکن درحقیقت، یہ سب آسانی سے خصوصی طریقوں کا استعمال کرتے ہوئے حاصل کیا جاتا ہے - getters اور setters ۔
حاصل کرنے والے اور ترتیب دینے والے - 2
نام انگریزی سے آتا ہے " get " - " وصول کریں " (یعنی، "کسی فیلڈ کی قیمت حاصل کرنے کا طریقہ") اور سیٹ - " سیٹ " (یعنی، "کسی فیلڈ کی قدر طے کرنے کا طریقہ")۔ آئیے دیکھتے ہیں کہ وہ ہماری کلاس کو بطور مثال استعمال کرتے ہوئے کیسا نظر آتے ہیں Cat:
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()فیلڈ ویلیو لوٹاتا ہے weightجس کے لیے اسے بلایا گیا تھا۔ یہ پروگرام میں ایسا لگتا ہے:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       String barsikName = barsik.getName();
       int barsikAge = barsik.getAge();
       int barsikWeight = barsik.getWeight();

       System.out.println("Cat name: " + barsikName);
       System.out.println("Cat's age: " + barsikAge);
       System.out.println("Weight of the cat: " + barsikWeight);
   }
}
کنسول آؤٹ پٹ:

Name кота: Барсик
Возраст кота: 5
Вес кота: 4
اب دوسری کلاس ( Main) سے فیلڈز تک رسائی ہے Cat، لیکن صرف گیٹرز کے ذریعے ۔ براہ کرم نوٹ کریں کہ حاصل کرنے والوں کے پاس ایک رسائی موڈیفائر ہے public، یعنی وہ پروگرام میں کہیں سے بھی قابل رسائی ہیں۔ اقدار کو تفویض کرنے کے بارے میں کیا خیال ہے؟ سیٹر کے طریقے اس کے لیے ذمہ دار ہیں۔
public void setName(String name) {
   this.name = name;
}
ان کا کام، جیسا کہ آپ دیکھ سکتے ہیں، بھی آسان ہے۔ ہم setName()کسی آبجیکٹ پر ایک طریقہ کو کال کرتے ہیں Cat، اسے دلیل کے طور پر ایک سٹرنگ پاس کرتے ہیں، اور یہ سٹرنگ nameہمارے آبجیکٹ کے فیلڈ کو تفویض کی جاتی ہے۔
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);

       System.out.println("The original name of the cat is " + barsik.getName());
       barsik.setName("Basil");
       System.out.println("The new name of the cat -" + barsik.getName());
   }
}
یہاں ہم نے گیٹرز اور سیٹرز دونوں کا استعمال کیا۔ سب سے پہلے، گیٹر کا استعمال کرتے ہوئے، ہم نے کنسول میں بلی کا ابتدائی نام وصول کیا اور ظاہر کیا۔ پھر، سیٹر کا استعمال کرتے ہوئے، nameاس کے فیلڈ کو ایک نئی قدر تفویض کی گئی تھی - "واسیلی"۔ اور پھر، ایک گیٹر کا استعمال کرتے ہوئے، ہمیں یہ چیک کرنے کے لیے دوبارہ نام ملا کہ آیا یہ واقعی بدل گیا ہے۔ کنسول آؤٹ پٹ:

Изначальное Name кота — Барсик
Новое Name кота — Васorй
ایسا لگتا ہے، کیا فرق ہے؟ ہم آبجیکٹ فیلڈز کو غلط اقدار بھی تفویض کر سکتے ہیں، چاہے ہمارے پاس سیٹرز ہوں:
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
کنسول آؤٹ پٹ:

Возраст Барсика — -1000 лет
فرق یہ ہے کہ سیٹر ایک مکمل طریقہ ہے ۔ اور ایک طریقہ میں، فیلڈ کے برعکس، آپ تصدیقی منطق ڈال سکتے ہیں جس کی آپ کو ناقابل قبول اقدار کو روکنے کے لیے درکار ہے۔ مثال کے طور پر، آپ آسانی سے عمر کے طور پر منفی نمبر تفویض کرنے کو غیر فعال کر سکتے ہیں:
public void setAge(int age) {
   if (age >= 0) {
       this.age = age;
   } else {
       System.out.println("Error! Age cannot be negative!");
   }
}
اور اب ہمارا کوڈ صحیح طریقے سے کام کرتا ہے!
public class Main {

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5, 4);
       barsik.setAge(-1000);

       System.out.println("Age of Barsik -" + barsik.getAge() + " years");
   }
}
کنسول آؤٹ پٹ:

Ошибка! Возраст не может быть отрицательным числом!
Возраст Барсика — 5 лет
سیٹر کے اندر ایک پابندی ہے، اور یہ غلط ڈیٹا سیٹ کرنے کی کوششوں سے بچاتا ہے۔ بارسیک کی عمر میں کوئی تبدیلی نہیں آئی۔ گیٹر اور سیٹرز ہمیشہ بنائے جانے چاہئیں۔ یہاں تک کہ اگر آپ کے شعبوں میں ممکنہ اقدار پر کوئی پابندی نہیں ہے، تب بھی ان سے کوئی نقصان نہیں ہوگا۔ ایک صورت حال کا تصور کریں: آپ اور آپ کے ساتھی مل کر ایک پروگرام لکھ رہے ہیں۔ Catآپ نے پبلک فیلڈز کے ساتھ ایک کلاس بنائی ہے ، اور تمام پروگرامرز انہیں اپنی مرضی کے مطابق استعمال کرتے ہیں۔ اور پھر ایک اچھا دن آپ پر طلوع ہوتا ہے: "لعنت، جلد یا بدیر کوئی غلطی سے کسی متغیر کو منفی نمبر تفویض کر سکتا ہے weight! ہمیں سیٹرز بنانے اور تمام شعبوں کو نجی بنانے کی ضرورت ہے! آپ انہیں بناتے ہیں، اور آپ کے ساتھیوں کے لکھے ہوئے تمام کوڈ فوری طور پر ٹوٹ جاتے ہیں۔ Catسب کے بعد، انہوں نے پہلے ہی کوڈ کا ایک گروپ لکھا تھا جہاں انہوں نے براہ راست کھیتوں تک رسائی حاصل کی تھی ۔
cat.name = "Hippopotamus";
اور اب فیلڈز پرائیویٹ ہو گئے ہیں اور کمپائلر غلطیوں کا ایک گروپ پیدا کرتا ہے!
cat.name = "Hippopotamus";//error! The name field of the Cat class has private access!
ایسی صورت حال میں، یہ بہتر ہو گا کہ کھیتوں کو چھپانا اور شروع سے ہی گیٹر سیٹر پیدا کرنا ۔ آپ کے تمام ساتھی انہیں استعمال کریں گے، اور اگر آپ کو دیر سے معلوم ہوا کہ آپ کو فیلڈ ویلیوز کو محدود کرنے کی ضرورت ہے، تو آپ سیٹر کے اندر صرف ایک چیک شامل کریں گے۔ اور کوئی بھی پہلے سے لکھے ہوئے کوڈ کو نہیں توڑ سکے گا۔ یقیناً، اگر آپ کسی مخصوص فیلڈ تک صرف پڑھنے کے لیے رسائی چاہتے ہیں، تو آپ اس کے لیے ایک گیٹر بنا سکتے ہیں۔ "باہر"، یعنی آپ کی کلاس کے باہر، صرف طریقے دستیاب ہونے چاہئیں۔ ڈیٹا کو چھپایا جانا چاہیے۔
حاصل کرنے والے اور ترتیب دینے والے - 4
موبائل فون سے تشبیہ دی جا سکتی ہے۔ تصور کریں کہ عام موبائل فون کے آن ہونے کے بجائے، آپ کو ایک کھلا کیس والا فون دیا گیا، جہاں تمام تاریں، سرکٹس وغیرہ موجود ہیں۔ باہر چپکی ہوئی فون کام کرتا ہے: اگر آپ ڈایاگرام کے ساتھ سخت کوشش کرتے ہیں، تو آپ کال کرنے کے قابل بھی ہوسکتے ہیں۔ لیکن آپ شاید اسے توڑ دیں گے۔ اس کے بجائے، مینوفیکچرنگ کمپنی آپ کو ایک انٹرفیس دیتی ہے: کلائنٹ صرف مطلوبہ نمبر ڈائل کرتا ہے، ہینڈ سیٹ کے ساتھ سبز بٹن دباتا ہے، اور کال شروع ہوجاتی ہے۔ اور اسے اس بات کی پرواہ نہیں ہے کہ سرکٹس اور تاروں کے ساتھ اندر کیا ہو رہا ہے اور وہ اپنا کام کیسے انجام دیتے ہیں۔ اس مثال میں، کمپنی کے پاس فون کے "اندرونی" (ڈیٹا) تک محدود رسائی ہے اور صرف انٹرفیس (طریقے) کو باہر چھوڑ دیا ہے۔ نتیجے کے طور پر، کلائنٹ کو وہی ملے گا جو وہ چاہتا تھا (ایک کال کریں) اور یقینی طور پر اندر سے کچھ نہیں ٹوٹے گا۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION