JavaRush /Java Blogu /Random-AZ /Java-da miras və kompozisiya
dio
Səviyyə
Москва

Java-da miras və kompozisiya

Qrupda dərc edilmişdir
Bu məqalə Java-da miras və kompozisiya anlayışlarını təsvir edir. Birinci misal varisliyi nümayiş etdirir və sonra kompozisiyadan istifadə edərək miras dizaynını necə təkmilləşdirməyi göstərir. Sonda onlar arasında necə seçim edəcəyimizi ümumiləşdirəcəyik. Java-da miras və kompozisiya - 1

1. Vərəsəlik

Fərz edək ki, bizim bir sinifimiz var Insect(İngiliscə həşərat) Bu sinifdə iki üsul var: 1. move()(İngilis dili hərəkətindən) və 2. attack()(İngilis hücumundan)
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İndi siz növlərdən biri olan , lakin və -nin Insectmüxtəlif tətbiqləri olan bir sinif (İngilis arısı) təyin etmək istəyirsiniz . Bu mirasdan istifadə etməklə edilə bilər: 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();
	}
}
Sinif iyerarxiya diaqramı olduqca sadədir: Java-da miras və kompozisiya - 2İcra nəticəsi:
Fly
Fly
Attack
"Uçmaq" iki dəfə yazılır, buna görə də üsul move()iki dəfə çağırılır. Ancaq yalnız bir dəfə çağırılmalıdır. Problem səbəb olur super.attack(). Metod sinif metodunu attack ()çağırır . Bir alt sinif çağırdıqda , o, həmçinin ləğv edilmiş metodu da çağırır . Problemi həll etmək üçün biz: move()Insectsuper.attack ()move()
  1. Alt sinif metodunu aradan qaldırın attack(). Bu, alt sinfi supersinf metodunun həyata keçirilməsindən asılı edəcək attack(). Əgər attack()attack()supersinif hərəkət etmək üçün başqa üsuldan istifadə etməyə başlayırsa, alt sinif də dəyişməlidir. Bu pis inkapsulyasiyadır.
  2. Metodunu attack()aşağıdakı kimi yenidən yazın:

    public void attack() {
    	move();
    	System.out.println("Attack");
    }
  3. Bu, düzgün nəticəyə zəmanət verir, çünki alt sinif artıq supersinifdən asılı deyil. Bununla belə, kod superklassın dublikatıdır. (metod attack()yalnız bir sətir çıxarmaqdan daha mürəkkəb işlər görür). Bu yaxşı proqram dizaynı deyil və dublikat kod olmamalıdır.

Bu miras dizaynı pisdir, çünki alt sinif onun supersinifinin icra detallarından asılıdır. Supersinif dəyişərsə, alt sinif düzgün işləməyəcək.

2. Tərkibi

Siz miras əvəzinə kompozisiyadan istifadə edə bilərsiniz. Onu istifadə edərək həll yoluna baxaq. Funksiya attack()interfeys kimi mücərrədləşdirilmişdir.
interface Attack {
	public void move();
	public void attack();
}
Hücum interfeysini tətbiq etməklə müxtəlif hücum növləri müəyyən edilə bilər.
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);
	}
}
Hücum funksiyası xarici olduğundan, sinif Insectartıq onu ehtiva etmir.
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;
	}
}
Sinif Bee(İngilis Bee-dən), növün necə Insecthücum edə biləcəyi.
// 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();
	}
}
Sinif diaqramı: Java-da miras və kompozisiya - 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();
	}
}
İcra nəticəsi:
fly
move
fly
sting

3. Bu yanaşmalardan nə vaxt istifadə edilməlidir?

Aşağıdakı 2 məqam varislik və kompozisiya arasında qərar verməyə kömək edə bilər:
  1. Əgər siz "IS" formasının sinifləri arasındakı əlaqə ilə məşğul olursunuzsa və bir sinif bütün interfeyslərini başqa bir sinfə təqdim etmək istəyirsə, irsiyyətə üstünlük verilir.
  2. əlaqə "HAS" olarsa, kompozisiyaya üstünlük verilir.
Beləliklə, miras və tərkibin öz tətbiqləri var və onların mahiyyətini başa düşməyə dəyər. Linklər:
  1. Bloch, Joshua. Effektiv java. Pearson Education India, 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...
Orijinal məqaləyə keçid Tərcümə edilmişdir
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION