JavaRush /Blog Jawa /Random-JV /Pusaka pirang-pirang ing Jawa. Komposisi vs. Warisan
DSergey_Kh
tingkat

Pusaka pirang-pirang ing Jawa. Komposisi vs. Warisan

Diterbitake ing grup

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. Pusaka pirang-pirang ing Jawa.  Komposisi vs. Warisan - 1Ayo nganggep kelas SuperClasskasebut abstrak lan sawetara metode diumumake ing kono. Loro kelas konkrit ClassAlan 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 ClassClan warisan saka ClassAlan 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 ClassAlan fungsi methodB()kelas ClassBing kelas ClassC? Solusi kasebut dumunung ing panggunaan komposisi. Ing ngisor iki minangka versi kelas ClassCsing 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.
  1. 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 ClassCkaya 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 kelas ClassDora 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.

  2. 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.

  3. Manfaat liyane saka komposisi yaiku ngidini keluwesan ing cara nelpon. Implementasi kelas kita ClassCing 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.

  4. 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.

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