JavaRush /جاوا بلاگ /Random-UR /جاوا میں وراثت بمقابلہ ساخت
dio
سطح
Москва

جاوا میں وراثت بمقابلہ ساخت

گروپ میں شائع ہوا۔
یہ مضمون جاوا میں وراثت اور ساخت کے تصورات کو واضح کرتا ہے۔ پہلی مثال وراثت کو ظاہر کرتی ہے اور پھر دکھاتی ہے کہ ساخت کا استعمال کرتے ہوئے وراثت کے ڈیزائن کو کیسے بہتر بنایا جائے۔ ہم خلاصہ کریں گے کہ آخر میں ان کے درمیان انتخاب کیسے کیا جائے۔ جاوا میں وراثت بمقابلہ ساخت - 1

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();
	}
}
کلاس کے درجہ بندی کا خاکہ کافی آسان ہے: جاوا میں وراثت بمقابلہ ساخت - 2عمل درآمد کا نتیجہ:
Fly
Fly
Attack
"فلائی" کو دو بار ٹائپ کیا جاتا ہے، اس لیے طریقہ کو move()دو بار کہا جاتا ہے۔ لیکن اسے صرف ایک بار بلایا جانا چاہئے۔ مسئلہ کی وجہ سے ہے super.attack(). طریقہ کلاس طریقہ کو attack ()کہتے ہیں ۔ جب کوئی ذیلی طبقہ کال کرتا ہے تو یہ اوور رائیڈڈ طریقہ کو بھی کال کرتا ہے ۔ مسئلہ کو حل کرنے کے لیے ہم یہ کر سکتے ہیں: move()Insectsuper.attack ()move()
  1. ذیلی طبقے کے طریقہ کار کو ختم کریں attack()۔ یہ ذیلی طبقے کو attack()سپر کلاس کے طریقہ کار کے نفاذ پر منحصر کر دے گا۔ اگر attack()attack()سپر کلاس حرکت کرنے کے لیے ایک مختلف طریقہ استعمال کرنا شروع کردے تو ذیلی کلاس کو بھی تبدیل کرنے کی ضرورت ہوگی۔ یہ خراب انکیپسولیشن ہے۔
  2. attack()مندرجہ ذیل طریقہ کو دوبارہ لکھیں :

    public void attack() {
    	move();
    	System.out.println("Attack");
    }
  3. یہ صحیح نتیجہ کی ضمانت دیتا ہے کیونکہ ذیلی کلاس اب سپر کلاس پر منحصر نہیں ہے۔ تاہم، کوڈ سپر کلاس کا ڈپلیکیٹ ہے۔ (طریقہ 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();
	}
}
کلاس ڈایاگرام: جاوا میں وراثت بمقابلہ ساخت - 3
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 نکات وراثت اور ساخت کے درمیان فیصلہ کرنے میں آپ کی مدد کر سکتے ہیں:
  1. اگر آپ "IS" فارم کی کلاسوں کے درمیان تعلقات کے ساتھ کام کر رہے ہیں اور ایک کلاس اپنے تمام انٹرفیس کسی دوسری کلاس کو فراہم کرنا چاہتی ہے، تو وراثت بہتر ہے۔
  2. اگر رشتہ "HAS" ہے تو کمپوزیشن کو ترجیح دی جاتی ہے۔
اس طرح، وراثت اور ساخت کا اپنا اطلاق ہوتا ہے اور یہ ان کی خوبیوں کو سمجھنے کے قابل ہے۔ لنکس:
  1. بلوچ، جوشوا موثر جاوا۔ پیئرسن ایجوکیشن انڈیا، 2008
  2. https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance
  3. https://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should...
اصل مضمون کا لنک ترجمہ شدہ
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION