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. Ipagpalagay natin na ang klaseSuperClass
ay abstract at ang ilang pamamaraan ay ipinahayag dito. Parehong kongkretong klase ClassA
at 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 ClassC
at mamana ito mula ClassA
sa 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 ClassA
at isang function methodB()
ng isang klase ClassB
sa isang klase ClassC
? Ang solusyon ay nakasalalay sa paggamit ng komposisyon. Nasa ibaba ang isang bersyon ng klase ClassC
na 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.-
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
ClassC
tulad 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 klaseClassD
ay 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.
-
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.
-
Ang isa pang bentahe ng komposisyon ay nagbibigay-daan ito para sa kakayahang umangkop sa mga pamamaraan ng pagtawag. Ang aming pagpapatupad ng klase
ClassC
na 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.
-
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.
GO TO FULL VERSION