
Cat
ڪلاس لکي سگهو ٿا:
package learn.codegym;
public class Cat {
private String name;
private int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public void sayMeow() {
System.out.println("Meow!");
}
public void jump() {
System.out.println("Jump!");
}
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;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
توھان ان جي باري ۾ سڀ ڪجھ ڄاڻو ٿا، ۽ توھان ڏسي سگھوٿا فيلڊ ۽ طريقا جيڪي ان وٽ آھن. فرض ڪريو اوچتو توهان کي پروگرام ۾ ٻين جانورن جي طبقن کي متعارف ڪرائڻ جي ضرورت آهي. Animal
توهان شايد سهولت لاءِ والدين طبقي سان گڏ هڪ طبقاتي ورثي جي جوڙجڪ ٺاهي سگهو ٿا . ان کان اڳ، اسان ھڪڙو طبقو ٺاھيو آھي جيڪو ھڪڙي جانورن جي ڪلينڪ جي نمائندگي ڪري ٿو، جنھن ڏانھن اسان ھڪڙي اعتراض (مثال طور والدين طبقي جو) منتقل ڪري سگھون ٿا Animal
، ۽ پروگرام جانور کي مناسب طور تي علاج ڪيو آھي ان جي بنياد تي ته اھو ڪتو آھي يا ٻلي. جيتوڻيڪ اهي آسان ترين ڪم نه آهن، پروگرام مرتب وقت تي ڪلاس بابت تمام ضروري معلومات سکڻ جي قابل آهي. ان جي مطابق، جڏهن توهان هڪ Cat
اعتراض کي پاس ڪيو ويٽرنري ڪلينڪ ڪلاس جي طريقن جي main()
طريقن ۾، پروگرام اڳ ۾ ئي ڄاڻي ٿو ته اهو هڪ ٻلي آهي، نه ڪتو. هاڻي اچو ته تصور ڪريون ته اسان هڪ مختلف ڪم کي منهن ڏئي رهيا آهيون. اسان جو مقصد ڪوڊ اينالائيزر لکڻ آهي. CodeAnalyzer
اسان کي ھڪڙي ھڪڙي طريقي سان ھڪڙي ڪلاس ٺاهڻ جي ضرورت آھي : void analyzeObject(Object o)
. اهو طريقو گهرجي:
- ان کي منظور ٿيل اعتراض جو ڪلاس مقرر ڪريو ۽ ڪنسول تي ڪلاس جو نالو ڏيکاريو؛
- منظور ٿيل ڪلاس جي سڀني شعبن جا نالا مقرر ڪريو، جن ۾ خانگي شامل آهن، ۽ انهن کي ڪنسول تي ڏيکاريو؛
- منظور ٿيل ڪلاس جي سڀني طريقن جا نالا مقرر ڪريو، جن ۾ خانگي به شامل آھن، ۽ انھن کي ڪنسول تي ڏيکاريو.
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
// Print the name of the class of object o
// Print the names of all variables of this class
// Print the names of all methods of this class
}
}
هاڻي اسان واضح طور تي ڏسي سگهون ٿا ته هي ڪم ٻين ڪمن کان مختلف آهي جيڪي توهان اڳ ۾ حل ڪيا آهن. اسان جي موجوده مقصد سان، ڏکيائي ان حقيقت ۾ آهي ته نه اسان کي ۽ نه ئي پروگرام کي خبر آهي ته ڪهڙي طريقي سان گذري ويندي analyzeClass()
. جيڪڏهن توهان اهڙو پروگرام لکندا آهيو، ٻيا پروگرامر ان کي استعمال ڪرڻ شروع ڪندا، ۽ اهي شايد هن طريقي سان ڪجهه به پاس ڪري سگھن ٿا - ڪنهن به معياري جاوا ڪلاس يا ڪنهن ٻئي طبقي جو اهي لکندا آهن. پاس ٿيل ڪلاس ۾ ڪي به تعداد ۽ طريقا ٿي سگھن ٿا. ٻين لفظن ۾، اسان کي (۽ اسان جو پروگرام) ڪا به خبر ناهي ته اسان ڪهڙن طبقن سان ڪم ڪنداسين. پر اڃا تائين، اسان کي هن ڪم کي مڪمل ڪرڻ جي ضرورت آهي. ۽ اهو آهي جتي معياري جاوا ريفليشن API اسان جي مدد لاءِ اچي ٿو. Reflection API ٻوليءَ جو هڪ طاقتور اوزار آهي. Oracle جي سرڪاري دستاويز سفارش ڪري ٿو ته هي ميکانيزم صرف تجربيڪار پروگرامرن پاران استعمال ڪيو وڃي جيڪي ڄاڻن ٿا ته اهي ڇا ڪري رهيا آهن. توھان جلد سمجھندا سين ڇو ته اسان ھن قسم جي ڊيڄاريندڙ اڳ ۾ ئي ڏئي رھيا آھيون :) ھتي انھن شين جي ھڪڙي فهرست آھي جيڪي توھان Reflection API سان ڪري سگھو ٿا:
- ڪنهن شئي جي درجي کي سڃاڻو/ متعين ڪريو.
- ڪلاس ميڊيفائرز، فيلڊز، طريقا، مستقل، تعمير ڪندڙ، ۽ سپر ڪلاس بابت ڄاڻ حاصل ڪريو.
- معلوم ڪريو ته ڪھڙا طريقا لاڳو ٿيل انٽرفيس سان تعلق رکن ٿا.
- ھڪڙي ڪلاس جو ھڪڙو مثال ٺاھيو جنھن جي ڪلاس جو نالو معلوم نه آھي جيستائين پروگرام تي عمل نه ڪيو وڃي.
- حاصل ڪريو ۽ نالي سان ھڪڙي مثال جي فيلڊ جي قيمت مقرر ڪريو.
- نالي سان هڪ مثالي طريقو ڪال ڪريو.
ڪنهن شئي جي درجي کي ڪيئن سڃاڻڻ/ طئي ڪرڻ
اچو ته بنيادي ڳالهين سان شروع ڪريون. جاوا ريفريڪشن انجڻ ۾ داخلا پوائنٽClass
ڪلاس آھي. ها، اهو واقعي مضحکہ خیز ڏسڻ ۾ اچي ٿو، پر اهو اهو آهي جيڪو عڪس آهي :) Class
ڪلاس استعمال ڪندي، اسان پهريون ڀيرو طئي ڪندا آهيون ڪنهن به شئي جو ڪلاس اسان جي طريقي سان گذري ويو. اچو ته اهو ڪرڻ جي ڪوشش ڪريون:
import learn.codegym.Cat;
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
Class clazz = o.getClass();
System.out.println(clazz);
}
public static void main(String[] args) {
analyzeClass(new Cat("Fluffy", 6));
}
}
ڪنسول آئوٽ:
class learn.codegym.Cat
ٻن ڳالهين تي ڌيان ڏيو. پهرين، اسان عمدي طور Cat
ڪلاس کي الڳ learn.codegym
پيڪيج ۾ رکون ٿا. ھاڻي توھان ڏسي سگھو ٿا ته getClass()
طريقو ڪلاس جو پورو نالو ڏئي ٿو. ٻيو، اسان نالو رکيو اسان جي متغير clazz
. اهو ٿورڙو عجيب لڳندو آهي. ان کي ”طبقو“ سڏڻ جو مطلب ٿيندو، پر جاوا ۾ ”ڪلاس“ هڪ مخصوص لفظ آهي. مرتب ڪندڙ متغيرن کي ان کي سڏڻ جي اجازت نه ڏيندو. اسان کي انهي جي چوڌاري حاصل ڪرڻو پيو :) شروعات لاءِ خراب ناهي! اسان وٽ ان قابليت جي فهرست تي ٻيو ڇا آهي؟
ڪلاس ميڊيفائرز، فيلڊز، طريقا، مستقل، تعمير ڪندڙ، ۽ سپر ڪلاسز بابت معلومات ڪيئن حاصل ڪجي.
هاڻي شيون وڌيڪ دلچسپ ٿي رهيون آهن! موجوده ڪلاس ۾، اسان وٽ ڪوبه مستقل يا والدين ڪلاس ناهي. اچو ته انهن کي شامل ڪريون مڪمل تصوير ٺاهڻ لاءِ. آسان ترين والدين ڪلاس ٺاهيوAnimal
:
package learn.codegym;
public class Animal {
private String name;
private int age;
}
Cat
۽ اسان پنھنجي طبقي کي وارث بڻائينداسين Animal
۽ ھڪڙو مسلسل شامل ڪنداسين:
package learn.codegym;
public class Cat extends Animal {
private static final String ANIMAL_FAMILY = "Feline family";
private String name;
private int age;
// ...the rest of the class
}
هاڻي اسان وٽ مڪمل تصوير آهي! اچو ته ڏسو ته ڪهڙو عڪاسي ڪرڻ جي قابل آهي :)
import learn.codegym.Cat;
import java.util.Arrays;
public class CodeAnalyzer {
public static void analyzeClass(Object o) {
Class clazz = o.getClass();
System.out.println("Class name: " + clazz);
System.out.println("Class fields: " + Arrays.toString(clazz.getDeclaredFields()));
System.out.println("Parent class: " + clazz.getSuperclass());
System.out.println("Class methods: " + Arrays.toString(clazz.getDeclaredMethods()));
System.out.println("Class constructors: " + Arrays.toString(clazz.getConstructors()));
}
public static void main(String[] args) {
analyzeClass(new Cat("Fluffy", 6));
}
}
هتي اهو آهي جيڪو اسان ڪنسول تي ڏسون ٿا:
Class name: class learn.codegym.Cat
Class fields: [private static final java.lang.String learn.codegym.Cat.ANIMAL_FAMILY, private java.lang.String learn.codegym.Cat.name, private int learn.codegym.Cat.age]
Parent class: class learn.codegym.Animal
Class methods: [public java.lang.String learn.codegym.Cat.getName(), public void learn.codegym.Cat.setName(java.lang.String), public void learn.codegym.Cat.sayMeow(), public void learn.codegym.Cat.setAge(int), public void learn.codegym.Cat.jump(), public int learn.codegym.Cat.getAge()]
Class constructors: [public learn.codegym.Cat(java.lang.String, int)]
ڏسو ته سڀني تفصيلي ڪلاس جي معلومات جيڪا اسان حاصل ڪرڻ جي قابل هئا! ۽ نه رڳو عوامي معلومات، پر نجي معلومات پڻ! نوٽ: private
variables پڻ لسٽ ۾ ڏيکاريل آھن. اسان جي طبقي جو "تجزيو" لازمي طور تي مڪمل طور تي سمجهي سگهجي ٿو: اسان اهو analyzeObject()
طريقو استعمال ڪري رهيا آهيون ته اسان هر شي کي سکڻ لاء. پر اهو سڀ ڪجهه ناهي جيڪو اسان عڪاسي سان ڪري سگهون ٿا. اسان صرف سادي مشاهدي تائين محدود نه آهيون - اسان عمل ڪرڻ لاءِ اڳتي وڌنداسين! :)
هڪ ڪلاس جو هڪ مثال ڪيئن ٺاهيو جنهن جي ڪلاس جو نالو معلوم نه هجي جيستائين پروگرام تي عمل نه ڪيو وڃي.
اچو ته ڊفالٽ ڪنسٽرڪٽر سان شروع ڪريون. اسان جيCat
ڪلاس ۾ اڃا تائين ھڪڙو نه آھي، تنھنڪري اچو ته ان کي شامل ڪريون:
public Cat() {
}
هتي آهي ڪوڊ ٺاهڻ لاءِ Cat
اعتراض استعمال ڪندي اعتراض ( createCat()
طريقي):
import learn.codegym.Cat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static Cat createCat() throws IOException, IllegalAccessException, InstantiationException, ClassNotFoundException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String className = reader.readLine();
Class clazz = Class.forName(className);
Cat cat = (Cat) clazz.newInstance();
return cat;
}
public static Object createObject() throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String className = reader.readLine();
Class clazz = Class.forName(className);
Object result = clazz.newInstance();
return result;
}
public static void main(String[] args) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException {
System.out.println(createCat());
}
}
ڪنسول ان پٽ:
learn.codegym.Cat
ڪنسول آئوٽ:
Cat{name='null', age=0}
هي ڪا غلطي ناهي: جا قدر name
۽ age
ڪنسول تي ڏيکاريا ويا آهن ڇو ته اسان انهن کي ڪلاس toString()
جي طريقي ۾ ڪڍڻ لاء ڪوڊ لکيو آهي Cat
. هتي اسان هڪ ڪلاس جو نالو پڙهون ٿا جنهن جو اعتراض اسان ڪنسول مان ٺاهينداسين. پروگرام ڪلاس جو نالو سڃاڻي ٿو جنهن جو اعتراض ٺاهيو وڃي ٿو. 
newInstance()
ڪندي ، اسان هن طبقي جو هڪ نئون اعتراض ٺاهيندا آهيون. اهو ٻيو معاملو آهي جيڪڏهن Cat
تعمير ڪندڙ دليلن کي ان پٽ طور وٺندو آهي. اچو ته ڪلاس جي ڊفالٽ ڪنسٽرڪٽر کي هٽائي ڇڏيون ۽ ڪوشش ڪريون اسان جو ڪوڊ ٻيهر.
null
java.lang.InstantiationException: learn.codegym.Cat
at java.lang.Class.newInstance(Class.java:427)
ڪجهه غلط ٿي ويو! اسان کي هڪ غلطي ملي آهي ڇو ته اسان ڊفالٽ تعمير ڪندڙ استعمال ڪندي هڪ اعتراض ٺاهڻ لاء هڪ طريقو سڏيو آهي. پر هاڻي اسان وٽ اهڙو ڪو تعمير ڪندڙ ناهي. تنهن ڪري جڏهن newInstance()
طريقو هلندو آهي، عکاسي ميڪانيزم اسان جي پراڻي تعمير ڪندڙ کي ٻن پيٽرولن سان استعمال ڪري ٿو:
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
پر اسان پيرا ميٽرن سان ڪجهه به نه ڪيو، ڄڻ ته اسان انهن بابت مڪمل طور تي وساري ڇڏيو هو! تعمير ڪندڙ کي دليلن کي منتقل ڪرڻ لاء عڪاسي استعمال ڪندي ٿوري "تخليق" جي ضرورت آهي:
import learn.codegym.Cat;
import java.lang.reflect.InvocationTargetException;
public class Main {
public static Cat createCat() {
Class clazz = null;
Cat cat = null;
try {
clazz = Class.forName("learn.codegym.Cat");
Class[] catClassParams = {String.class, int.class};
cat = (Cat) clazz.getConstructor(catClassParams).newInstance("Fluffy", 6);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return cat;
}
public static void main(String[] args) {
System.out.println(createCat());
}
}
ڪنسول آئوٽ:
Cat{name='Fluffy', age=6}
اچو ته هڪ ويجهي نظر رکون ته اسان جي پروگرام ۾ ڇا ٿي رهيو آهي. اسان Class
شين جو هڪ صف ٺاهيو.
Class[] catClassParams = {String.class, int.class};
اهي اسان جي تعمير ڪندڙ جي پيٽرولن سان ملن ٿا (جنهن ۾ صرف String
۽ int
پيٽرولر آهن). اسان انهن کي clazz.getConstructor()
طريقي سان منتقل ڪيو ۽ گهربل تعمير ڪندڙ تائين رسائي حاصل ڪريو. ان کان پوء، اسان کي صرف ضروري دليلن سان طريقي سان سڏڻ جي ضرورت آهي newInstance()
، ۽ واضح طور تي اعتراض کي مطلوب قسم تي اڇلائڻ نه وساريو: Cat
.
cat = (Cat) clazz.getConstructor(catClassParams).newInstance("Fluffy", 6);
هاڻي اسان جو اعتراض ڪاميابي سان پيدا ٿيو آهي! ڪنسول آئوٽ:
Cat{name='Fluffy', age=6}
ساڄي طرف هلڻو آهي :)
هڪ مثال جي فيلڊ جي قيمت ڪيئن حاصل ڪجي ۽ سيٽ ڪريو نالي سان.
تصور ڪريو ته توھان ھڪڙو ڪلاس استعمال ڪري رھيا آھيو جيڪو ٻئي پروگرامر پاران لکيل آھي. اضافي طور تي، توهان وٽ ان کي تبديل ڪرڻ جي صلاحيت نه آهي. مثال طور، هڪ تيار ڪيل ڪلاس لائبريري هڪ JAR ۾ ڀريل. توهان طبقن جو ڪوڊ پڙهي سگهو ٿا، پر توهان ان کي تبديل نٿا ڪري سگهو. فرض ڪريو ته پروگرامر جنهن هن لائبريريءَ ۾ هڪ ڪلاس ٺاهيو (اهو اسان جو پراڻوCat
ڪلاس هجي)، ڊزائن فائنل ٿيڻ کان اڳ رات جو ڪافي ننڊ نه ڪري، فيلڊ لاءِ گيٽر ۽ سيٽر ڪڍي ڇڏيو age
. هاڻي هي طبقو توهان وٽ آيو آهي. اهو توهان جي سڀني ضرورتن کي پورو ڪري ٿو، ڇو ته توهان کي صرف Cat
توهان جي پروگرام ۾ شين جي ضرورت آهي. پر توھان کي انھن جي ضرورت آھي ھڪڙو age
فيلڊ آھي! اھو ھڪڙو مسئلو آھي: اسان فيلڊ تائين پھچي نٿا سگھون، ڇاڪاڻتہ ان ۾ موڊيفائر آھي private
، ۽ گيٽر ۽ سيٽر کي ننڊ کان محروم ڊولپر پاران ختم ڪيو ويو جنھن ڪلاس ٺاھيو:/ خير، عڪاسي اسان جي ھن صورتحال ۾ مدد ڪري سگھي ٿي! اسان وٽ ڪلاس لاءِ ڪوڊ تائين رسائي آهي Cat
، تنهنڪري اسان گهٽ ۾ گهٽ اهو معلوم ڪري سگهون ٿا ته ان ۾ ڪهڙا فيلڊ آهن ۽ انهن کي ڇا چئبو آهي. هن معلومات سان هٿياربند، اسان اسان جو مسئلو حل ڪري سگهون ٿا:
import learn.codegym.Cat;
import java.lang.reflect.Field;
public class Main {
public static Cat createCat() {
Class clazz = null;
Cat cat = null;
try {
clazz = Class.forName("learn.codegym.Cat");
cat = (Cat) clazz.newInstance();
// We got lucky with the name field, since it has a setter
cat.setName("Fluffy");
Field age = clazz.getDeclaredField("age");
age.setAccessible(true);
age.set(cat, 6);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return cat;
}
public static void main(String[] args) {
System.out.println(createCat());
}
}
جيئن ته تبصرن ۾ چيو ويو آهي، name
فيلڊ سان هر شيء سڌو آهي، ڇو ته ڪلاس ڊولپرز هڪ سيٽر مهيا ڪيو. توھان اڳ ۾ ئي ڄاڻو ٿا ته ڊفالٽ ٺاھيندڙن مان شيون ڪيئن ٺاھيون: اسان وٽ آھي newInstance()
ھن لاءِ. پر اسان کي ٻئي فيلڊ سان ڪجهه ٽڪرائڻو پوندو. اچو ته سمجهون ته هتي ڇا ٿي رهيو آهي :)
Field age = clazz.getDeclaredField("age");
هتي، اسان جو Class clazz
اعتراض استعمال ڪندي، اسان طريقي age
سان فيلڊ تائين رسائي حاصل ڪندا آهيون getDeclaredField()
. اهو اسان کي عمر جي ميدان کي هڪ Field age
اعتراض جي طور تي حاصل ڪرڻ جي اجازت ڏئي ٿو. پر اهو ڪافي نه آهي، ڇاڪاڻ ته اسان صرف private
فيلڊن کي قيمتون تفويض نٿا ڪري سگهون. هن کي ڪرڻ لاء، اسان کي استعمال ڪندي فيلڊ کي رسائي لائق بڻائڻ جي ضرورت آهي setAccessible()
:
age.setAccessible(true);
هڪ دفعو اسان هن کي فيلڊ ۾ ڪندا آهيون، اسان هڪ قدر تفويض ڪري سگهون ٿا:
age.set(cat, 6);
جئين توهان ڏسي سگهو ٿا، اسان جي Field age
اعتراض ۾ هڪ قسم جو اندر-آئوٽ سيٽر آهي جنهن ۾ اسان هڪ int قدر ۽ اعتراض جنهن جي فيلڊ کي مقرر ڪيو وڃي ٿو. اسان پنهنجو main()
طريقو هلون ٿا ۽ ڏسو:
Cat{name='Fluffy', age=6}
تمام سٺو! اسان ڪيو! :) اچو ته ڏسون ته اسان ٻيو ڇا ڪري سگهون ٿا ...
هڪ مثالي طريقي کي نالي سان ڪيئن سڏجي.
اچو ته پوئين مثال ۾ صورتحال کي ٿورو تبديل ڪريون. اچو ته چوندا آهن تهCat
ڪلاس ڊولپر حاصل ڪندڙن ۽ سيٽرن سان غلطي نه ڪئي. ان سلسلي ۾ سڀ ڪجهه ٺيڪ آهي. ھاڻي مسئلو مختلف آھي: ھڪڙو طريقو آھي جنھن جي اسان کي ضرور ضرورت آھي، پر ڊولپر ان کي خانگي بڻايو:
private void sayMeow() {
System.out.println("Meow!");
}
ان جو مطلب اهو آهي ته جيڪڏهن اسان پنهنجي پروگرام ۾ شيون ٺاهي سگهون ٿا ، ته پوء اسان انهن تي طريقي سان Cat
سڏڻ جي قابل نه هوندا . sayMeow()
اسان وٽ ٻليون هونديون جيڪي ميون نه ڪن؟ اھو عجيب آھي :/ اسان ان کي ڪيئن ٺيڪ ڪنداسين؟ هڪ ڀيرو ٻيهر، Reflection API اسان جي مدد ڪري ٿي! اسان ڄاڻون ٿا ته طريقي جو نالو اسان کي گهربل آهي. باقي سڀ ڪجهه ٽيڪنيڪل آهي:
import learn.codegym.Cat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void invokeSayMeowMethod() {
Class clazz = null;
Cat cat = null;
try {
cat = new Cat("Fluffy", 6);
clazz = Class.forName(Cat.class.getName());
Method sayMeow = clazz.getDeclaredMethod("sayMeow");
sayMeow.setAccessible(true);
sayMeow.invoke(cat);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
invokeSayMeowMethod();
}
}
هتي اسان گهڻو ئي ساڳيو ڪم ڪندا آهيون جيڪو اسان ڪيو هو جڏهن هڪ خانگي فيلڊ تائين پهچندي هئي. پهريون، اسان کي گهربل طريقو ملي ٿو. اهو هڪ Method
اعتراض ۾ سمايل آهي:
Method sayMeow = clazz.getDeclaredMethod("sayMeow");
اهو getDeclaredMethod()
طريقو اسان کي نجي طريقن ڏانهن وڃڻ جي اجازت ڏئي ٿو. اڳيون، اسان طريقي کي سڏين ٿا:
sayMeow.setAccessible(true);
۽ نيٺ، اسان کي گهربل اعتراض تي طريقو سڏين ٿا:
sayMeow.invoke(cat);
هتي، اسان جو طريقو ڪال هڪ "ڪال بيڪ" وانگر نظر اچي ٿو: اسان هڪ عرصو استعمال ڪرڻ جا عادي آهيون ڪنهن شئي کي مطلوب طريقي سان اشارو ڪرڻ لاءِ ( cat.sayMeow()
)، پر جڏهن عڪاسي سان ڪم ڪريون ٿا، اسان طريقي سان ان شئي ڏانهن وڃون ٿا جنهن تي اسان ڪال ڪرڻ چاهيون ٿا. اهو طريقو. اسان جي ڪنسول تي ڇا آهي؟
Meow!
سڀ ڪم ڪيو! :) ھاڻي توھان ڏسي سگھوٿا وسيع امڪان جيڪي جاوا جي عڪاسي ميڪانيزم اسان کي ڏئي ٿو. مشڪل ۽ غير متوقع حالتن ۾ (جهڙوڪ بند ٿيل لائبريري مان ڪلاس سان اسان جا مثال)، اهو واقعي اسان جي مدد ڪري سگهي ٿو. پر، جيئن ڪنهن وڏي طاقت سان، اهو وڏي ذميواري آڻيندو آهي. عڪس جا نقصان بيان ڪيا ويا آهن خاص سيڪشن
۾ Oracle ويب سائيٽ تي. اتي ٽي مکيه نقصان آهن:
-
ڪارڪردگي بدتر آهي. طريقن کي ريفريڪشن استعمال ڪندي سڏيو ويندو آهي انهن طريقن جي ڀيٽ ۾ وڌيڪ خراب ڪارڪردگي آهي جن کي عام طريقي سان سڏيو ويندو آهي.
-
اتي سيڪيورٽي پابنديون آهن. موٽڻ واري ميڪانيزم اسان کي رن ٽائم تي پروگرام جي رويي کي تبديل ڪرڻ جي اجازت ڏئي ٿي. پر توهان جي ڪم جي جڳهه تي، جڏهن حقيقي منصوبي تي ڪم ڪري رهيا آهيو، توهان شايد انهن حدن کي منهن ڏئي سگهون ٿا جيڪي هن جي اجازت نه ڏيندا آهن.
-
اندروني معلومات جي نمائش جو خطرو. اهو سمجهڻ ضروري آهي ته عڪاسي انڪپسوليشن جي اصول جي سڌي خلاف ورزي آهي: اهو اسان کي نجي شعبن، طريقن، وغيره تائين رسائي ڏئي ٿو. مان نه ٿو سمجهان ته مون کي اهو ذڪر ڪرڻ جي ضرورت آهي ته او او پي جي اصولن جي سڌي ۽ واضح خلاف ورزي کي استعمال ڪيو وڃي. صرف انتهائي سخت ڪيسن ۾، جڏهن توهان جي ڪنٽرول کان ٻاهر سببن جي ڪري مسئلو حل ڪرڻ جا ٻيا طريقا نه آهن.
GO TO FULL VERSION