یہ مضمون جاوا میں وراثت اور ساخت کے تصورات کو واضح کرتا ہے۔ پہلی مثال وراثت کو ظاہر کرتی ہے اور پھر دکھاتی ہے کہ ساخت کا استعمال کرتے ہوئے وراثت کے ڈیزائن کو کیسے بہتر بنایا جائے۔ ہم خلاصہ کریں گے کہ آخر میں ان کے درمیان انتخاب کیسے کیا جائے۔
1. وراثت
آئیے فرض کریں کہ ہمارے پاس ایک کلاس ہےInsect
(انگریزی کیڑے) اس کلاس میں دو طریقے ہیں: 1. move()
(انگریزی حرکت سے) اور 2. attack()
(انگریزی حملے سے)
class Insect {
private int size;
private String color;
public Insect(int size, String color) {
this.size = size;
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void move() {
System.out.println("Move");
}
public void attack() {
move(); //assuming an insect needs to move before attacking
System.out.println("Attack");
}
}
اب آپ ایک کلاس Bee
(انگریزی مکھی) کی وضاحت کرنا چاہتے ہیں، جو کہ اقسام میں سے ایک ہے Insect
، لیکن attack()
اس کے مختلف نفاذ ہیں اور move()
۔ یہ وراثت کا استعمال کرتے ہوئے کیا جا سکتا ہے:
class Bee extends Insect {
public Bee(int size, String color) {
super(size, color);
}
public void move() {
System.out.println("Fly");
}
public void attack() {
move();
super.attack();
}
}
public class InheritanceVSComposition {
public static void main(String[] args) {
Insect i = new Bee(1, "red");
i.attack();
}
}
کلاس کے درجہ بندی کا خاکہ کافی آسان ہے: عمل درآمد کا نتیجہ:
Fly
Fly
Attack
"فلائی" کو دو بار ٹائپ کیا جاتا ہے، اس لیے طریقہ کو move()
دو بار کہا جاتا ہے۔ لیکن اسے صرف ایک بار بلایا جانا چاہئے۔ مسئلہ کی وجہ سے ہے super.attack()
. طریقہ کلاس طریقہ کو attack ()
کہتے ہیں ۔ جب کوئی ذیلی طبقہ کال کرتا ہے تو یہ اوور رائیڈڈ طریقہ کو بھی کال کرتا ہے ۔ مسئلہ کو حل کرنے کے لیے ہم یہ کر سکتے ہیں: move()
Insect
super.attack ()
move()
- ذیلی طبقے کے طریقہ کار کو ختم کریں
attack()
۔ یہ ذیلی طبقے کوattack()
سپر کلاس کے طریقہ کار کے نفاذ پر منحصر کر دے گا۔ اگرattack()attack()
سپر کلاس حرکت کرنے کے لیے ایک مختلف طریقہ استعمال کرنا شروع کردے تو ذیلی کلاس کو بھی تبدیل کرنے کی ضرورت ہوگی۔ یہ خراب انکیپسولیشن ہے۔ -
attack()
مندرجہ ذیل طریقہ کو دوبارہ لکھیں :public void attack() { move(); System.out.println("Attack"); }
-
یہ صحیح نتیجہ کی ضمانت دیتا ہے کیونکہ ذیلی کلاس اب سپر کلاس پر منحصر نہیں ہے۔ تاہم، کوڈ سپر کلاس کا ڈپلیکیٹ ہے۔ (طریقہ
attack()
صرف اسٹرنگ کو آؤٹ پٹ کرنے سے زیادہ پیچیدہ چیزیں کرتا ہے)۔ یہ اچھا سافٹ ویئر ڈیزائن نہیں ہے اور کوئی ڈپلیکیٹ کوڈ نہیں ہونا چاہیے۔
2. ترکیب
آپ وراثت کے بجائے مرکب استعمال کرسکتے ہیں۔ آئیے اس کا استعمال کرتے ہوئے ایک حل دیکھیں۔ فنکشن کوattack()
انٹرفیس کے طور پر خلاصہ کیا جاتا ہے۔
interface Attack {
public void move();
public void attack();
}
اٹیک انٹرفیس کو لاگو کرکے مختلف قسم کے حملے کی تعریف کی جا سکتی ہے۔
class AttackImpl implements Attack {
private String move;
private String attack;
public AttackImpl(String move, String attack) {
this.move = move;
this.attack = attack;
}
@Override
public void move() {
System.out.println(move);
}
@Override
public void attack() {
move();
System.out.println(attack);
}
}
چونکہ اٹیک فنکشن بیرونی ہے، اس لیے کلاس میں Insect
اب یہ شامل نہیں ہے۔
class Insect {
private int size;
private String color;
public Insect(int size, String color) {
this.size = size;
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
کلاس Bee
(انگریزی مکھی سے)، ایک قسم کیسے Insect
حملہ کر سکتی ہے۔
// This wrapper class wrap an Attack object
class Bee extends Insect implements Attack {
private Attack attack;
public Bee(int size, String color, Attack attack) {
super(size, color);
this.attack = attack;
}
public void move() {
attack.move();
}
public void attack() {
attack.attack();
}
}
کلاس ڈایاگرام:
public class InheritanceVSComposition2 {
public static void main(String[] args) {
Bee a = new Bee(1, "black", new AttackImpl("fly", "move"));
a.attack();
// if you need another implementation of move()
// there is no need to change Insect, we can quickly use new method to attack
Bee b = new Bee(1, "black", new AttackImpl("fly", "sting"));
b.attack();
}
}
عملدرآمد کا نتیجہ:
fly
move
fly
sting
3. ان طریقوں کو کب استعمال کیا جائے؟
درج ذیل 2 نکات وراثت اور ساخت کے درمیان فیصلہ کرنے میں آپ کی مدد کر سکتے ہیں:- اگر آپ "IS" فارم کی کلاسوں کے درمیان تعلقات کے ساتھ کام کر رہے ہیں اور ایک کلاس اپنے تمام انٹرفیس کسی دوسری کلاس کو فراہم کرنا چاہتی ہے، تو وراثت بہتر ہے۔
- اگر رشتہ "HAS" ہے تو کمپوزیشن کو ترجیح دی جاتی ہے۔
- بلوچ، جوشوا موثر جاوا۔ پیئرسن ایجوکیشن انڈیا، 2008
- https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance
- https://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should...
GO TO FULL VERSION