JavaRush /Java Blog /Random-TL /Inheritance vs composition sa Java
dio
Antas
Москва

Inheritance vs composition sa Java

Nai-publish sa grupo
Inilalarawan ng artikulong ito ang mga konsepto ng pamana at komposisyon sa Java. Ang unang halimbawa ay nagpapakita ng mana at pagkatapos ay nagpapakita kung paano pahusayin ang disenyo ng mana gamit ang komposisyon. Ibubuod namin kung paano pumili sa pagitan ng mga ito sa dulo. Inheritance vs Composition sa Java - 1

1. Pamana

Ipagpalagay natin na mayroon tayong klase Insect(English insect) Ang klase na ito ay naglalaman ng dalawang pamamaraan: 1. move()(mula sa English move) at 2. attack()(mula sa English 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");
	}
}
Ngayon ay gusto mong tukuyin ang isang klase Bee(English bee), na isa sa mga uri Insect, ngunit may iba't ibang pagpapatupad attack()ng at move(). Magagawa ito gamit ang mana:
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();
	}
}
Ang diagram ng hierarchy ng klase ay medyo simple: Inheritance vs Composition sa Java - 2Resulta ng pagpapatupad:
Fly
Fly
Attack
Ang "Fly" ay nai-type nang dalawang beses, kaya ang pamamaraan move()ay tinatawag na dalawang beses. Pero isang beses lang dapat tawagan. Ang problema ay sanhi ng super.attack(). Ang pamamaraan attack ()ay tumatawag sa isang paraan move()ng klase Insect. Kapag tumawag ang isang subclass super.attack (), tinatawag din nito ang overridden na paraan move(). Upang ayusin ang problema maaari naming:
  1. Tanggalin ang attack()subclass na pamamaraan. Gagawin nitong umaasa ang subclass sa attack()pagpapatupad ng pamamaraan ng superclass. Kung attack()attack()ang superclass ay nagsimulang gumamit ng ibang paraan para sa paglipat, ang subclass ay kailangang baguhin din. Ito ay masamang encapsulation.
  2. Isulat muli ang pamamaraan attack()tulad ng sumusunod:

    public void attack() {
    	move();
    	System.out.println("Attack");
    }
  3. Ginagarantiyahan nito ang tamang resulta dahil hindi na nakadepende ang subclass sa superclass. Gayunpaman, ang code ay isang duplicate ng superclass. (ang pamamaraan attack()ay gumagawa ng mas kumplikadong mga bagay kaysa sa paglabas lamang ng isang string). Hindi ito magandang disenyo ng software at dapat walang duplicate na code.

Masama ang inheritance design na ito dahil ang subclass ay nakadepende sa mga detalye ng pagpapatupad ng superclass nito. Kung magbabago ang superclass, hindi gagana nang tama ang subclass.

2. Komposisyon

Maaari mong gamitin ang komposisyon sa halip na mana. Tingnan natin ang isang solusyon sa paggamit nito. Ang function attack()ay abstracted bilang isang interface.
interface Attack {
	public void move();
	public void attack();
}
Maaaring tukuyin ang iba't ibang uri ng pag-atake sa pamamagitan ng pagpapatupad ng Attack interface.
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);
	}
}
Dahil ang pag-atake ay panlabas, ang klase ay Insecthindi na naglalaman nito.
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;
	}
}
Class Bee(mula sa English Bee), kung paano ang tipong Insectmakakaatake.
// 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();
	}
}
Class diagram: Inheritance vs Composition sa 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();
	}
}
Resulta ng pagpapatupad:
fly
move
fly
sting

3. Kailan gagamitin ang mga pamamaraang ito?

Makakatulong sa iyo ang sumusunod na 2 puntos na magpasya sa pagitan ng mana at komposisyon:
  1. Kung nakikipag-ugnayan ka sa pagitan ng mga klase ng form na "IS" at nais ng isang klase na ibigay ang lahat ng mga interface nito sa isa pang klase, mas gusto ang mana.
  2. kung ang relasyon ay "MAY", mas gusto ang komposisyon.
Kaya, ang mana at komposisyon ay may sariling mga aplikasyon at ito ay nagkakahalaga ng pag-unawa sa kanilang mga merito. Mga link:
  1. Bloch, Joshua. Epektibong 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...
Link sa orihinal na artikulong Isinalin
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION