Jika saya mengimplementasikan Antarmuka, apakah ini disebut Warisan?

31

Jika kelas saya implementssebuah antarmuka maka dapatkah saya mengatakan bahwa saya mengikuti warisan? Saya tahu bahwa ketika kelas kelas extendslain maka itu warisan.

RajeeV VenkaT
sumber
7
Komentar Jodrell benar-benar salah. Menerapkan sebuah antarmuka memang merupakan warisan, dan mewarisi satu antarmuka dari yang lain adalah warisan. Bagaimana kami bisa tahu? Dengan mendefinisikan kata yang kita gunakan. Warisan adalah properti yang anggota warisan dari satu jenis juga anggota dari jenis lain. Dengan definisi ini, jelas kelas yang mengimplementasikan antarmuka telah mewarisi semua metode antarmuka; lihat saja kelas dan antarmuka dan Anda akan menemukan bahwa dalam program yang benar, mereka memiliki anggota yang sama.
Eric Lippert
Saya telah menghapus centang dan pergi dengan lebih banyak kebingungan.
RajeeV VenkaT
18
Untuk apa nilainya, saya pikir Anda menghabiskan banyak waktu untuk definisi kata yang tidak akan memberi Anda banyak manfaat. Pada akhirnya, kita semua tahu apa artinya mengimplementasikan antarmuka, dan apakah itu dianggap "warisan" sebagian besar tidak penting untuk pekerjaan sehari-hari Anda.
Robert Harvey
3
Saya (kebanyakan) setuju dengan Robert. Saya pikir ada nilai nyata dalam memahami makna teknis yang tepat dari kata-kata jargon karena mereka digunakan dalam berbagai konteks. Tetapi Robert benar bahwa jauh lebih bermanfaat untuk memahami dampak praktisnya! Bagaimana Anda bisa menggunakan warisan untuk membuat kode Anda lebih aman? Lebih bisa diuji? Lebih bisa digunakan kembali? Lebih fleksibel? Dan seterusnya. Mengetahui bahwa anggota tipe dasar juga anggota tipe turunan memang hebat, tetapi masih lebih baik untuk mengetahui cara menggunakannya secara efektif.
Eric Lippert

Jawaban:

78

UPDATE: Saya telah merevisi jawaban ini. Sejumlah poin bagus muncul dalam komentar yang pantas disebut.

Jika kelas saya mengimplementasikan antarmuka maka dapatkah saya mengatakan bahwa saya mengikuti warisan?

Tidak sepenuhnya jelas apa yang Anda maksud dengan "mengikuti warisan". Mari kita ajukan pertanyaan yang sedikit berbeda?

Apa itu warisan?

  • Ketika anggota satu jenis X dianggap anggota jenis lain Y, para anggota Y yang diwarisi dari X .
  • Ada hubungan warisan antara beberapa jenis; yaitu, untuk beberapa tipe X dan Y kita mengatakan "Y mewarisi dari X".

Ini agak berbeda. Sangat disayangkan karena membingungkan.

Kebingungan apa yang biasanya muncul dari perbedaan halus ini?

Kebingungan mungkin timbul karena orang menganggap warisan sebagai mekanisme untuk berbagi perincian implementasi. Meskipun ini adalah mekanisme yang demikian, mekanisme itu bekerja dengan cara berbagi anggota . Para anggota tidak perlu memiliki implementasi! Seperti yang akan kita lihat, mereka bisa abstrak.

Saya pribadi akan lebih bahagia jika spesifikasi Java dan C # menggunakan kata selain "inherit" untuk menggambarkan hubungan antara metode antarmuka dan kelas, untuk menghindari kebingungan ini. Tapi mereka tidak, dan kita harus berargumen dari spesifikasinya, bukan menentang mereka.

Di Jawa, apakah anggota antarmuka diwarisi oleh kelas yang mengimplementasikannya?

Ya, ada beberapa. Lihat spesifikasi Java bagian 8.4.8, yang saya kutip di sini untuk kenyamanan Anda.

Kelas C mewarisi dari superclass langsung dan superinterfaces langsung semua metode abstrak dan default m yang semua hal berikut ini benar: [...]

Jika Anda mengatakan bahwa suatu kelas mengimplementasikan antarmuka maka kelas mewarisi metode abstrak dan default dari antarmuka itu . (Tentu saja saya telah menghilangkan kondisi yang mengikuti; lihat spesifikasi untuk detail. Secara khusus, kelas yang mengimplementasikan anggota antarmuka tidak dianggap mewarisi anggota itu. Sekali lagi, apakah ini membingungkan? Ya.)

Apakah kita biasanya mengatakan dalam Java bahwa suatu kelas mewarisi dari suatu antarmuka?

Biasanya kita akan mengatakan bahwa sebuah kelas mengimplementasikan antarmuka. Seperti disebutkan di atas, suatu kelas dapat mewarisi anggota dari suatu antarmuka, namun masih belum dikatakan mewarisi dari antarmuka. Yang membingungkan, ya.

Apakah perbedaan halus ini penting dalam pekerjaan sehari-hari?

Biasanya tidak. Jenis parsing sempit dari spesifikasi ini lebih berguna bagi penulis kompiler daripada lini pengembang bisnis. Lebih penting untuk memahami kapan harus menggunakan antarmuka daripada untuk mendapatkan definisi yang tepat tentang "inherit from".

Eric Lippert
sumber
4
Saya tidak bisa berdebat dengan referensi kanonik. Ketika spesifikasi berbeda, seperti yang seharusnya terjadi, istilah sederhana menjadi terlalu banyak secara semantik dan ambigu di luar konteks. Pertanyaan ini ditandai dengan javajadi ini adalah jawaban yang benar, kecuali OP berarti beberapa lainnya java:-)
Jodrell
5
Meskipun pertanyaan ini ditandai dengan Java, saya merasa bermasalah untuk mengutip spesifikasi bahasa untuk istilah umum. Banyak bahasa memiliki antarmuka dan spesifikasi bahasanya mungkin menggunakan istilah yang berbeda, jadi menggunakan istilah khusus Java mungkin membingungkan ketika berbicara dengan pengembang yang menggunakan X-Lang.
Thomas Owens
5
@ThomasOwens: Saya setuju bahwa skenario ini biasa dan saya sepenuhnya tidak setuju dengan kesimpulan Anda. Solusi untuk masalah komunikasi yang Anda gambarkan adalah mendidik semua orang yang terlibat untuk makna yang tepat dari kata-kata dalam konteks yang relevan . Spesifikasi ada untuk memberikan kejelasan ini; gunakan mereka!
Eric Lippert
5
Mengapa spesifikasi bahasa Jawa mendapatkan hasil akhir di sini? Spesifikasi bahasa sering mengklaim hal-hal yang "pengembang umum" tidak setuju dengan terminologi.
Benjamin Gruenbaum
5
@BenjaminGruenbaum: Apakah saya tidak tahu itu? Pengembang itu salah, dan mereka sering mengambilnya untuk "mendidik" orang lain tentang kepercayaan mereka yang salah. Anda tidak akan percaya jumlah buku bahasa pemrograman yang harus saya perbaiki karena penulis memiliki beberapa keyakinan yang benar-benar gila tentang VB, C #, JavaScript, dll, yang sama sekali tidak benar. (Jon Skeet tidak ada di antara mereka; C # In Depth benar sejak awal! Belum pernah saya membuat begitu sedikit komentar tentang buku dan masih mendapat bayaran.)
Eric Lippert
26

Warisan berarti menulis subkelas baru untuk superclass. Menulis kelas baru terhadap antarmuka sedang mengimplementasikan antarmuka itu. (Dan menulis antarmuka baru berdasarkan yang lama memperluas antarmuka itu.)

Satu-satunya istilah yang benar yang berlaku untuk ketiga kemungkinan adalah subtyping . Tidak setiap subtipe adalah subclass.

Kilian Foth
sumber
1
Buku GoF tampaknya mempertimbangkan istilah pewarisan antarmuka yang sesuai untuk menjelaskan subtipe (Bagian 1.6 Kelas versus Warisan Antarmuka)
gnat
"Saya pernah menghadiri pertemuan kelompok pengguna Java di mana James Gosling (penemu Java) adalah pembicara utama. Selama sesi tanya jawab yang berkesan, seseorang bertanya kepadanya:" Jika Anda bisa melakukan Jawa lagi, apa yang akan Anda ubah? "" Saya akan tinggalkan kelas, "jawabnya. Dia menjelaskan bahwa masalah sebenarnya bukan kelas per se, tetapi lebih pada implementasi warisan (hubungan yang diperluas). Warisan antarmuka (hubungan implementasi) lebih disukai. Anda harus menghindari warisan implementasi sedapat mungkin." javaworld.com/article/2073649/core-java/…
ricardoramos
1

Dengan subkelas , Anda

  • mewarisi status superclass (semua variabel instan, apakah Anda melihatnya atau tidak)
  • mewarisi implementasi aktual (semua metode non-abstrak)

Dengan antarmuka , Anda memenuhi kontrak dengan menerapkan metode yang dinyatakan.

Itu cara klasik untuk melihatnya. Sekarang dengan Java 8 antarmuka menjadi campuran:

  • Anda masih belum mewarisi keadaan (karena antarmuka masih belum memiliki variabel instan)
  • Anda sekarang dapat mewarisi implementasi standar dari antarmuka

Akankah mengimplementasikan antarmuka yang semua metodenya memiliki implementasi standar masih dianggap sebagai 'implement', atau lebih tepatnya sebagai ekstensi? Saya tidak tahu. Karena kasus ini agak dibuat-buat (ini sebenarnya mengaktifkan multi-inheritance tanpa kewarganegaraan), saya masih menggunakan 'pewarisan' hanya dengan subkelas.

Peter Walser
sumber