Haruskah saya mengimplementasikan antarmuka secara langsung atau meminta superclass melakukannya?

14

Apakah ada perbedaan di antara keduanya

public class A extends AbstractB implements C
{...}

melawan...

public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}

Saya mengerti bahwa dalam kedua kasus, kelas A akan berakhir sesuai dengan antarmuka. Dalam kasus kedua, AbstractBdapat menyediakan implementasi untuk metode antarmuka di C. Apakah itu satu-satunya perbedaan?

Jika saya TIDAK ingin memberikan implementasi untuk metode antarmuka apa pun AbstractB , gaya apa yang harus saya gunakan ? Apakah menggunakan satu atau yang lain memiliki beberapa tujuan 'dokumentasi' tersembunyi?

c_maker
sumber
3
saran pada judul: haruskah saya mengimplementasikan antarmuka secara langsung atau meminta superclass melakukannya
Jeanne Boyarsky

Jawaban:

20

Itu semua tergantung pada apakah secara AbstractB implements Csemantik. Yaitu jika masuk akal untuk AbstractBmenerapkan C, kemudian pergi untuk itu.

Jika kita mengambil contoh nyata perbedaan semantik menjadi jelas.

Jika A = Anjing, AbstractB = Hewan, C = IBark

Hanya pilihan yang masuk akal

class Dog extends Animal implements IBark{

Ini tidak masuk akal, karena ini akan menyiratkan bahwa semua binatang menggonggong.

class Animal implements IBark{

Perbedaan lainnya ikut berperan jika Anda memiliki lebih dari sekadar class Amewarisi AbstractB. Di # 1 mereka tidak perlu mengimplementasikan C, di # 2 mereka semua dipaksa untuk mengimplementasikan C.

Karthik T
sumber
1
+1 Jauh lebih jelas daripada jawaban saya!
Hand-E-Food
Selain itu, jika antarmuka Heterotrophitu tampaknya masuk akal untuk Animalmenerapkan Heterotroph. Jika Anda mengharapkan banyak binatang menggonggong lainnya dan ingin memperlakukan mereka dengan cara yang sama kelas lain BarkingAnimal extends Animal implements IBarkakan menjadi cara untuk pergi.
scarfridge
@ scarfridge Sebenarnya saya berharap hewan akan memperpanjang Heterotrophtetapi terima kasih atas masukan Anda
Karthik T
2

Cara mudah untuk menentukan hubungan pewarisan yang tepat bukanlah dengan melihat kelas itu sendiri, tetapi pada kode yang memanggil metode pada kelas tersebut. Di suatu tempat dalam kode Anda, Anda memiliki sesuatu seperti AbstractB b = new A();atau otherObject.addAbstractB(this);. Either way, Anda kemudian menggunakan AbstractBreferensi itu untuk membuat berbagai panggilan metode.

Dalam situasi itu, apakah Anda ingin memanggil metode C? Jika demikian, maka AbstractBharus diimplementasikan C. Jika tidak, seharusnya tidak. Jika Anda tidak memiliki situasi seperti itu, maka Anda tidak perlu warisan, dan harus refactor untuk menggunakan komposisi sebagai gantinya karena itu jauh lebih longgar ditambah.

Karl Bielefeldt
sumber
2

Ini bukan tujuan dokumentasi "tersembunyi". Ini memungkinkan Anda untuk memberikan AbstractB dan semua subkelasnya ke C. Sebenarnya ada tiga gaya.

public class A extends AbstractB implements C
public class AbstractB

Saya akan menggunakan ini jika AbstractB tidak secara logis mengimplementasikan C. Bahkan jika itu tidak memberikan metode, itu bisa memiliki makna. Seperti Anjing memperluas Wag alat Hewan. Tidak masuk akal bagi semua hewan untuk Bercinta. Perhatikan bahwa pendekatan ini sebenarnya tidak menghalangi AbstractB dari menyediakan implementasi.

public class A extends AbstractB
public AbstractB implements C

Saya akan menggunakan ini jika saya ingin semua subclass mengimplementasikan antarmuka DAN masuk akal bagi mereka semua untuk melakukannya. Seperti Beagle memperluas AbstractDog mengimplementasikan Wag.

public class A extends AbstractB implements C
public class AbstractB implements C

Yang ini berlebihan tetapi bisa menambah kejelasan.

Jeanne Boyarsky
sumber
Saya pikir "AbstractC" (yang tidak ada dalam pertanyaan) pada paragraf ke-2 harus diubah menjadi "AbstractB". Saya tidak dapat mengedit untuk melakukan itu karena editor harus setidaknya 6 karakter.
cellepo