JavaRush /جاوا بلاگ /Random-UR /ترمیم کرنے والوں تک رسائی۔ نجی، محفوظ، طے شدہ، عوامی

ترمیم کرنے والوں تک رسائی۔ نجی، محفوظ، طے شدہ، عوامی

گروپ میں شائع ہوا۔
ہیلو! آج کے لیکچر میں ہم " ایکسیس موڈیفائرز " کے تصور سے واقف ہوں گے اور ان کے ساتھ کام کرنے کی مثالیں دیکھیں گے۔ ترمیم کرنے والوں تک رسائی۔  نجی، محفوظ، طے شدہ، عوامی - 1اگرچہ لفظ "آئیے واقف ہوں" مکمل طور پر درست نہیں ہوگا: آپ ان میں سے بیشتر سے پچھلے لیکچرز سے پہلے ہی واقف ہیں۔ صرف اس صورت میں، آئیے اہم چیز کے بارے میں اپنی یادداشت کو تازہ کریں۔ رسائی میں ترمیم کرنے والے اکثر کلیدی الفاظ ہوتے ہیں جو آپ کے کوڈ کے مختلف حصوں تک رسائی کی سطح کو منظم کرتے ہیں۔ کیوں "اکثر"؟ کیونکہ ان میں سے ایک بطور ڈیفالٹ سیٹ ہوتا ہے اور کسی کلیدی لفظ سے ظاہر نہیں ہوتا ہے :) جاوا میں کل چار رسائی موڈیفائرز ہیں۔ ہم ان کو انتہائی سخت سے لے کر انتہائی "نرم" تک ترتیب دیتے ہیں:
  • نجی؛
  • محفوظ
  • پہلے سے طے شدہ (پیکیج نظر آتا ہے)؛
  • عوام
آئیے ان میں سے ہر ایک کو دیکھتے ہیں، فیصلہ کرتے ہیں کہ وہ کب ہمارے لیے کارآمد ہو سکتے ہیں اور مثالیں دیتے ہیں :)

ترمیم کرنے والا نجی

ترمیم کرنے والوں تک رسائی۔  نجی، محفوظ، طے شدہ، عوامی - 2Private- سب سے زیادہ پابندی والا رسائی ترمیم کنندہ۔ یہ ایک ہی کلاس کے اندر ڈیٹا اور طریقوں کی مرئیت کو محدود کرتا ہے۔ آپ اس ترمیم کار کو گیٹرز اور سیٹرز کے بارے میں لیکچر سے جانتے ہیں۔ کیا آپ کو یہ مثال یاد ہے؟
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 سال کی عمر، نام "" اور 0 وزن والی بلی بنانا ممکن ہے۔ اس مسئلے کو حل کرنے کے لیے، ہم استعمال شدہ گیٹرز اور سیٹٹرز ، اور موڈیفائر کا استعمال کرتے ہوئے ڈیٹا تک محدود رسائی بھی private۔
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) {
       // checking the input parameter
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       // checking the input parameter
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       // checking the input parameter
       this.weight = weight;
   }
}
درحقیقت، فیلڈز تک رسائی کو محدود کرنا اور گیٹرز سیٹرز کو لاگو کرنا privateحقیقی کام میں استعمال کی سب سے عام مثال ہے۔ یعنی کسی پروگرام میں encapsulation کو نافذ کرنا اس موڈیفائر کا بنیادی مقصد ہے۔ یہ نہ صرف فیلڈز پر لاگو ہوتا ہے۔ تصور کریں کہ آپ کے پروگرام میں ایک طریقہ ہے جو کچھ بہت پیچیدہ فعالیت کو نافذ کرتا ہے۔ اس کو ایک مثال کے طور پر سامنے لانے کے لیے... فرض کریں کہ آپ کا طریقہ readDataFromCollider()ان پٹ کے بطور ڈیٹا کے ساتھ ایک ایڈریس لیتا ہے، لارج ہیڈرون کولائیڈر سے بائٹ فارمیٹ میں ڈیٹا پڑھتا ہے، اس ڈیٹا کو ٹیکسٹ میں تبدیل کرتا ہے، اسے فائل میں لکھتا ہے اور پرنٹ کرتا ہے۔ یہاں تک کہ طریقہ کار کی تفصیل بھی عجیب لگتی ہے، کوڈ کو ہی چھوڑ دیں :) کوڈ کی پڑھنے کی اہلیت کو بڑھانے کے لیے، طریقہ کی پیچیدہ منطق کو ایک جگہ نہ لکھنا اچھا ہوگا، بلکہ اس کے برعکس، فعالیت کو توڑنا ہے۔ الگ الگ طریقوں میں. مثال کے طور پر، یہ طریقہ readByteData()ڈیٹا کو پڑھنے، convertBytesToSymbols()ٹکرانے والے سے پڑھے گئے ڈیٹا کو ٹیکسٹ میں تبدیل کرنے، saveToFile()نتیجے میں آنے والے ٹیکسٹ کو فائل میں محفوظ کرنے اور printColliderData()ہماری ڈیٹا فائل کو پرنٹ کرنے کے لیے ذمہ دار ہے۔ طریقہ readDataFromCollider()بہت آسان ہو جائے گا:
public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   public byte[] readByteData(Path pathToData) {

       // reads data in bytes
   }

   public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {

       // convert bytes to characters
   }

   public File saveToFile(String[] colliderData) {

       // save the read data to a file
   }

   public void printColliderData(File fileWithColliderData) {

       // print data from file
   }
}
تاہم، جیسا کہ آپ انٹرفیس پر لیکچر سے یاد کرتے ہیں، صارف کو صرف حتمی انٹرفیس تک رسائی حاصل ہوتی ہے۔ اور ہمارے 4 طریقے اس کا حصہ نہیں ہیں۔ وہ معاون ہیں : ہم نے انہیں کوڈ کی پڑھنے کی اہلیت کو بہتر بنانے اور چار مختلف کاموں کو ایک طریقہ میں گھڑنے سے بچنے کے لیے بنایا ہے۔ صارف کو ان طریقوں تک رسائی دینے کی ضرورت نہیں ہے۔ اگر کسی صارف کو کولائیڈر کے ساتھ کام کرتے وقت اس طریقہ تک رسائی حاصل ہے convertBytesToSymbols()، تو وہ غالباً یہ سمجھ نہیں پائے گا کہ یہ طریقہ کیا ہے اور اس کی ضرورت کیوں ہے۔ کون سے بائٹس کو تبدیل کیا جاتا ہے؟ وہ کہاں سے آئے؟ انہیں متن میں کیوں تبدیل کریں؟ اس طریقہ کار میں چلنے والی منطق یوزر انٹرفیس کا حصہ نہیں ہے۔ صرف طریقہ readDataFromCollider()انٹرفیس کا حصہ ہے۔ ان چار "اندرونی" طریقوں کا کیا کرنا ہے؟ ٹھیک ہے! ایک ترمیم کنندہ کے ساتھ ان تک رسائی کو محدود کریں private۔ اس طرح وہ کلاس کے اندر اپنا کام آسانی سے کر سکتے ہیں اور صارف کو الجھن میں نہیں ڈال سکتے، جنہیں ان میں سے ہر ایک کی الگ الگ منطق کی ضرورت نہیں ہے۔
public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   private byte[] readByteData(Path pathToData) {
       // reads data in bytes
   }

   private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
       // convert bytes to characters
   }

   private File saveToFile(String[] colliderData) {
       // save the read data to a file
   }

   private void printColliderData(File fileWithColliderData) {
       // print data from file
   }
}

موڈیفائر محفوظ ہے۔

اگلا سب سے زیادہ پابندی والا رسائی موڈیفائر ہے protected۔ ترمیم کرنے والوں تک رسائی۔  نجی، محفوظ، طے شدہ، عوامی - 3 رسائی موڈیفائر کے ساتھ نامزد کردہ فیلڈز اور طریقے protectedنظر آئیں گے:
  • تمام کلاسوں کے اندر جو ہمارے جیسے ہی پیکیج میں ہیں؛
  • ہماری کلاس کی تمام جانشینی کلاسوں کے اندر۔
یہ تصور کرنا فوری طور پر مشکل ہے کہ اس کی کب ضرورت ہو گی۔ حیران نہ ہوں: protectedدرخواست کے مقابلے میں بہت کم معاملات ہیں private، اور وہ مخصوص ہیں۔ تصور کریں کہ ہمارے پاس ایک تجریدی طبقہ ہے AbstractSecretAgentجو کسی خفیہ ایجنسی کے خفیہ ایجنٹ کو ظاہر کرتا ہے اور ساتھ ہی ایک پیکیج top_secretجس میں اس طبقے اور اس کی اولاد شامل ہے۔ کنکریٹ کلاسز - FBISecretAgent, وغیرہ - اس سے وراثت MI6SecretAgentمیں ملی ہیں۔ MossadSecretAgentخلاصہ کلاس کے اندر ہم ایک ایجنٹ کاؤنٹر کو نافذ کرنا چاہتے ہیں۔ جب پروگرام میں کہیں نیا ایجنٹ آبجیکٹ بنایا جائے گا تو اس میں اضافہ ہوگا۔
package top_secret;

public abstract class AbstractSecretAgent {

   public static int agentCount = 0;
}
لیکن ہمارے ایجنٹ خفیہ ہیں! اس کا مطلب یہ ہے کہ صرف انہیں اور کسی کو ان کی تعداد کے بارے میں نہیں معلوم ہونا چاہئے۔ ہم آسانی سے protectedفیلڈ میں ایک ترمیم کنندہ شامل کر سکتے agentCountہیں، اور پھر یا تو دیگر خفیہ ایجنٹ کی کلاسوں کی اشیاء، یا وہ کلاسیں جو ہمارے "خفیہ" پیکج میں موجود ہیں، اس کی قدر حاصل کر سکتے ہیں top_secret۔
public abstract class AbstractSecretAgent {

   protected static int agentCount = 0;
}
یہ اس طرح کے مخصوص کاموں کے لئے ہے کہ ایک ترمیم کنندہ کی ضرورت ہے protected:)

پیکیج نظر آنے والا ترمیم کنندہ

ہماری فہرست میں اگلا ہے ترمیم کنندہ defaultیا، جیسا کہ اسے بھی کہا جاتا ہے، package visible۔ یہ کلیدی لفظ سے ظاہر نہیں ہوتا ہے کیونکہ یہ جاوا میں تمام شعبوں اور طریقوں کے لیے بطور ڈیفالٹ سیٹ ہوتا ہے۔ اگر آپ اپنے کوڈ میں لکھتے ہیں -
int x = 10;
... متغیر کو ایک ہی رسائی xحاصل ہوگی ۔ package visibleاگر کسی طریقہ (یا متغیر) کو کسی ترمیم کنندہ کے ساتھ نشان زد نہیں کیا گیا ہے، تو اسے "ڈیفالٹ موڈیفائر" کے ساتھ نشان زد سمجھا جاتا ہے۔ ایسے موڈیفائر کے ساتھ متغیرات یا طریقے (یعنی بالکل بھی بغیر) پیکیج کی تمام کلاسوں کے لیے نظر آتے ہیں جن میں ان کا اعلان کیا گیا ہے۔ اور صرف ان کے لیے۔ اس کے استعمال محدود ہیں، بالکل موڈیفائر کی طرح protected۔ اکثر، default-access کا استعمال ایسے پیکیج میں کیا جاتا ہے جہاں کچھ یوٹیلیٹی کلاسز ہیں جو اس پیکیج میں موجود دیگر تمام کلاسز کی فعالیت کو نافذ نہیں کرتی ہیں۔ آئیے ایک مثال دیتے ہیں۔ تصور کریں کہ ہمارے پاس " سروسز " پیکج ہے۔ اس کے اندر مختلف کلاسز ہیں جو ڈیٹا بیس کے ساتھ کام کرتی ہیں۔ مثال کے طور پر، ایک کلاس ہے UserServiceجو ڈیٹا بیس سے صارف کا ڈیٹا پڑھتی ہے، ایک کلاس ہے CarServiceجو ایک ہی ڈیٹا بیس سے کاروں کے بارے میں ڈیٹا پڑھتی ہے، اور دوسری کلاسیں، جن میں سے ہر ایک اپنی قسم کی اشیاء کے ساتھ کام کرتا ہے اور ڈیٹا بیس سے ان کے بارے میں ڈیٹا پڑھتا ہے۔
package services;

public class UserService {
}

package services;

public class CarService {
}
تاہم، ایسی صورت حال آسانی سے ہو سکتی ہے جب ڈیٹا بیس میں موجود ڈیٹا ایک فارمیٹ میں ہو، لیکن ہمیں اس کی ضرورت دوسرے فارمیٹ میں ہو۔ تصور کریں کہ ڈیٹا بیس میں صارف کی تاریخ پیدائش ٹائم زون کے ساتھ TIMESTAMP کی شکل میں محفوظ ہے...
2014-04-04 20:32:59.390583+02
...اس کے بجائے ہمیں سب سے آسان چیز کی ضرورت ہے java.util.Date۔ servicesاس مقصد کے لیے ہم پیکج کے اندر ایک خاص کلاس بنا سکتے ہیں Mapper۔ وہ ڈیٹا بیس سے ڈیٹا کو جاوا آبجیکٹ میں تبدیل کرنے کا ذمہ دار ہو گا جن سے ہم واقف ہیں۔ ایک سادہ مددگار کلاس۔ ہم عام طور پر تمام کلاسز کو بطور بناتے ہیں public class ClassName، لیکن یہ ضروری نہیں ہے۔ ہم اپنے مددگار طبقے کو محض اس طرح قرار دے سکتے ہیں class Mapper۔ اس صورت میں، یہ اب بھی اپنا کام کرتا ہے، لیکن پیکیج کے باہر کسی کو نظر نہیں آتا ہے services!
package services;

class Mapper {
}


package services;

public class CarService {

   Mapper mapper;
}
اور یہ، درحقیقت، درست منطق ہے: پیکیج سے باہر کوئی ایک معاون کلاس کیوں دیکھے گا جو صرف اسی پیکیج کی کلاسوں کے ساتھ کام کرتا ہے؟

عوامی ترمیم کنندہ

اور فہرست میں آخری، لیکن کم از کم نہیں - ترمیم کنندہ public! آپ اس سے جاوا رش میں تعلیم حاصل کرنے کے پہلے دن ملے تھے، لانچنگ public static void main(String[] args)۔ ترمیم کرنے والوں تک رسائی۔  نجی، محفوظ، طے شدہ، عوامی - 4 اب جب کہ آپ انٹرفیس کے بارے میں لیکچرز کا مطالعہ کر چکے ہیں، اس کا مقصد آپ پر واضح ہے :) آخر کار، publicاسے صارفین کو کچھ دینے کے لیے بنایا گیا تھا۔ مثال کے طور پر، آپ کے پروگرام کا انٹرفیس۔ فرض کریں کہ آپ نے ایک مترجم پروگرام لکھا ہے، اور یہ روسی متن کا انگریزی میں ترجمہ کر سکتا ہے۔ آپ نے ایک طریقہ بنایا ہے translate(String textInRussian)جس کے اندر ضروری منطق کو نافذ کیا جاتا ہے۔ آپ نے اس طریقہ کو لفظ کے ساتھ نشان زد کیا public، اور اب یہ انٹرفیس کا حصہ بن جائے گا:
public class Translator {

   public String translate(String textInRussian) {

       // translates text from Russian to English
   }
}
آپ پروگرام کی سکرین پر موجود "ترجمہ" بٹن کے ساتھ اس طریقہ سے کال کو جوڑ سکتے ہیں - اور بس! کوئی بھی اسے استعمال کر سکتا ہے۔ موڈیفائر کے ساتھ نشان زد کوڈ کے حصے publicآخری صارف کے لیے بنائے گئے ہیں۔ زندگی سے ایک مثال پیش کرنے کے لیے، privateیہ وہ تمام عمل ہیں جو ٹی وی کے اندر ہوتے ہیں جب یہ کام کر رہا ہوتا ہے، اور publicیہ ٹی وی کے ریموٹ کنٹرول کے بٹن ہیں جن کی مدد سے صارف اسے کنٹرول کر سکتا ہے۔ اس کے ساتھ ساتھ اسے یہ جاننے کی ضرورت نہیں ہے کہ ٹی وی کیسے کام کرتا ہے اور کیسے کام کرتا ہے۔ ریموٹ کنٹرول public-طریقوں کا ایک سیٹ ہے: on(), off(), nextChannel(), previousChannel(), increaseVolume(), decreaseVolume()وغیرہ۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION