Dalam salah satu wawancara saya, saya diminta untuk menjelaskan perbedaan antara Interface dan kelas Abstrak .
Inilah tanggapan saya:
Metode antarmuka Java secara implisit abstrak dan tidak dapat memiliki implementasi. Kelas abstrak Java dapat memiliki metode instan yang mengimplementasikan perilaku default.
Variabel yang dideklarasikan dalam antarmuka Java secara default final. Kelas abstrak dapat berisi variabel non-final.
Anggota antarmuka Java bersifat publik secara default. Kelas abstrak Java dapat memiliki cita rasa anggota kelas seperti privat, dilindungi, dll.
Antarmuka Java harus diimplementasikan menggunakan kata kunci "implement"; Kelas abstrak Java harus diperluas menggunakan kata kunci "extends".
Antarmuka hanya dapat memperluas antarmuka Java lainnya, kelas abstrak dapat memperluas kelas Java lainnya dan mengimplementasikan beberapa antarmuka Java.
Kelas Java dapat mengimplementasikan banyak antarmuka tetapi hanya dapat memperluas satu kelas abstrak.
Namun, pewawancara tidak puas, dan mengatakan kepada saya bahwa deskripsi ini mewakili " pengetahuan kutu buku ".
Dia meminta saya untuk tanggapan yang lebih praktis, menjelaskan kapan saya akan memilih kelas abstrak dari sebuah antarmuka, menggunakan contoh-contoh praktis .
Di mana saya salah?
sumber
Jawaban:
Saya akan memberi Anda contoh pertama:
Misalkan Anda memiliki 3 database dalam aplikasi Anda. Maka setiap implementasi untuk database itu perlu mendefinisikan 2 metode di atas:
Tetapi bagaimana jika
encryptPassword()
tidak tergantung pada basis data, dan itu sama untuk setiap kelas? Maka hal di atas tidak akan menjadi pendekatan yang baik.Sebagai gantinya, pertimbangkan pendekatan ini:
Sekarang di setiap kelas anak, kita hanya perlu menerapkan satu metode - metode yang bergantung pada basis data.
sumber
Tidak ada yang sempurna di dunia ini. Mereka mungkin mengharapkan lebih dari pendekatan praktis.
Tetapi setelah penjelasan Anda, Anda dapat menambahkan baris-baris ini dengan pendekatan yang sedikit berbeda.
Antarmuka adalah aturan (aturan karena Anda harus memberikan implementasi kepada mereka yang tidak dapat Anda abaikan atau hindari, sehingga diberlakukan seperti aturan) yang berfungsi sebagai dokumen pemahaman bersama di antara berbagai tim dalam pengembangan perangkat lunak.
Antarmuka memberikan ide apa yang harus dilakukan tetapi tidak bagaimana itu akan dilakukan. Jadi implementasi sepenuhnya tergantung pada pengembang dengan mengikuti aturan yang diberikan (artinya diberikan tanda tangan metode).
Kelas abstrak dapat berisi deklarasi abstrak, implementasi konkret, atau keduanya.
Deklarasi abstrak seperti aturan yang harus diikuti dan implementasi konkret seperti panduan (Anda dapat menggunakannya sebagaimana adanya atau Anda dapat mengabaikannya dengan menimpa dan memberikan implementasi Anda sendiri padanya).
Selain itu metode mana dengan tanda tangan yang sama dapat mengubah perilaku dalam konteks yang berbeda disediakan sebagai deklarasi antarmuka sebagai aturan untuk diterapkan sesuai dalam konteks yang berbeda.
Sunting: Java 8 memudahkan untuk mendefinisikan metode default dan statis di antarmuka.
Sekarang ketika sebuah kelas akan mengimplementasikan SomeInterface, itu tidak wajib untuk memberikan implementasi untuk metode antarmuka standar.
Jika kami memiliki antarmuka lain dengan metode berikut:
Java tidak mengizinkan perluasan beberapa kelas karena menghasilkan "Masalah Berlian" di mana kompiler tidak dapat memutuskan metode superclass mana yang akan digunakan. Dengan metode default, masalah berlian akan muncul untuk antarmuka juga. Karena jika suatu kelas mengimplementasikan keduanya
dan tidak menerapkan metode standar umum, kompiler tidak dapat memutuskan mana yang akan dipilih. Untuk menghindari masalah ini, di java 8 itu wajib untuk menerapkan metode standar umum dari antarmuka yang berbeda. Jika ada kelas yang mengimplementasikan kedua antarmuka di atas, itu harus menyediakan implementasi untuk metode defaultMethod () jika tidak, kompiler akan membuang kesalahan waktu kompilasi.
sumber
Anda membuat ringkasan yang baik tentang perbedaan praktis dalam penggunaan dan implementasi tetapi tidak mengatakan apa-apa tentang perbedaan makna.
Sebuah antarmuka adalah deskripsi dari perilaku kelas pelaksana akan memiliki. Kelas implementasi memastikan, bahwa ia akan memiliki metode ini yang dapat digunakan di dalamnya. Itu pada dasarnya adalah kontrak atau janji yang harus dibuat kelas.
Sebuah kelas abstrak adalah dasar untuk subclass yang berbeda bahwa perilaku saham yang tidak perlu berulang kali dibuat. Subclass harus menyelesaikan perilaku dan memiliki opsi untuk mengesampingkan perilaku yang telah ditentukan (selama itu tidak didefinisikan sebagai
final
atauprivate
).Anda akan menemukan contoh-contoh bagus dalam
java.util
paket yang menyertakan antarmuka sepertiList
dan kelas abstrak sepertiAbstractList
yang sudah mengimplementasikan antarmuka. The dokumentasi resmi menjelaskanAbstractList
sebagai berikut:sumber
abstract
kata kunci, yaitu ketika kompiler melihat ini, mereka tahu, informasi berikut tidak lengkap dan membutuhkan implementasi . Antarmuka selalu tidak lengkap, tetapi kelas abstrak adalah abstrak karena mereka harus memilikiincomplete (abstract)
metode.Antarmuka terdiri dari variabel singleton (public static final) dan metode abstrak publik. Kami biasanya lebih suka menggunakan antarmuka secara real time ketika kami tahu apa yang harus dilakukan tetapi tidak tahu bagaimana melakukannya .
Konsep ini dapat lebih dipahami dengan contoh:
Pertimbangkan kelas Pembayaran. Pembayaran dapat dilakukan dengan banyak cara, seperti PayPal, kartu kredit, dll. Jadi kami biasanya mengambil Pembayaran sebagai antarmuka kami yang berisi
makePayment()
metode dan CreditCard dan PayPal adalah dua kelas implementasi.Dalam contoh di atas CreditCard dan PayPal adalah dua kelas / strategi implementasi. Antarmuka juga memungkinkan kita konsep pewarisan berganda di Jawa yang tidak dapat diselesaikan oleh kelas abstrak.
Kami memilih kelas abstrak ketika ada beberapa fitur yang kami tahu harus melakukan apa, dan fitur lain yang kami tahu caranya .
Perhatikan contoh berikut:
Jika kita menambahkan metode (konkret / abstrak) di masa depan ke kelas abstrak yang diberikan, maka kelas implementasi tidak perlu mengubah kode-kodenya. Namun, jika kita menambahkan metode di antarmuka di masa mendatang, kita harus menambahkan implementasi ke semua kelas yang mengimplementasikan antarmuka itu, jika tidak, kompilasi kesalahan waktu terjadi.
Ada perbedaan lain tetapi ini adalah perbedaan besar yang mungkin seperti yang diharapkan pewawancara Anda. Semoga ini bermanfaat.
sumber
interface
danabstract class
.Perbedaan antara kelas Abstact dan antarmuka
Metode Default Antarmuka di Java 8
Metode Statis Antarmuka Java
Antarmuka Fungsional Java
Kelas abstrak versus antarmuka di Java 8
Perbedaan Konseptual:
Kelas abstrak berlaku untuk implementasi skeletal (yaitu parsial) dari antarmuka tetapi tidak boleh ada tanpa antarmuka yang cocok.
Jadi ketika kelas abstrak secara efektif direduksi menjadi visibilitas rendah, implementasi kerangka antarmuka, dapatkah metode standar juga mengambilnya? Jelas: Tidak! Menerapkan antarmuka hampir selalu membutuhkan beberapa atau semua alat pembangun kelas yang kurang dimiliki metode standar. Dan jika beberapa antarmuka tidak, itu jelas merupakan kasus khusus, yang seharusnya tidak membuat Anda tersesat.
Metode Default Antarmuka di Java 8
Java 8 memperkenalkan " Metode Default " atau (metode Defender) fitur baru, yang memungkinkan pengembang untuk menambahkan metode baru ke Antarmuka tanpa merusak implementasi Antarmuka yang ada. Ini memberikan fleksibilitas untuk memungkinkan Interface mendefinisikan implementasi yang akan digunakan sebagai default dalam situasi di mana Kelas konkret gagal menyediakan implementasi untuk metode itu.
Mari kita perhatikan contoh kecil untuk memahami cara kerjanya:
Kelas berikut akan berhasil dikompilasi di Java JDK 8,
Jika Anda membuat instance dari OldInterfaceImpl:
Metode Bawaan:
Metode default dapat diberikan ke Antarmuka tanpa memengaruhi Kelas implementasi karena mencakup implementasi. Jika setiap metode ditambahkan dalam Interface yang didefinisikan dengan implementasi maka tidak ada Kelas pelaksana yang terpengaruh. Kelas pelaksana dapat mengganti implementasi default yang disediakan oleh Antarmuka.
Saat kami memperluas antarmuka yang berisi metode default, kami dapat melakukan yang berikut,
Kesalahan kompilasi metode ForEach diselesaikan menggunakan Metode Default
Untuk Java 8, koleksi JDK telah diperluas dan metode forEach ditambahkan ke seluruh koleksi (yang bekerja bersama dengan lambdas). Dengan cara konvensional, kode tersebut terlihat seperti di bawah ini,
Karena hasil ini setiap Kelas pelaksana dengan kesalahan kompilasi, metode default ditambahkan dengan implementasi yang diperlukan agar implementasi yang ada tidak boleh diubah.
Antarmuka Iterable dengan metode Default di bawah ini,
Mekanisme yang sama telah digunakan untuk menambahkan Stream di Antarmuka JDK tanpa melanggar Kelas pelaksana.
Metode Default dan Beberapa Masalah Ambiguitas Warisan
Karena Kelas java dapat mengimplementasikan beberapa Antarmuka dan setiap Antarmuka dapat menentukan metode default dengan metode tanda tangan yang sama, oleh karena itu, metode yang diwariskan dapat saling bertentangan.
Pertimbangkan contoh di bawah ini,
Kode di atas akan gagal dikompilasi dengan kesalahan berikut,
Untuk memperbaiki kelas ini, kita perlu menyediakan implementasi metode default:
Lebih lanjut, jika kita ingin menjalankan implementasi default yang disediakan oleh salah satu Antarmuka super daripada implementasi kita sendiri, kita dapat melakukannya sebagai berikut,
Kami dapat memilih implementasi default atau keduanya sebagai bagian dari metode baru kami.
Poin penting tentang metode default antarmuka java:
Tautan Sumber Daya:
Metode Statis Antarmuka Java
Metode Antarmuka Java Interface, contoh kode, metode statis vs metode standar
Metode statis antarmuka Java mirip dengan metode default kecuali bahwa kita tidak bisa menimpanya di kelas implementasi. Fitur ini membantu kita menghindari hasil yang tidak diinginkan jika implementasi buruk di kelas implementasi. Mari kita lihat ini dengan contoh sederhana.
Sekarang mari kita lihat kelas implementasi yang memiliki metode isNull () dengan implementasi yang buruk.
Perhatikan bahwa isNull (String str) adalah metode kelas sederhana, itu tidak mengesampingkan metode antarmuka. Sebagai contoh, jika kita akan menambahkan anotasi @Override ke metode isNull (), itu akan menghasilkan kesalahan kompiler.
Sekarang ketika kita akan menjalankan aplikasi, kita mendapatkan output berikut.
Jika kita membuat metode antarmuka dari statis ke default, kita akan mendapatkan output berikut.
Metode statis antarmuka Java hanya dapat dilihat oleh metode antarmuka, jika kita menghapus metode isNull () dari kelas MyDataImpl, kita tidak akan dapat menggunakannya untuk objek MyDataImpl. Namun seperti metode statis lainnya, kita dapat menggunakan metode statis antarmuka menggunakan nama kelas. Misalnya, pernyataan yang valid adalah:
Poin penting tentang metode statis antarmuka java:
Antarmuka Fungsional Java
Sebelum saya menyimpulkan posting, saya ingin memberikan pengantar singkat untuk antarmuka Fungsional. Antarmuka dengan tepat satu metode abstrak dikenal sebagai Antarmuka Fungsional.
Anotasi baru
@FunctionalInterface
telah diperkenalkan untuk menandai antarmuka sebagai Antarmuka Fungsional.@FunctionalInterface
anotasi adalah fasilitas untuk menghindari penambahan metode abstrak yang tidak disengaja dalam antarmuka fungsional. Ini opsional tetapi praktik yang baik untuk menggunakannya.Antarmuka fungsional sudah lama ditunggu dan banyak dicari fitur Java 8 karena memungkinkan kita untuk menggunakan ekspresi lambda untuk instantiate mereka. Paket java.util.function baru dengan banyak antarmuka fungsional ditambahkan untuk menyediakan tipe target untuk ekspresi lambda dan referensi metode. Kami akan melihat antarmuka fungsional dan ekspresi lambda di posting mendatang.
Lokasi Sumber Daya:
sumber
Semua pernyataan Anda valid kecuali pernyataan pertama Anda (setelah rilis Java 8):
Dari halaman dokumentasi :
Metode standar:
Antarmuka dapat memiliki metode default , tetapi berbeda dari metode abstrak di kelas abstrak.
Saat Anda memperluas antarmuka yang berisi metode default, Anda dapat melakukan hal berikut:
abstract
.Metode Statis:
Selain metode default, Anda dapat menentukan metode statis di antarmuka. (Metode statis adalah metode yang dikaitkan dengan kelas di mana ia didefinisikan daripada dengan objek apa pun. Setiap instance kelas berbagi metode statisnya.)
Ini memudahkan Anda untuk mengatur metode pembantu di perpustakaan Anda;
Contoh kode dari halaman dokumentasi tentang
interface
memilikistatic
dandefault
metode.Gunakan pedoman di bawah ini untuk memilih apakah akan menggunakan antarmuka atau kelas abstrak.
Antarmuka:
Kelas abstrak:
Bagikan kode di antara beberapa kelas yang terkait erat. Itu menetapkan adalah suatu hubungan.
Berbagi keadaan umum di antara kelas terkait (negara dapat dimodifikasi dalam kelas beton)
Posting terkait:
Antarmuka vs Kelas Abstrak (OO umum)
Implements vs extends: Kapan digunakan? Apa bedanya?
Dengan melihat contoh-contoh ini, Anda dapat memahaminya
Kelas yang tidak terkait dapat memiliki kemampuan melalui antarmuka tetapi kelas terkait mengubah perilaku melalui ekstensi kelas dasar.
sumber
stateless
dalam antarmuka adalah hit yang bagus. Antarmuka tidak dapat memiliki keadaan apa pun (Antarmuka dapat memiliki konstanta tetapi bersifat final / statis sehingga tidak dapat diubah).Penjelasan Anda terlihat bagus, tetapi mungkin itu terlihat seperti Anda membaca semuanya dari buku teks? : - /
Yang lebih saya pedulikan adalah, seberapa solid contoh Anda? Apakah Anda repot-repot memasukkan hampir semua perbedaan antara abstrak dan antarmuka?
Secara pribadi, saya akan menyarankan tautan ini: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
untuk daftar perbedaan lengkap ..
Semoga ini membantu Anda dan semua pembaca lainnya dalam wawancara di masa depan
sumber
Banyak pengembang junior membuat kesalahan dengan memikirkan antarmuka, kelas abstrak dan konkret sebagai sedikit variasi dari hal yang sama, dan memilih salah satunya murni dengan alasan teknis: Apakah saya memerlukan banyak pewarisan? Apakah saya perlu tempat untuk meletakkan metode umum? Apakah saya perlu repot dengan sesuatu selain kelas yang konkret? Ini salah, dan tersembunyi dalam pertanyaan-pertanyaan ini adalah masalah utama: "Saya" . Ketika Anda menulis kode untuk diri sendiri, Anda jarang memikirkan pengembang lain saat ini atau di masa depan yang sedang mengerjakan atau dengan kode Anda.
Antarmuka dan kelas abstrak, meskipun tampaknya serupa dari sudut pandang teknis, memiliki arti dan tujuan yang sama sekali berbeda.
Ringkasan
Antarmuka mendefinisikan kontrak yang beberapa implementasi akan memenuhi untuk Anda .
Kelas abstrak menyediakan perilaku default yang dapat digunakan kembali oleh implementasi Anda .
Dua poin di atas adalah yang saya cari saat wawancara, dan merupakan ringkasan yang cukup ringkas. Baca terus untuk detail lebih lanjut.
Ringkasan alternatif
Contohnya
Dengan kata lain: Kelas konkret melakukan pekerjaan yang sebenarnya, dengan cara yang sangat spesifik. Sebagai contoh, sebuah
ArrayList
menggunakan area memori yang berdekatan untuk menyimpan daftar objek dalam cara yang kompak yang menawarkan akses acak cepat, iterasi, dan perubahan di tempat, tetapi mengerikan dalam penyisipan, penghapusan, dan kadang-kadang bahkan penambahan; sementara itu, aLinkedList
menggunakan node yang terhubung ganda untuk menyimpan daftar objek, yang sebaliknya menawarkan iterasi cepat, perubahan di tempat, dan penyisipan / penghapusan / penambahan, tetapi mengerikan pada akses acak. Kedua jenis daftar ini dioptimalkan untuk berbagai kasus penggunaan, dan sangat penting bagaimana Anda akan menggunakannya. Saat Anda mencoba memeras kinerja dari daftar yang sangat berinteraksi dengan Anda, dan ketika memilih jenis daftar terserah Anda, Anda harus hati-hati memilih yang mana yang Anda instantiating.Di sisi lain, pengguna tingkat tinggi dari daftar tidak benar-benar peduli bagaimana itu sebenarnya diterapkan, dan mereka harus diisolasi dari perincian ini. Mari kita bayangkan bahwa Java tidak mengekspos
List
antarmuka, tetapi hanya memilikiList
kelas nyata yang sebenarnyaLinkedList
sekarang. Semua pengembang Java akan menyesuaikan kodenya agar sesuai dengan detail implementasi: hindari akses acak, tambahkan cache untuk mempercepat akses, atau cukup implementasi ulangArrayList
sendiri, meskipun itu tidak sesuai dengan semua kode lain yangList
hanya berfungsi dengan baik . Itu akan mengerikan ... Tapi sekarang bayangkan bahwa master Java benar-benar menyadari bahwa daftar tertaut mengerikan untuk sebagian besar kasus penggunaan aktual, dan memutuskan untuk beralih ke daftar array hanya untuk merekaList
kelas tersedia. Ini akan memengaruhi kinerja setiap program Java di dunia, dan orang-orang tidak akan senang karenanya. Dan penyebab utamanya adalah detail implementasi tersedia, dan pengembang berasumsi bahwa detail itu adalah kontrak permanen yang dapat mereka andalkan. Inilah sebabnya mengapa penting untuk menyembunyikan detail implementasi, dan hanya mendefinisikan kontrak abstrak. Ini adalah tujuan dari sebuah antarmuka: tentukan input apa yang diterima suatu metode, dan output seperti apa yang diharapkan, tanpa memaparkan semua nyali yang akan menggoda programmer untuk mengubah kode mereka agar sesuai dengan detail internal yang mungkin berubah dengan pembaruan di masa mendatang. .Kelas abstrak berada di tengah-tengah antara antarmuka dan kelas konkret. Seharusnya membantu implementasi berbagi kode umum atau membosankan. Misalnya,
AbstractCollection
memberikan implementasi dasar untukisEmpty
berdasarkan ukuran adalah 0,contains
seperti iterate dan bandingkan,addAll
seperti diulangadd
, dan sebagainya. Ini memungkinkan implementasi fokus pada bagian-bagian penting yang membedakan di antara mereka: bagaimana sebenarnya menyimpan dan mengambil data.Perspektif lain: API versus SPI
Antarmuka adalah gateway kohesi rendah antara berbagai bagian kode. Mereka memungkinkan perpustakaan ada dan berkembang tanpa merusak setiap pengguna perpustakaan ketika sesuatu berubah secara internal. Ini disebut Antarmuka Pemrograman Aplikasi , bukan Kelas Pemrograman Aplikasi. Pada skala yang lebih kecil, mereka juga memungkinkan banyak pengembang untuk berkolaborasi dengan sukses pada proyek-proyek skala besar, dengan memisahkan berbagai modul melalui antarmuka yang terdokumentasi dengan baik.
Kelas abstrak adalah pembantu kohesi tinggi yang akan digunakan saat mengimplementasikan antarmuka, dengan asumsi beberapa tingkat detail implementasi. Atau, kelas abstrak digunakan untuk mendefinisikan SPI, Antarmuka Penyedia Layanan.
Perbedaan antara API dan SPI adalah halus, tetapi penting: untuk API, fokusnya adalah pada siapa yang menggunakannya , dan untuk SPI fokusnya adalah pada siapa yang mengimplementasikannya .
Menambahkan metode ke API mudah, semua pengguna API yang ada masih akan dikompilasi. Menambahkan metode ke SPI sulit, karena setiap penyedia layanan (implementasi konkret) harus menerapkan metode baru. Jika antarmuka digunakan untuk mendefinisikan SPI, penyedia harus merilis versi baru setiap kali kontrak SPI berubah. Jika kelas abstrak digunakan sebagai gantinya, metode baru dapat didefinisikan dalam hal metode abstrak yang ada, atau sebagai
throw not implemented exception
bertopik kosong , yang setidaknya akan memungkinkan versi yang lebih lama dari implementasi layanan untuk tetap dikompilasi dan dijalankan.Catatan tentang Java 8 dan metode default
Meskipun Java 8 memperkenalkan metode default untuk antarmuka, yang membuat garis antara antarmuka dan kelas abstrak bahkan lebih blurrier, ini bukan agar implementasi dapat menggunakan kembali kode, tetapi untuk membuatnya lebih mudah untuk mengubah antarmuka yang berfungsi baik sebagai API dan sebagai SPI (atau salah digunakan untuk mendefinisikan SPI, bukan kelas abstrak).
"Pengetahuan buku"
Rincian teknis yang diberikan dalam jawaban OP dianggap "pengetahuan buku" karena ini biasanya pendekatan yang digunakan di sekolah dan di sebagian besar buku teknologi tentang bahasa: apa itu, bukan bagaimana menggunakannya dalam praktik, terutama dalam aplikasi skala besar .
Inilah analogi: seharusnya pertanyaannya adalah:
Jawaban teknisnya seperti:
Itu semua benar, tetapi sepenuhnya merindukan poin bahwa mereka adalah dua hal yang sama sekali berbeda, dan keduanya dapat digunakan pada saat yang sama untuk tujuan yang berbeda, dan aspek "melakukannya" bukanlah hal yang paling penting tentang salah satu dari dua opsi tersebut. . Jawabannya tidak memiliki perspektif, itu menunjukkan cara berpikir yang tidak matang, sementara benar menyajikan "fakta".
sumber
Bagaimana dengan berpikir dengan cara berikut:
Jadi ketika Anda memiliki kelas abstrak Mamalia, Manusia subkelas, dan antarmuka Mengemudi, maka Anda bisa mengatakan
Saran saya adalah ungkapan pengetahuan buku menunjukkan bahwa ia ingin mendengar perbedaan semantik antara keduanya (seperti yang sudah disarankan orang lain di sini).
sumber
Antarmuka adalah "kontrak" di mana kelas yang mengimplementasikan kontrak berjanji untuk mengimplementasikan metode. Contoh di mana saya harus menulis antarmuka bukan kelas adalah ketika saya meningkatkan permainan dari 2D ke 3D. Saya harus membuat antarmuka untuk berbagi kelas antara versi 2D dan 3D game.
Lalu saya bisa menerapkan metode yang didasarkan pada lingkungan, sementara masih bisa memanggil metode-metode dari objek yang tidak tahu versi permainan yang memuat.
public class Adventure extends JFrame implements Playable
public class Dungeon3D extends SimpleApplication implements Playable
public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable
Biasanya, di gameworld, dunia bisa menjadi kelas abstrak yang melakukan metode pada permainan:
sumber
Kelas abstrak bukan abstraksi murni karena koleksi betonnya (metode yang diterapkan) serta metode yang tidak diterapkan. Tetapi Antarmuka adalah abstraksi murni karena hanya ada metode yang tidak diimplementasikan bukan metode konkret.
Mengapa kelas abstrak?
Mengapa Antarmuka?
sumber
Sebuah antarmuka seperti satu set gen yang didokumentasikan publik untuk memiliki beberapa jenis efek: tes A DNA akan memberitahu saya apakah saya punya mereka - dan jika saya lakukan, saya secara terbuka dapat membuatnya diketahui bahwa aku seorang "pembawa "Dan sebagian dari perilaku atau keadaan saya akan sesuai dengan mereka. (Tapi tentu saja, saya mungkin memiliki banyak gen lain yang memberikan sifat di luar lingkup ini.)
Sebuah kelas abstrak seperti nenek moyang mati dari spesies tunggal-seks (*): Dia tidak dapat dibawa ke kehidupan, tetapi hidup (yaitu non-abstrak ) mewarisi keturunan semua gen-nya.
(*) Untuk meregangkan metafora ini, katakanlah semua anggota spesies hidup pada usia yang sama. Ini berarti semua leluhur leluhur yang mati juga harus mati - dan demikian pula, semua keturunan leluhur yang hidup haruslah hidup.
sumber
Saya melakukan wawancara untuk bekerja dan saya akan melihat jawaban Anda juga tidak baik (maaf tapi saya sangat jujur). Kedengarannya seperti Anda telah membaca tentang perbedaan dan merevisi jawaban, tetapi mungkin Anda belum pernah menggunakannya dalam praktik.
Penjelasan yang baik tentang mengapa Anda akan menggunakan masing-masing bisa jauh lebih baik daripada memiliki penjelasan yang tepat tentang perbedaannya. Pengusaha ultimatley ingin programmer untuk melakukan hal-hal yang tidak mengenal mereka yang mungkin sulit ditunjukkan dalam sebuah wawancara. Jawaban yang Anda berikan akan baik jika melamar pekerjaan berbasis teknis atau dokumentasi tetapi bukan peran pengembang.
Semoga sukses dengan wawancara di masa depan.
Juga jawaban saya untuk pertanyaan ini lebih tentang teknik wawancara daripada materi teknis yang Anda berikan. Mungkin pertimbangkan untuk membacanya. https://workplace.stackexchange.com/ dapat menjadi tempat yang sangat baik untuk hal semacam ini.
sumber
Anda memilih Antarmuka di Jawa untuk menghindari Masalah Intan di beberapa pewarisan .
Jika Anda ingin semua metode Anda diterapkan oleh klien Anda, Anda pergi untuk antarmuka. Ini berarti Anda mendesain seluruh aplikasi secara abstrak.
Anda memilih kelas abstrak jika Anda sudah tahu kesamaan. Misalnya Ambil kelas abstrak
Car
. Pada level yang lebih tinggi Anda menerapkan metode mobil umum seperticalculateRPM()
. Ini adalah metode yang umum dan Anda membiarkan klien menerapkan perilakunya seperticalculateMaxSpeed()
dll. Mungkin Anda akan menjelaskan dengan memberikan beberapa contoh waktu nyata yang Anda temui dalam pekerjaan Anda sehari-hari.sumber
Antarmuka murni abstrak. kami tidak memiliki kode implementasi dalam antarmuka.
Kelas abstrak berisi metode dan implementasinya.
klik di sini untuk menonton tutorial tentang antarmuka dan kelas abstrak
sumber
Perbedaan utama yang saya amati adalah bahwa kelas abstrak memberi kita beberapa perilaku umum yang sudah dilaksanakan dan subkelas hanya perlu mengimplementasikan fungsionalitas khusus yang sesuai dengan mereka. sedangkan untuk antarmuka hanya akan menentukan tugas apa yang perlu dilakukan dan tidak ada implementasi yang diberikan oleh antarmuka. Saya dapat mengatakan itu menentukan kontrak antara dirinya dan kelas yang diimplementasikan.
sumber
Bahkan saya telah menghadapi pertanyaan yang sama dalam beberapa wawancara dan percayalah, membuat waktu Anda menyedihkan untuk meyakinkan pewawancara. Jika saya melekatkan semua jawaban dari atas maka saya perlu menambahkan satu poin kunci lagi untuk membuatnya lebih meyakinkan dan memanfaatkan OO yang terbaik
Jika Anda tidak merencanakan modifikasi apa pun dalam aturan , untuk subclass yang harus diikuti, untuk masa depan yang panjang, pergi untuk antarmuka, karena Anda tidak dapat memodifikasi di dalamnya dan jika Anda melakukannya, Anda harus pergi untuk perubahan di semua sub kelas lainnya, sedangkan, jika Anda berpikir, Anda ingin menggunakan kembali fungsionalitas, menetapkan beberapa aturan dan juga membuatnya terbuka untuk modifikasi , pilih kelas Abstrak.
Pikirkan dengan cara ini, Anda telah menggunakan layanan yang dapat dikonsumsi atau Anda telah memberikan beberapa kode kepada dunia dan Anda memiliki kesempatan untuk mengubah sesuatu, misalkan pemeriksaan keamanan Dan Jika saya menjadi konsumen kode dan Suatu pagi setelah pembaruan, saya temukan semua tanda baca di Eclipse saya, seluruh aplikasi sedang down. Jadi untuk mencegah mimpi buruk seperti itu, gunakan Abstract over Interfaces
Saya pikir ini mungkin meyakinkan Pewawancara sampai batas ... Selamat Wawancara Di Depan.
sumber
Ketika saya mencoba untuk berbagi perilaku antara 2 kelas yang terkait erat, saya membuat kelas abstrak yang memegang perilaku umum dan berfungsi sebagai induk bagi kedua kelas.
Ketika saya mencoba mendefinisikan Tipe, daftar metode yang dapat dipanggil oleh pengguna objek saya, lalu saya membuat antarmuka.
Sebagai contoh, saya tidak akan pernah membuat kelas abstrak dengan 1 subkelas konkret karena kelas abstrak adalah tentang perilaku berbagi. Tapi saya mungkin bisa membuat antarmuka dengan hanya satu implementasi. Pengguna kode saya tidak akan tahu bahwa hanya ada satu implementasi. Memang, dalam rilis mendatang mungkin ada beberapa implementasi, yang semuanya adalah subkelas dari beberapa kelas abstrak baru yang bahkan tidak ada ketika saya membuat antarmuka.
Itu mungkin tampak agak terlalu kutu buku juga (meskipun saya belum pernah melihatnya menempatkannya di mana pun yang saya ingat). Jika pewawancara (atau OP) benar-benar menginginkan lebih banyak pengalaman pribadi saya tentang hal itu, saya akan siap dengan anekdot dari antarmuka yang telah berevolusi karena kebutuhan dan sebaliknya.
Satu hal lagi. Java 8 sekarang memungkinkan Anda untuk memasukkan kode default ke antarmuka, lebih jauh mengaburkan garis antara antarmuka dan kelas abstrak. Tetapi dari apa yang saya lihat, fitur itu terlalu sering digunakan bahkan oleh pembuat perpustakaan inti Java. Fitur itu ditambahkan, dan memang demikian, untuk memungkinkan untuk memperluas antarmuka tanpa membuat ketidakcocokan biner. Tetapi jika Anda membuat Tipe baru dengan mendefinisikan antarmuka, maka antarmuka tersebut HANYA sebuah antarmuka. Jika Anda ingin juga memberikan kode umum, maka tentu saja buatlah kelas pembantu (abstrak atau konkret). Jangan mengacaukan antarmuka Anda dari awal dengan fungsionalitas yang mungkin ingin Anda ubah.
sumber
Perbedaan mendasar antara antarmuka dan kelas abstrak adalah, antarmuka mendukung multiple inheritance tetapi kelas abstrak tidak.
Di kelas abstrak juga Anda dapat menyediakan semua metode abstrak seperti antarmuka.
mengapa kelas abstrak diperlukan?
Dalam beberapa skenario, saat memproses permintaan pengguna, kelas abstrak tidak tahu niat pengguna apa. Dalam skenario itu, kami akan mendefinisikan satu metode abstrak di kelas dan meminta pengguna yang memperluas kelas ini, harap berikan niat Anda dalam metode abstrak. Dalam hal ini kelas abstrak sangat berguna
Mengapa antarmuka diperlukan?
Katakanlah, saya punya pekerjaan yang saya tidak punya pengalaman di bidang itu. Contoh, jika Anda ingin membangun sebuah bangunan atau bendungan, lalu apa yang akan Anda lakukan dalam skenario itu?
Di sini saya tidak peduli tentang logika bagaimana mereka membangun. Objek akhir memenuhi persyaratan saya atau tidak, itu hanya poin kunci saya.
Di sini persyaratan Anda disebut antarmuka dan konstruktor disebut implementor.
sumber
Dalam beberapa kata, saya akan menjawab seperti ini:
Kelas abstrak dapat diperlakukan sebagai sesuatu di antara dua kasus ini (memperkenalkan beberapa keadaan tetapi juga mengharuskan Anda untuk mendefinisikan perilaku), kelas yang sepenuhnya abstrak adalah antarmuka (ini adalah pengembangan lebih lanjut dari kelas yang terdiri dari metode virtual hanya dalam C ++ sebagai Sejauh yang saya tahu sintaksnya).
Tentu saja, mulai dari Jawa 8 hal-hal sedikit berubah, tetapi idenya masih sama.
Saya kira ini cukup untuk wawancara Java biasa, jika Anda tidak diwawancarai ke tim kompiler.
sumber
Dari apa yang saya pahami, sebuah Antarmuka, yang terdiri dari variabel akhir dan metode tanpa implementasi, diimplementasikan oleh kelas untuk memperoleh sekelompok metode atau metode yang terkait satu sama lain. Di sisi lain, kelas abstrak, yang dapat berisi variabel dan metode non-final dengan implementasi, biasanya digunakan sebagai panduan atau sebagai superclass dari mana semua kelas terkait atau sejenis mewarisi. Dengan kata lain, kelas abstrak berisi semua metode / variabel yang dibagikan oleh semua subkelasnya.
sumber
Di kelas abstrak, Anda dapat menulis implementasi metode default! Tetapi dalam Interface Anda tidak bisa. Pada dasarnya, dalam antarmuka terdapat metode virtual murni yang harus diimplementasikan oleh kelas yang mengimplementasikan antarmuka.
sumber
Ya, respons Anda secara teknis benar tetapi di mana Anda salah tidak menunjukkannya, Anda memahami sisi positif dan buruk dari memilih satu di antara yang lain. Selain itu, mereka mungkin khawatir / panik tentang kompatibilitas basis kode mereka dengan peningkatan di masa depan. Jenis respons ini mungkin telah membantu (selain apa yang Anda katakan):
Semoga sukses di wawancara Anda berikutnya!
sumber
Saya akan mencoba menjawab dengan menggunakan skenario praktis untuk menunjukkan perbedaan antara keduanya.
Antarmuka datang dengan nol payload yaitu tidak ada negara yang harus dipertahankan dan dengan demikian merupakan pilihan yang lebih baik untuk hanya mengasosiasikan kontrak (kemampuan) dengan kelas.
Misalnya, saya memiliki kelas Tugas yang melakukan beberapa tindakan, sekarang untuk menjalankan tugas di utas terpisah, saya tidak benar-benar perlu memperluas kelas Utas, bukan pilihan yang lebih baik adalah membuat Tugas mengimplementasikan antarmuka Runnable (mis. Mengimplementasikan metode run () -nya ) dan kemudian meneruskan objek kelas Tugas ini ke instance Thread dan memanggil metode start ().
Yah secara teknis itu mungkin tetapi desain bijaksana yang akan menjadi alasan pilihan yang buruk adalah:
Dengan kata lain, kelas tugas membutuhkan kemampuan untuk dijalankan di utas yang dicapai dengan menerapkan ayat antarmuka Runnable memperluas kelas Utas yang akan menjadikannya utas.
Penafian: contoh konyol berikut, cobalah untuk tidak menilai:
Sekarang Anda telah diberi pilihan untuk menjadi GodLike tetapi Anda dapat memilih untuk menjadi Forgiver saja (yaitu bukan GodLike) dan lakukan:
Atau Anda dapat memilih untuk menjadi seperti GodLike dan melakukan:
PS dengan antarmuka java 8 juga dapat memiliki metode statis juga default (implementasi yang dapat dikesampingkan) dan perbedaan antarmuka b / w dan kelas abstrak bahkan lebih dipersempit.
sumber
Hampir semuanya sepertinya sudah dibahas di sini .. Menambahkan hanya satu poin lagi tentang implementasi praktis
abstract
kelas:sumber
hmm sekarang orang-orang adalah pendekatan praktis lapar, Anda benar, tetapi sebagian besar pewawancara terlihat sesuai dengan kebutuhan mereka saat ini dan menginginkan pendekatan praktis.
setelah menyelesaikan jawaban Anda, Anda harus melompat pada contoh:
Abstrak:
misalnya kita memiliki fungsi gaji yang memiliki beberapa parametar yang sama untuk semua karyawan. maka kita dapat memiliki kelas abstrak yang disebut CTC dengan tubuh metode yang didefinisikan secara parsial dan akan diperluas oleh semua jenis karyawan dan mendapatkan redeined sesuai daging sapi ekstra mereka. Untuk fungsi umum.
Antarmuka
antarmuka di java memungkinkan untuk memiliki fungsi interfcae tanpa memperluas yang itu dan Anda harus jelas dengan penerapan tanda tangan fungsionalitas yang ingin Anda perkenalkan di aplikasi Anda. itu akan memaksa Anda untuk memiliki definisi. Untuk fungsi yang berbeda.
Anda dapat memiliki aktivitas paksa seperti itu dengan kelas abstrak juga dengan mendefinisikan methgos sebagai yang abstrak, sekarang sebuah kelas yang meluas kelas abstrak dan abstrak sampai ia menimpa fungsi abstrak itu.
sumber
Dari apa yang saya mengerti dan bagaimana saya mendekati,
Antarmuka seperti spesifikasi / kontrak, kelas apa pun yang mengimplementasikan kelas antarmuka harus mengimplementasikan semua metode yang didefinisikan dalam kelas abstrak (kecuali metode default (diperkenalkan di Java 8))
Sedangkan saya mendefinisikan abstrak kelas ketika saya tahu implementasi yang diperlukan untuk beberapa metode kelas dan beberapa metode saya masih tidak tahu apa yang akan menjadi implementasi (kita mungkin tahu fungsi tanda tangan tetapi bukan implementasi). Saya melakukan ini sehingga nanti di bagian pengembangan ketika saya tahu bagaimana metode ini harus diimplementasikan, saya hanya bisa memperluas kelas abstrak ini dan mengimplementasikan metode ini.
Catatan: Anda tidak dapat memiliki tubuh fungsi dalam metode antarmuka kecuali metode tersebut statis atau default.
sumber
Saya percaya apa yang pewawancara coba lakukan mungkin adalah perbedaan antara antarmuka dan implementasi.
Antarmuka - bukan antarmuka Java, tetapi "antarmuka" dalam istilah yang lebih umum - untuk modul kode, pada dasarnya, kontrak yang dibuat dengan kode klien yang menggunakan antarmuka.
Implementasi modul kode adalah kode internal yang membuat modul berfungsi. Seringkali Anda dapat mengimplementasikan antarmuka tertentu dalam lebih dari satu cara yang berbeda, dan bahkan mengubah implementasinya tanpa kode klien bahkan menyadari perubahan tersebut.
Antarmuka Java seharusnya hanya digunakan sebagai antarmuka dalam pengertian generik di atas, untuk menentukan bagaimana kelas berperilaku untuk kepentingan kode klien menggunakan kelas, tanpa menentukan implementasi apa pun. Jadi, sebuah antarmuka menyertakan tanda tangan metode - nama, tipe pengembalian, dan daftar argumen - untuk metode yang diharapkan dipanggil oleh kode klien, dan pada prinsipnya harus memiliki banyak Javadoc untuk setiap metode yang menggambarkan apa yang dilakukan metode itu. Alasan yang paling menarik untuk menggunakan antarmuka adalah jika Anda berencana untuk memiliki beberapa implementasi antarmuka yang berbeda, mungkin memilih implementasi tergantung pada konfigurasi penempatan.
Kelas abstrak Java, sebaliknya, menyediakan implementasi parsial kelas, daripada memiliki tujuan utama menentukan antarmuka. Ini harus digunakan ketika beberapa kelas berbagi kode, tetapi ketika subclass juga diharapkan untuk memberikan bagian dari implementasi. Ini memungkinkan kode bersama muncul hanya di satu tempat - kelas abstrak - sambil memperjelas bahwa bagian-bagian implementasi tidak ada dalam kelas abstrak dan diharapkan disediakan oleh subkelas.
sumber
jawaban Anda benar tetapi pewawancara mengharuskan Anda untuk membedakan menurut perspektif rekayasa perangkat lunak tidak sesuai dengan rincian Jawa.
Kata-kata sederhana:
Antarmuka adalah seperti antarmuka toko apa pun yang ditampilkan di sana harus ada di toko, jadi metode apa pun di Antarmuka harus ada diimplementasikan di kelas beton. Sekarang bagaimana jika beberapa kelas berbagi beberapa metode yang tepat dan bervariasi dalam yang lain. Misalkan Antarmuka adalah tentang toko yang berisi dua hal dan misalkan kita memiliki dua toko yang keduanya berisi peralatan olahraga tetapi satu memiliki pakaian ekstra dan yang lainnya memiliki sepatu ekstra. Jadi yang Anda lakukan adalah membuat kelas abstrak untuk Olahraga yang mengimplementasikan metode Olahraga dan membiarkan metode lainnya tidak diterapkan. Kelas abstrak di sini berarti bahwa toko ini tidak ada sendiri tetapi merupakan dasar untuk kelas / toko lain. Dengan cara ini Anda mengatur kode, menghindari kesalahan mereplikasi kode, menyatukan kode, dan memastikan penggunaan kembali oleh beberapa kelas lain.
sumber