JavaRush /Java блогу /Random-KY /Мурас жана Java курамы
dio
Деңгээл
Москва

Мурас жана Java курамы

Группада жарыяланган
Бул макалада Java тorндеги мурас жана курамы түшүнүктөрү чагылдырылган. Биринчи мисал мурасты көрсөтөт, андан кийин курамын колдонуу менен мурастын дизайнын кантип жакшыртуу керектигин көрсөтөт. Биз аягында алардын ортосунда кантип тандоо керек экенин кыскача айтып беребиз. Мурас жана Java курамында - 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();
	}
}
Класстын иерархиялык диаграммасы абдан жөнөкөй: Мурас жана Java курамында - 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. Бул туура натыйжага кепилдик берет, анткени субкласс мындан ары суперкласстан көз каранды эмес. Бирок, code суперкласстын дубликаты. (ыкма attack()сапты чыгарууга караганда татаалыраак нерселерди жасайт). Бул жакшы программалык дизайн эмес жана эч кандай дубликат code болбошу керек.

Бул мурас дизайны начар, анткени субкласс анын суперклассынын ишке ашыруу деталдарынан көз каранды. Эгерде суперкласс өзгөрсө, субкласс туура иштебейт.

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мындан ары аны камтыbyte.
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();
	}
}
Класс диаграммасы: Мурас жана Java курамында - 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. Блох, Джошуа. Натыйжалуу java. Pearson Education Индия, 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