Multiple Pusaka ing Jawa
Multiple warisan ngidini sampeyan nggawe kelas sing warisan saka macem-macem superclasses. Ora kaya sawetara basa pemrograman berorientasi obyek populer liyane, kayata C++, Jawa ora ngidini sawetara warisan saka kelas. Jawa ora ndhukung sawetara warisan kelas amarga bisa mimpin kanggo masalah mirah. Lan tinimbang golek cara kanggo ngatasi masalah iki, ana pilihan sing luwih apik carane bisa entuk asil sing padha kaya pirang-pirang warisan.Masalah Diamond
Kanggo luwih gampang ngerti masalah berlian, ayo nganggep manawa warisan pirang-pirang didhukung ing Jawa. Ing kasus iki, kita bisa duwe hirarki kelas kaya sing ditampilake ing gambar ing ngisor iki. Ayo nganggep kelasSuperClass
kasebut abstrak lan sawetara metode diumumake ing kono. Loro kelas konkrit ClassA
lan 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(){
}
}
Saiki umpamane kita pengin ngleksanakake ClassC
lan warisan saka ClassA
lan ClassB
.
package com.journaldev.inheritance;
public class ClassC extends ClassA, ClassB{
public void test(){
//calling super class method
doSomething();
}
}
Elinga yen metode kasebut test()
diarani metode superclass doSomething()
. Iki ndadékaké kanggo ambiguity amarga compiler ora ngerti cara superclass kanggo eksekusi. Iki minangka diagram kelas berbentuk berlian sing diarani masalah berlian. Iki minangka alasan utama kenapa Jawa ora ndhukung warisan pirang-pirang. Elinga yen masalah ing ndhuwur karo sawetara warisan kelas mung bisa kelakon karo telung kelas sing duwe paling siji cara umum.
Multiple Interface Warisan
Ing Jawa, sawetara warisan ora didhukung ing kelas, nanging didhukung ing antarmuka. Lan siji antarmuka bisa ngluwihi akeh antarmuka liyane. Ing ngisor iki conto prasaja.package com.journaldev.inheritance;
public interface InterfaceA {
public void doSomething();
}
package com.journaldev.inheritance;
public interface InterfaceB {
public void doSomething();
}
Elinga yen loro antarmuka nyatakake cara sing padha. Saiki kita bisa nggawe antarmuka sing ngluwihi loro antarmuka kasebut, kaya sing ditampilake ing conto ing ngisor iki.
package com.journaldev.inheritance;
public interface InterfaceC extends InterfaceA, InterfaceB {
//same method is declared in InterfaceA and InterfaceB both
public void doSomething();
}
Iki kerjane apik amarga antarmuka mung ngumumake metode lan implementasine bakal ditindakake ing kelas sing menehi antarmuka. Mangkono, ora ana cara kanggo entuk ambiguitas ing pirang-pirang warisan antarmuka.
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();
}
}
Wigati dimangerteni manawa sampeyan ngilangi metode superclass utawa ngetrapake metode antarmuka, gunakake anotasi @Override
. Apa yen kita pengin nggunakake fungsi methodA()
kelas ClassA
lan fungsi methodB()
kelas ClassB
ing kelas ClassC
? Solusi kasebut dumunung ing panggunaan komposisi. Ing ngisor iki minangka versi kelas ClassC
sing nggunakake komposisi kanggo nemtokake metode kelas lan metode doSomething()
salah sawijining obyek.
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();
}
}
Komposisi vs. Warisan
Salah sawijining praktik pemrograman Java sing paling apik yaiku "komposisi persetujuan sadurunge warisan." Kita bakal njelajah sawetara aspek sing ndhukung pendekatan iki.-
Ayo kita duwe superclass lan kelas sing ngluwihi:
package com.journaldev.inheritance; public class ClassC{ public void methodC(){ } } package com.journaldev.inheritance; public class ClassD extends ClassC{ public int test(){ return 0; } }
Kode ing ndhuwur kompilasi lan dianggo kanthi apik. Nanging, apa yen kita ngganti implementasine kelas
ClassC
kaya ing ngisor iki:package com.journaldev.inheritance; public class ClassC{ public void methodC(){ } public void test(){ } }
Elinga yen metode kasebut
test()
wis ana ing subkelas, nanging jinis bali beda. Saiki kelasClassD
ora bakal kompilasi lan yen sampeyan nggunakake IDE sembarang, bakal njaluk sampeyan ngganti jinis bali ing superclass utawa subclass.Saiki mbayangno kahanan sing duwe hierarki warisan kelas multi-level lan ora duwe akses menyang superclass. Kita ora duwe pilihan nanging ngganti tandha metode subclass utawa jenenge kanggo mbusak kesalahan kompilasi. Kita uga kudu ngganti cara subclass ing kabeh panggonan sing diarani. Mangkono, warisan ndadekake kode kita brittle.
Masalah ing ndhuwur ora bakal kelakon karo komposisi lan iki ndadekake luwih atraktif kanggo warisan.
-
Masalah liyane babagan warisan yaiku kita mbukak kabeh metode superclass menyang klien lan yen superclass kita ora dirancang kanthi bener lan ana bolongan keamanan, mula sanajan kita ngetrapake implementasine kelas sing paling apik, kita kena pengaruh implementasine sing ora apik. saka superclass. Komposisi mbantu kita nyedhiyakake akses kontrol menyang metode superclass, dene warisan ora menehi kontrol liwat metode superclass. Iki uga minangka salah sawijining mupangat utama komposisi saka warisan.
-
Manfaat liyane saka komposisi yaiku ngidini keluwesan ing cara nelpon. Implementasi kelas kita
ClassC
ing ndhuwur ora optimal lan njamin wektu kompilasi diikat karo metode sing bakal diarani. Kanthi owah-owahan minimal kita bisa nggawe telpon cara fleksibel lan dinamis.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(); } }
Asil saka program sing ditampilake ing ndhuwur:
doSomething implementation of A doSomething implementation of B
Keluwesan iki ing cara nelpon ora kasedhiya karo warisan, kang nambah keuntungan liyane kanggo pilihan komposisi.
-
Pengujian unit luwih gampang ditindakake kanthi komposisi amarga kita ngerti yen kita nggunakake kabeh metode saka superclass lan bisa nyalin kanggo tes kasebut. Dene ing warisan luwih gumantung marang superclass lan ora ngerti kabeh metode superclass sing bakal digunakake. Dadi, kita kudu nyoba kabeh metode superclass, yaiku karya ekstra amarga warisan.
Saenipun, kita mung kudu nggunakake warisan nalika subclass kanggo hubungan superclass ditetepake minangka "iku". Ing kabeh kasus liyane, dianjurake kanggo nggunakake komposisi.
GO TO FULL VERSION