JavaRush /Java Blog /Random-TL /Maramihang pamana sa Java. Komposisyon kumpara sa Mana

Maramihang pamana sa Java. Komposisyon kumpara sa Mana

Nai-publish sa grupo

Maramihang Pamana sa Java

Binibigyang-daan ka ng multiple inheritance na lumikha ng klase na nagmana mula sa maraming superclass. Hindi tulad ng ilang iba pang sikat na object-oriented programming language, gaya ng C++, hindi pinapayagan ng Java ang maraming inheritance mula sa mga klase. Hindi sinusuportahan ng Java ang multiple class inheritance dahil maaari itong humantong sa problema sa brilyante. At sa halip na maghanap ng mga paraan upang malutas ang problemang ito, may mas magagandang opsyon kung paano natin makakamit ang parehong resulta tulad ng maramihang mana.

Problema sa brilyante

Upang mas madaling maunawaan ang problema sa brilyante, ipagpalagay natin na ang maramihang pamana ay sinusuportahan sa Java. Sa kasong ito, maaari tayong magkaroon ng hierarchy ng klase tulad ng ipinapakita sa larawan sa ibaba. Maramihang pamana sa Java.  Komposisyon vs. Pamana - 1Ipagpalagay natin na ang klase SuperClassay abstract at ang ilang pamamaraan ay ipinahayag dito. Parehong kongkretong klase ClassAat ClassB.
package com.journaldev.inheritance;
public abstract class SuperClass {
	public abstract void doSomething();
}
package com.journaldev.inheritance;
public class ClassA extends SuperClass{
	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of A");
	}
	//ClassA own method
	public void methodA(){
	}
}
package com.journaldev.inheritance;
public class ClassB extends SuperClass{
	@Override
	public void doSomething(){
		System.out.println("doSomething implementation of B");
	}
	//ClassB specific method
	public void methodB(){
	}
}
Ngayon ipagpalagay na gusto nating ipatupad ClassCat mamana ito mula ClassAsa at ClassB.
package com.journaldev.inheritance;
public class ClassC extends ClassA, ClassB{
	public void test(){
		//calling super class method
		doSomething();
	}
}
Tandaan na tinatawag ng pamamaraan test()ang superclass na pamamaraan doSomething(). Ito ay humahantong sa kalabuan dahil hindi alam ng compiler kung aling pamamaraan ng superclass ang isasagawa. Ito ay isang diagram ng klase na hugis diyamante na tinatawag na problema sa brilyante. Ito ang pangunahing dahilan kung bakit hindi sinusuportahan ng Java ang maramihang pamana. Tandaan na ang problema sa itaas sa multiple class inheritance ay maaari lamang mangyari sa tatlong klase na mayroong kahit isang karaniwang paraan.

Multiple Interface Inheritance

Sa Java, hindi sinusuportahan ang maramihang pamana sa mga klase, ngunit sinusuportahan ito sa mga interface. At ang isang interface ay maaaring pahabain ang maraming iba pang mga interface. Nasa ibaba ang isang simpleng halimbawa.
package com.journaldev.inheritance;
public interface InterfaceA {
	public void doSomething();
}
package com.journaldev.inheritance;
public interface InterfaceB {
	public void doSomething();
}
Tandaan na ang parehong mga interface ay nagpapahayag ng parehong paraan. Ngayon ay maaari na tayong lumikha ng isang interface na nagpapalawak sa parehong mga interface na ito, tulad ng ipinapakita sa halimbawa sa ibaba.
package com.journaldev.inheritance;
public interface InterfaceC extends InterfaceA, InterfaceB {
	//same method is declared in InterfaceA and InterfaceB both
	public void doSomething();
}
Ito ay mahusay na gumagana dahil ang mga interface ay nagdedeklara lamang ng mga pamamaraan at ang pagpapatupad ay gagawin sa mga klase na nagmamana ng interface. Kaya, walang paraan upang makakuha ng kalabuan sa multiple interface inheritance.
package com.journaldev.inheritance;
public class InterfacesImpl implements InterfaceA, InterfaceB, InterfaceC {
	@Override
	public void doSomething() {
		System.out.println("doSomething implementation of concrete class");
	}
	public static void main(String[] args) {
		InterfaceA objA = new InterfacesImpl();
		InterfaceB objB = new InterfacesImpl();
		InterfaceC objC = new InterfacesImpl();

		//all the method calls below are going to same concrete implementation
		objA.doSomething();
		objB.doSomething();
		objC.doSomething();
	}
}
Pakitandaan na kapag na-override mo ang anumang superclass na paraan o nagpapatupad ng paraan ng interface, gamitin ang anotasyon @Override. Paano kung gusto nating gumamit ng isang function methodA()ng isang klase ClassAat isang function methodB()ng isang klase ClassBsa isang klase ClassC? Ang solusyon ay nakasalalay sa paggamit ng komposisyon. Nasa ibaba ang isang bersyon ng klase ClassCna gumagamit ng komposisyon upang tukuyin ang parehong mga pamamaraan ng mga klase at ang pamamaraan doSomething()ng isa sa mga bagay.
package com.journaldev.inheritance;
public class ClassC{
	ClassA objA = new ClassA();
	ClassB objB = new ClassB();
	public void test(){
		objA.doSomething();
	}
	public void methodA(){
		objA.methodA();
	}
	public void methodB(){
		objB.methodB();
	}
}

Komposisyon kumpara sa Mana

Ang isa sa mga pinakamahusay na kasanayan sa Java programming ay ang "pag-apruba ng komposisyon bago ang mana." Susuriin namin ang ilan sa mga aspeto na pabor sa diskarteng ito.
  1. Sabihin nating mayroon tayong superclass at isang klase na nagpapalawak nito:

    package com.journaldev.inheritance;
    public class ClassC{
    	public void methodC(){
    	}
    }
    package com.journaldev.inheritance;
    public class ClassD extends ClassC{
    	public int test(){
    		return 0;
    	}
    }

    Ang code sa itaas ay nag-compile at gumagana nang maayos. Ngunit, paano kung baguhin natin ang pagpapatupad ng klase ClassCtulad ng ipinapakita sa ibaba:

    package com.journaldev.inheritance;
    public class ClassC{
    	public void methodC(){
    	}
    	public void test(){
    	}
    }

    Tandaan na ang pamamaraan test()ay umiiral na sa subclass, ngunit ang uri ng pagbabalik ay iba. Ngayon ang klase ClassDay hindi mag-compile at kung gagamit ka ng anumang IDE, ipo-prompt ka nito na baguhin ang uri ng pagbabalik sa superclass o subclass.

    Ngayon isipin ang isang sitwasyon kung saan mayroon tayong multi-level na class inheritance hierarchy at walang access sa superclass. Wala kaming pagpipilian kundi baguhin ang aming subclass method signature o ang pangalan nito para maalis ang compilation error. Kailangan din nating baguhin ang subclass na pamamaraan sa lahat ng lugar kung saan ito tinawag. Kaya, ginagawang malutong ng pamana ang ating code.

    Ang problema sa itaas ay hindi kailanman mangyayari sa komposisyon at ito ay ginagawang mas kaakit-akit sa mana.

  2. Ang isa pang problema sa inheritance ay ang paglalantad namin ng lahat ng mga pamamaraan ng superclass sa kliyente at kung ang aming superclass ay hindi maayos na idinisenyo at may mga butas sa seguridad, kung gayon kahit na ipinatupad namin ang pinakamahusay na pagpapatupad ng aming klase, kami ay apektado ng hindi magandang pagpapatupad ng superclass. Tinutulungan kami ng komposisyon sa pagbibigay ng kontroladong pag-access sa mga superclass na pamamaraan, samantalang ang mana ay hindi nagbibigay ng kontrol sa mga superclass na pamamaraan. Ito rin ay isa sa mga pangunahing benepisyo ng komposisyon mula sa mana.

  3. Ang isa pang bentahe ng komposisyon ay nagbibigay-daan ito para sa kakayahang umangkop sa mga pamamaraan ng pagtawag. Ang aming pagpapatupad ng klase ClassCna ipinakita sa itaas ay hindi optimal at tinitiyak na ang oras ng pag-compile ay nakatali sa pamamaraan na tatawagin. Sa kaunting pagbabago, maaari nating gawing flexible at dynamic ang method call.

    package com.journaldev.inheritance;
    public class ClassC{
    	SuperClass obj = null;
    	public ClassC(SuperClass o){
    		this.obj = o;
    	}
    	public void test(){
    		obj.doSomething();
    	}
    	public static void main(String args[]){
    		ClassC obj1 = new ClassC(new ClassA());
    		ClassC obj2 = new ClassC(new ClassB());
    
    		obj1.test();
    		obj2.test();
    	}
    }

    Ang resulta ng programa na ipinakita sa itaas:

    doSomething implementation of A
    doSomething implementation of B

    Ang flexibility na ito sa method calling ay hindi available na may inheritance, na nagdaragdag ng isa pang benepisyo sa pagpili ng komposisyon.

  4. Ang pagsubok sa unit ay mas madaling gawin sa komposisyon dahil alam namin na ginagamit namin ang lahat ng mga pamamaraan mula sa superclass at maaaring kopyahin ang mga ito para sa pagsubok. Samantalang sa inheritance ay mas dumedepende tayo sa superclass at hindi alam ang lahat ng method ng superclass na gagamitin. Kaya kailangan nating subukan ang lahat ng mga pamamaraan ng superclass, na dagdag na trabaho dahil sa mana.

    Sa isip, dapat lang tayong gumamit ng mana kapag ang subclass sa superclass na relasyon ay tinukoy bilang "ay". Sa lahat ng iba pang mga kaso, inirerekumenda na gamitin ang komposisyon.

Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION