JavaRush /Java blogi /Random-UZ /Java-da meros va kompozitsiya
dio
Daraja
Москва

Java-da meros va kompozitsiya

Guruhda nashr etilgan
Ushbu maqola Java-da meros va kompozitsiya tushunchalarini tasvirlaydi. Birinchi misol merosni ko'rsatadi va keyin kompozitsiyadan foydalangan holda meros dizaynini qanday yaxshilashni ko'rsatadi. Oxirida ular orasidan qanday tanlashni umumlashtiramiz. Java-da meros va kompozitsiya - 1

1. Meros

Faraz qilaylik, bizda sinf mavjud Insect(ingliz hasharotlari) Bu sinf ikkita usulni o'z ichiga oladi: 1. move()(inglizcha move dan) va 2. attack()(inglizcha hujumdan)
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");
	}
}
Endi siz klassni (inglizcha ari) aniqlamoqchisiz Bee, u turlardan biri bo'lib Insect, lekin attack()va ning turli xil ilovalariga ega move(). Buni meros yordamida amalga oshirish mumkin:
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();
	}
}
Sinf ierarxiyasi diagrammasi juda oddiy: Java-da meros va kompozitsiya - 2Bajarish natijasi:
Fly
Fly
Attack
"Fly" ikki marta yoziladi, shuning uchun usul move()ikki marta chaqiriladi. Lekin u faqat bir marta chaqirilishi kerak. Muammo sabab bo'ladi super.attack(). Usul sinf usulini attack ()chaqiradi . Subklass qo'ng'iroq qilganda , u ham bekor qilingan usulni chaqiradi . Muammoni hal qilish uchun biz: move()Insectsuper.attack ()move()
  1. Subklass usulini yo'q qiling attack(). Bu kichik sinfni supersinf usulini amalga oshirishga bog'liq qiladi attack(). Agar attack()attack()supersinf harakatlanish uchun boshqa usuldan foydalana boshlasa, pastki sinf ham o'zgarishi kerak bo'ladi. Bu yomon inkapsulyatsiya.
  2. Usulni attack()quyidagicha qayta yozing:

    public void attack() {
    	move();
    	System.out.println("Attack");
    }
  3. Bu to'g'ri natijani kafolatlaydi, chunki pastki sinf endi yuqori sinfga bog'liq emas. Biroq, kod superklassning dublikatidir. (usul attack()faqat satrni chiqarishdan ko'ra murakkabroq ishlarni bajaradi). Bu yaxshi dasturiy ta'minot dizayni emas va ikki nusxadagi kod bo'lmasligi kerak.

Ushbu meros dizayni yomon, chunki pastki sinf uning yuqori sinfini amalga oshirish tafsilotlariga bog'liq. Agar supersinf o'zgarsa, pastki sinf to'g'ri ishlamaydi.

2. Tarkibi

Meros o'rniga kompozitsiyadan foydalanishingiz mumkin. Keling, uni ishlatadigan yechimni ko'rib chiqaylik. Funktsiya attack()interfeys sifatida abstrakt qilingan.
interface Attack {
	public void move();
	public void attack();
}
Hujum interfeysini amalga oshirish orqali har xil turdagi hujumlarni aniqlash mumkin.
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);
	}
}
Hujum funktsiyasi tashqi bo'lgani uchun sinf Insectendi uni o'z ichiga olmaydi.
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;
	}
}
Sinf Bee(inglizcha Bee dan), turi qanday Insecthujum qilishi mumkin.
// 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();
	}
}
Sinf diagrammasi: Java-da meros va kompozitsiya - 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();
	}
}
Amalga oshirish natijasi:
fly
move
fly
sting

3. Ushbu yondashuvlardan qachon foydalanish kerak?

Quyidagi 2 nuqta meros va tarkib o'rtasida qaror qabul qilishingizga yordam beradi:
  1. Agar siz "IS" shaklidagi sinflar o'rtasidagi munosabat bilan shug'ullanayotgan bo'lsangiz va sinf o'zining barcha interfeyslarini boshqa sinfga taqdim qilmoqchi bo'lsa, meros afzalroqdir.
  2. agar munosabatlar "HAS" bo'lsa, unda kompozitsiyaga ustunlik beriladi.
Shunday qilib, meros va kompozitsiyaning o'ziga xos ilovalari bor va ularning afzalliklarini tushunishga arziydi. Havolalar:
  1. Bloch, Joshua. Samarali java. Pearson Education Hindiston, 2008 yil
  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...
Asl maqolaga havola tarjima qilingan
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION