CodeGym /جاوا بلاگ /Random-UR /جاوا میں فکسڈ اقدار: حتمی، مستقل، اور ناقابل تغیر
John Squirrels
سطح
San Francisco

جاوا میں فکسڈ اقدار: حتمی، مستقل، اور ناقابل تغیر

گروپ میں شائع ہوا۔
ہائے! آپ لفظ "موڈیفائر" سے پہلے ہی واقف ہیں۔ کم از کم، آپ کو رسائی میں ترمیم کرنے والے (عوامی، نجی) اور جامد ترمیم کار کا سامنا کرنا پڑا ہے۔ آج ہم فائنل نامی ایک خصوصی ترمیم کار پر بات کریں گے ۔ آپ ہمارے پروگرام کے حتمی ترمیم کنندہ "سیمنٹ" کے حصے کہہ سکتے ہیں جہاں مستقل، غیر مبہم، غیر تبدیل شدہ طرز عمل کی ضرورت ہے۔ آپ کے پروگراموں میں تین جگہیں ہیں جنہیں آپ استعمال کر سکتے ہیں: کلاسز، طریقے، اور متغیر۔ جاوا میں مقررہ اقدار: حتمی، مستقل، اور ناقابل تغیر - 2 چلو ترتیب میں ان کے ذریعے چلاتے ہیں. اگر حتمی ترمیم کار کلاس ڈیکلریشن میں استعمال ہوتا ہے تو اس کا مطلب ہے کہ کلاس وراثت میں نہیں مل سکتی۔ پچھلے اسباق میں، ہم نے وراثت کی ایک سادہ مثال استعمال کی: ہمارے پاس Animalپیرنٹ کلاس اور دو بچوں کی کلاسیں تھیں: CatاورDog
public class Animal {
}



public class Cat extends Animal {
   // Fields and methods of the Cat class
}


public class Dog extends Animal {

   // Fields and methods of the Dog class
}
تاہم، اگر ہم کلاس پر فائنلAnimal موڈیفائر استعمال کرتے ہیں ، تو Catاور Dogکلاسز اسے وراثت میں نہیں لے سکتے۔
public final class Animal {

}

public class Cat extends Animal {

   // Error! Cannot inherit from final Animal
}
مرتب کرنے والا فوری طور پر ایک غلطی پیدا کرتا ہے۔ جاوا میں، بہت سی فائنل کلاسز پہلے ہی نافذ ہیں۔ ان میں سے جو آپ کثرت سے استعمال کرتے ہیں، Stringسب سے زیادہ معروف ہے۔ مزید یہ کہ اگر کسی کلاس کو حتمی قرار دیا جاتا ہے تو کلاس کے تمام طریقے بھی حتمی ہو جاتے ہیں ۔ اس کا کیا مطلب ہے؟ اگر حتمی موڈیفائر کا استعمال کرتے ہوئے کسی طریقہ کا اعلان کیا جاتا ہے ، تو آپ اس طریقہ کو اوور رائڈ نہیں کر سکتے۔ مثال کے طور پر، یہاں ہمارے پاس ایک Animalکلاس ہے جو ایک speak()طریقہ کا اعلان کرتی ہے۔ لیکن، کتے اور بلیاں یقینی طور پر مختلف طریقوں سے "بولتے" ہیں۔ Catلہذا، ہم اسپیک() طریقوں کا اعلان اور کلاسز دونوں میں کریں گے Dog، لیکن ہم انہیں مختلف طریقے سے نافذ کریں گے۔
public class Animal {

   public void speak() {
       System.out.println("Hello!");
   }
}

public class Cat extends Animal {

   @Override
   public void speak() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void speak() {
       System.out.println("Woof!");
   }
}
ہم نے Catاور Dogکلاسز کو پیرنٹ کلاس میں اعلان کردہ طریقہ کو اوور رائیڈ کر دیا۔ اب، ایک جانور مختلف طریقے سے بات کرے گا، اس بات پر منحصر ہے کہ یہ کس قسم کی چیز ہے:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();

       cat.speak();
       dog.speak();
   }
}
آؤٹ پٹ: میانو! ووف! تاہم، اگر ہم Animalکلاس کے speak()طریقہ کار کو حتمی قرار دیتے ہیں، تو پھر ہم اسے دوسری کلاسوں میں اوور رائڈ نہیں کر سکتے:
public class Animal {

   public final void speak() {
       System.out.println("Hello!");
   }
}


public class Cat extends Animal {

   @Override
   public void speak() {// Error! A final method can't be overridden!
       System.out.println("Meow!");
   }
}
اور ہماری اشیاء کو speak()طریقہ استعمال کرنے پر مجبور کیا جائے گا جیسا کہ پیرنٹ کلاس میں بیان کیا گیا ہے:
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   cat.speak();
   dog.speak();
}
آؤٹ پٹ: ہیلو! ہیلو! اب، حتمی متغیر کے بارے میں. انہیں مستقل کے طور پر بھی جانا جاتا ہے ۔ سب سے پہلے (اور سب سے اہم بات)، ایک مستقل قدر کو تفویض کردہ ابتدائی قدر کو تبدیل نہیں کیا جا سکتا۔ یہ ایک بار اور سب کے لئے تفویض کیا جاتا ہے.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;// Error! You can't assign a new value to a final variable!
   }
}
ایک مستقل کو فوری طور پر شروع کرنے کی ضرورت نہیں ہے۔ یہ بعد میں کیا جا سکتا ہے۔ لیکن، ابتدائی طور پر اس کو تفویض کردہ قدر ہمیشہ کے لیے ایک جیسی رہے گی۔
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;// This is allowed
}
دوسرا، ہمارے متغیر کا نام نوٹ کریں۔ جاوا میں مستقل کے لیے ایک مختلف نام کنونشن ہے۔ یہ عام اونٹ کیس نوٹیشن نہیں ہے۔ اگر یہ ایک عام متغیر ہوتا تو ہم اسے constantExample کہتے ۔ لیکن، مستقل کے نام تمام کیپس میں لکھے جاتے ہیں، الفاظ کے درمیان انڈر سکور کے ساتھ (اگر ایک سے زیادہ الفاظ ہیں)، جیسے "CONSTANT_EXAMPLE"۔ ہمیں مستقل کی ضرورت کیوں ہے؟ وہ بہت مفید ہیں اگر، مثال کے طور پر، ایک مقررہ قیمت ہے جو آپ باقاعدگی سے کسی پروگرام میں استعمال کرتے ہیں۔ مثال کے طور پر، آپ نے تاریخ رقم کرنے اور گیم "The Witcher 4" خود لکھنے کا فیصلہ کیا ہے۔ گیم واضح طور پر مرکزی کردار کا نام استعمال کرے گا: "جیرالٹ آف ریویا"۔ اس سٹرنگ (اور دوسرے ہیروز کے نام) کو مستقل کے طور پر بہترین قرار دیا جاتا ہے: اس کی قیمت ایک جگہ پر محفوظ ہو جائے گی، اور اسے دس لاکھ بار داخل کرنے پر آپ یقینی طور پر ٹائپنگ کی غلطی نہیں کریں گے۔
public class TheWitcher4 {

   private static final String GERALT_NAME = "Geralt of Rivia";
   private static final String YENNEFER_NAME = "Yennefer of Wengerberg";
   private static final String TRISS_NAME = "Triss Merigold";

   public static void main(String[] args) {

       System.out.println("The Witcher 4");
       System.out.println("It's already the fourth Witcher game, but " + GERALT_NAME + " still can't decide who" +
               " he likes more: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("But, if you've never played The Witcher before, we'll start from the beginning.");
       System.out.println("The protagonist's name is " + GERALT_NAME);
       System.out.println(GERALT_NAME + " is a witcher, a monster hunter");
   }
}
آؤٹ پٹ: دی وِچر 4 یہ پہلے سے ہی چوتھا وِچر گیم ہے، لیکن ریویا کا جیرالٹ اب بھی یہ فیصلہ نہیں کر سکتا کہ وہ کسے زیادہ پسند کرتا ہے: وینگربرگ یا ٹریس میریگولڈ کے ینیفر لیکن، اگر آپ نے پہلے کبھی دی وِچر نہیں کھیلا ہے، تو ہم شروع کریں گے۔ آغاز مرکزی کردار کا نام جیرالٹ آف ریویا ہے جیرالٹ آف ریویا ایک جادوگر ہے، ایک راکشس شکاری ہے ہم نے ہیروز کے ناموں کو مستقل کے طور پر قرار دیا ہے۔ اب ہم یقینی طور پر کوئی ٹائپنگ نہیں کریں گے، اور ہر بار انہیں ہاتھ سے لکھنے کی ضرورت نہیں ہے۔ ایک اور پلس: اگر ہمیں کبھی بھی پورے پروگرام میں متغیر کی قدر کو تبدیل کرنے کی ضرورت ہو، تو آپ اسے پورے کوڈ بیس میں دستی طور پر ترمیم کرنے کے بجائے ایک جگہ پر کر سکتے ہیں۔ :)

ناقابل تغیر اقسام

جیسا کہ آپ نے جاوا کے ساتھ کام کیا ہے، آپ شاید پہلے ہی اس خیال کے عادی ہو چکے ہوں گے کہ پروگرامرز کا تمام اشیاء کی حالت پر تقریباً مکمل کنٹرول ہے۔ اگر آپ کوئی چیز بنانا چاہتے ہیں Catتو آپ کر سکتے ہیں۔ اگر آپ اس کا نام تبدیل کرنا چاہتے ہیں، تو آپ کر سکتے ہیں۔ اگر آپ اس کی عمر یا کچھ اور بدلنا چاہتے ہیں تو آپ کر سکتے ہیں۔ لیکن جاوا میں ڈیٹا کی کئی اقسام ہیں جن کی ایک خاص خاصیت ہے۔ وہ ناقابل تغیر ہیں ۔ اگر کوئی کلاس ناقابل تغیر ہے، تو اس کی اشیاء کی حالت کو تبدیل نہیں کیا جا سکتا۔ کچھ مثالیں چاہتے ہیں؟ یہ آپ کو حیران کر سکتا ہے، لیکن سب سے مشہور غیر تبدیل شدہ کلاس ہے String! تو، ہم واقعی سٹرنگ کی قدر کو تبدیل نہیں کر سکتے؟ ٹھیک ہے، آئیے اسے آزمائیں:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1 = "I love Python";// but changing str1 has no impact on str2
   System.out.println(str2);// str2 continues to point to the "I love Java" string, but str1 now points to a different object
}
آؤٹ پٹ: مجھے جاوا پسند ہے مجھے جاوا سے محبت ہے لکھنے کے بعد
str1 = "I love Python";
سٹرنگ "I love Java"آبجیکٹ تبدیل نہیں ہوا یا کہیں نہیں گیا۔ یہ اب بھی خوشی سے موجود ہے اور اس کا متن پہلے جیسا ہی ہے۔ کوڈ
str1 = "I love Python";
صرف ایک اور آبجیکٹ بنایا، جس کی طرف str1 اب اشارہ کرتا ہے۔ لیکن، ہم "مجھے جاوا سے پیار ہے" سٹرنگ آبجیکٹ پر کوئی اثر نہیں ہوتا۔ ٹھیک ہے، چلو کچھ اور کرنے کی کوشش کرتے ہیں! کلاس Stringطریقوں سے بھری ہوئی ہے، اور ان میں سے کچھ اعتراض کی حالت کو تبدیل کرتے دکھائی دیتے ہیں! replace()مثال کے طور پر، ایک طریقہ ہے ۔ آئیے اپنے سٹرنگ میں لفظ "جاوا" کو "ازگر" میں تبدیل کریں!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.replace("Java", "Python");// We try to change the state of str1 by swapping the word "Java" with "Python"
   System.out.println(str2);
}
آؤٹ پٹ: مجھے جاوا پسند ہے مجھے جاوا پسند ہے یہ دوبارہ کام نہیں کرتا ہے! شاید تبدیل کرنے کا طریقہ کام نہیں کرتا ہے؟ آئیے کچھ اور کرنے کی کوشش کرتے ہیں۔ مثال کے طور پر، substring(). یہ دلائل کے بطور پاس کردہ کریکٹر انڈیکس پر مبنی ذیلی اسٹرنگ لوٹاتا ہے۔ آئیے اپنے سٹرنگ کے پہلے 10 حروف کو کاٹ دیں:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   str1.substring(10);// Truncate the original String
   System.out.println(str2);
}
آؤٹ پٹ: مجھے جاوا پسند ہے مجھے جاوا پسند ہے جاوا میں مقررہ قدریں: حتمی، مستقل، اور ناقابل تغیر - 3 کچھ بھی نہیں بدلا۔ اور یہ نہیں ہونا چاہئے. جیسا کہ ہم نے پہلے کہا، سٹرنگز ناقابل تغیر ہیں۔ تو، کلاس میں تمام طریقوں کے ساتھ کیا ہے String؟ سب کے بعد، وہ تاروں کو کاٹ سکتے ہیں، حروف کو تبدیل کر سکتے ہیں، اور بہت کچھ۔ کچھ نہ ہوا تو کیا فائدہ؟ وہ اصل میں یہ چیزیں کر سکتے ہیں! لیکن، وہ ہر بار ایک نئی سٹرنگ واپس کرتے ہیں۔ لکھنا فضول ہے۔
str1.replace("Java", "Python");
کیونکہ آپ اصل چیز کو تبدیل نہیں کر سکتے۔ لیکن، اگر آپ طریقہ کا نتیجہ ایک نئے حوالہ متغیر پر لکھتے ہیں، تو آپ کو فرق فوری طور پر نظر آئے گا!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;// Both reference variables point to the same string.
   System.out.println(str2);

   String str1AfterReplacement =  str1.replace("Java", "Python");
   System.out.println(str2);

   System.out.println(str1AfterReplacement);
}
تمام Stringطریقے اس طرح کام کرتے ہیں۔ اعتراض کے لیے کچھ نہیں کیا جا سکتا "I love Java"۔ آپ صرف ایک نیا آبجیکٹ بنا سکتے ہیں اور لکھ سکتے ہیں: "<new object> = جوڑ توڑ کا نتیجہ "I love Java" object "۔ دوسری کون سی قسمیں ناقابل تغیر ہیں؟ کچھ جو آپ کو یقینی طور پر فوراً یاد رکھنے کی ضرورت ہو گی وہ قدیم اقسام کے لیے تمام ریپر کلاسز ہیں۔ Integer، Byte, Character, Short, Boolean, Long, Double, Float: یہ تمام کلاسیں immutableاشیاء بناتی ہیں (ہم ان کے بارے میں آئندہ اسباق میں بات کریں گے)۔ اس میں وہ کلاسز شامل ہیں جو بڑی تعداد میں تخلیق کرنے کے لیے استعمال ہوتی ہیں، جیسے کہ BigIntegerاور ۔ ہم نے حال ہی میں مستثنیات کا احاطہ کیا اور اسٹیک ٹریس کوBigDecimal چھوا ۔ اندازہ لگائیں کیا، java.lang.StackTraceElement آبجیکٹس بھی ناقابل تغیر ہیں۔ یہ سمجھ میں آتا ہے: اگر کوئی ہمارے اسٹیک کے ڈیٹا کو تبدیل کر سکتا ہے، تو یہ پوری چیز کو بے معنی کر دے گا۔ تصور کریں کہ کوئی اسٹیک ٹریس سے گزر رہا ہے اور OutOfMemoryError کو FileNotFoundException میں تبدیل کر رہا ہے ۔ اور پھر آپ اس اسٹیک کو خرابی کی وجہ تلاش کرنے کے لیے استعمال کرتے ہیں۔ لیکن پروگرام فائلوں کا استعمال بھی نہیں کرتا۔ :) تو، انہوں نے ان اشیاء کو ناقابل تغیر بنا دیا، صرف اس صورت میں ۔ ، کسی کو بھی اسٹرنگس کو ناقابل تغیر بنانے کی ضرورت کیوں ہوگی؟ ان کی اقدار کو تبدیل کرنا ایک مسئلہ کیوں ہوگا؟ یہ شاید اور بھی زیادہ آسان ہوگا۔ :/ اس کی کئی وجوہات ہیں۔ سب سے پہلے، یہ میموری کو بچاتا ہے. غیر تبدیل شدہ تاروں کو سٹرنگ پول میں رکھا جا سکتا ہے ، جس سے تاروں کو نئے بنانے کی بجائے دوبارہ استعمال کیا جا سکتا ہے۔ دوسرا، سیکورٹی کے لئے. مثال کے طور پر، صارف نام اور پاس ورڈ تقریباً ہر پروگرام میں Strings ہوتے ہیں۔ ان کو تبدیل کرنا ممکن بنانے کے نتیجے میں اجازت کے مسائل پیدا ہو سکتے ہیں۔ دیگر وجوہات ہیں، لیکن جاوا کے بارے میں ہمارے مطالعے نے ابھی تک ان کا احاطہ نہیں کیا ہے، اس لیے ہم بعد میں ان پر واپس آئیں گے۔
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION