Saya sadar bahwa ini adalah pertanyaan yang sangat mendasar, tetapi seorang pewawancara bertanya kepada saya dengan cara yang sangat licik dan saya tidak berdaya :(
Saya hanya tahu definisi material atau teoritis untuk sebuah antarmuka dan juga menerapkannya di banyak proyek yang saya kerjakan. Tapi saya benar-benar tidak mengerti mengapa dan bagaimana ini berguna.
Saya juga tidak mengerti satu hal pun dalam antarmuka. misalnya, kami menggunakan
conn.Dispose();
di blok akhirnya. Tapi saya tidak melihat bahwa kelas sedang mengimplementasikan atau mewarisi kelas IDisposable
interface ( SqlConnection
) yang saya maksud. Saya bertanya-tanya bagaimana saya bisa memanggil nama metode. Juga dalam hal yang sama, saya tidak memahami cara kerja metode Dispose karena, kita perlu mengimplementasikan tubuh fungsi dengan implementasi kita sendiri untuk semua metode antarmuka. Jadi bagaimana Antarmuka diterima atau disebut sebagai kontrak? Pertanyaan-pertanyaan ini terus bergulir di benak saya sampai sekarang dan terus terang saya tidak pernah melihat utas bagus yang akan menjelaskan pertanyaan saya dengan cara yang saya bisa mengerti.
MSDN seperti biasa terlihat sangat menakutkan dan tidak ada satu baris pun yang jelas di sana (Teman-teman , mohon maaf atas pengembangan tingkat tinggi, saya sangat merasa bahwa kode atau artikel apa pun harus mencapai pikiran siapa pun yang melihatnya, maka seperti yang dikatakan banyak orang, MSDN tidak berguna ).
Pewawancara berkata:
Dia memiliki 5 metode dan dia dengan senang hati mengimplementasikannya di kelas secara langsung, tetapi jika Anda harus menggunakan kelas atau antarmuka Abstrak, mana yang Anda pilih dan mengapa? Saya menjawabnya semua hal yang saya baca di berbagai blog mengatakan keuntungan dan kerugian dari kelas dan antarmuka abstrak, tetapi dia tidak yakin, dia mencoba untuk memahami "Mengapa Antarmuka" secara umum. "Mengapa kelas abstrak" secara umum bahkan jika saya dapat menerapkan metode yang sama hanya satu kali dan tidak akan mengubahnya.
Saya tidak melihat di mana di internet, saya bisa mendapatkan artikel yang akan menjelaskan saya dengan jelas tentang antarmuka dan fungsinya. Saya adalah salah satu dari banyak programmer, yang masih belum tahu tentang antarmuka (saya tahu teori dan metode yang saya gunakan) tetapi tidak puas karena saya memahaminya dengan jelas.
SqlConnection
mewarisiSystem.ComponentModel.Component
yang mengimplementasikanIDisposable
.SqlConnection
mengimplementasikanIDisposable
.Jawaban:
Antarmuka sangat bagus ketika Anda ingin membuat sesuatu seperti itu:
Dalam contoh saya, saya bisa menjadi pengembang yang menulis
MyLogClass
, dan pengembang lain, dapat membuat kelas mereka, dan ketika mereka ingin masuk, mereka mengimplementasikan antarmukaIMyLogInterface
. Itu karena mereka bertanya kepada saya apa yang perlu mereka terapkan untuk menggunakanWriteLog()
metode diMyLogClass
. Jawaban yang akan mereka temukan di antarmuka.sumber
MyClass
danMyOtherClass
mengapa Anda tidak menyebutaClass.WriteLog()
mengapa menambahkan langkah ekstra itu. ImplementasiWriteLog()
akan tetap berbeda untuk masing-masing kelas tetapi Anda sudah memiliki objek jadi mengapa meneruskannya ke kelas penangan?MyLogClass
WriteLog
metode. Jadi metodenya dapat menangani objek apa pun yang diimplementasikanIMyLogInterface
. Ini postingan menarik lainnya.Salah satu alasan saya menggunakan antarmuka adalah karena meningkatkan fleksibilitas kode. Katakanlah kita mendapat metode yang mengambil objek dari tipe kelas Akun sebagai parameter, seperti:
Masalah dengan ini, adalah bahwa parameter metode diperbaiki menuju implementasi akun. Ini bagus jika Anda tidak membutuhkan jenis akun lain. Ambil contoh ini, yang menggunakan antarmuka akun sebagai parameter.
Solusi ini tidak ditetapkan untuk implementasi, yang berarti saya dapat memberikan SuperSavingsAccount atau ExclusiveAccount (keduanya menerapkan antarmuka IAccount) dan mendapatkan perilaku berbeda untuk setiap akun yang diterapkan.
sumber
Antarmuka adalah kontrak yang harus diikuti oleh pelaksana. Kelas abstrak memungkinkan kontrak ditambah implementasi bersama - sesuatu yang tidak dapat dimiliki oleh Interfaces. Kelas dapat mengimplementasikan dan mewarisi banyak antarmuka. Kelas hanya dapat memperluas satu kelas abstrak.
Mengapa Antarmuka
IDbCommand
memilikiSqlCommand
danOracleCommand
yang mengimplementasikan antarmuka dengan cara tertentu )Mengapa Abstrak
sumber
DataContracts
) kami dalam Rakitan .NET ( misalnya Contracts.Shared.dll ) sehingga konsumen klien .NET dapat dengan mudah beroperasi menggunakanChannelFactory
( menghindari pembuatan kode melalui Tambahkan Referensi Layanan, dll. ) atau menggunakan Tambahkan Referensi Layanan dengan Jenis BersamaJadi dalam contoh ini, PowerSocket tidak mengetahui apa pun tentang objek lain. Semua objek bergantung pada Daya yang disediakan oleh PowerSocket, sehingga mereka mengimplementasikan IPowerPlug, dan dengan melakukan itu mereka dapat menyambungkannya.
Antarmuka berguna karena menyediakan kontrak yang dapat digunakan objek untuk bekerja bersama tanpa perlu mengetahui apa pun tentang satu sama lain.
sumber
Dalam satu kata - karena Polimorfisme !
Jika Anda "Memprogram ke Antarmuka, bukan Implementasi" daripada Anda dapat memasukkan objek berbeda yang berbagi antarmuka (tipe) yang sama ke dalam metode sebagai argumen. Dengan cara ini, kode metode Anda tidak digabungkan dengan implementasi kelas lain yang berarti selalu terbuka untuk bekerja dengan objek yang baru dibuat dari antarmuka yang sama. (Prinsip Buka / Tutup)
sumber
C # tidak memiliki pengetikan bebek - hanya karena Anda tahu metode tertentu diimplementasikan di sekumpulan kelas konkret tidak berarti Anda dapat memperlakukan semuanya sama sehubungan dengan memanggil metode itu. Menerapkan antarmuka memungkinkan Anda untuk memperlakukan semua kelas yang mengimplementasikannya sebagai jenis yang sama, berkenaan dengan definisi antarmuka itu.
sumber
Saya percaya bahwa banyak darah telah tumpah dalam menanyakan pertanyaan ini, dan banyak yang mencoba menyelesaikan masalah ini dengan menjelaskan istilah seperti robot yang tidak dapat dipahami oleh manusia normal.
Jadi Pertama. untuk mempelajari mengapa antarmuka dan mengapa abstrak Anda perlu mempelajari untuk apa mereka. Saya pribadi mempelajari dua ini saat menerapkan Kelas Pabrik. Anda menemukan tuturial yang baik di tautan ini
Sekarang mari kita gali berdasarkan tautan yang sudah saya berikan.
Anda memiliki kelas Kendaraan yang mungkin berubah sesuai kebutuhan pengguna (seperti menambahkan Truk , Tangki , Pesawat , dll. Dan kami punya
dan
dan keduanya memiliki Opsi Kontrak yang hanya mengatakan Kelas Saya harus memiliki metode Beli
Sekarang, Anda lihat, antarmuka itu hanya memberlakukan metode
Buy()
tetapi membiarkan kelas yang diwariskan memutuskan apa yang harus dilakukan ketika mereka mengimplementasikannya. Ini adalah batasan Antarmuka, dengan menggunakan antarmuka murni, Anda mungkin akan mengulangi beberapa tugas yang dapat kami implementasikan secara otomatis menggunakan abstact. Pada contoh kami, katakanlah, membeli setiap kendaraan memiliki diskon.Sekarang dengan menggunakan Kelas Pabrik, Anda dapat mencapai hal yang sama tetapi dengan menggunakan abstrak, Anda membiarkan kelas dasar menjalankan
Buy()
metode tersebut.sumber
Dengan antarmuka, Anda dapat melakukan hal berikut:
1) Buat antarmuka terpisah yang menawarkan potongan implementasi yang berbeda, memungkinkan antarmuka yang lebih kohesif.
2) Izinkan beberapa metode dengan nama yang sama antar antarmuka, karena hei, Anda tidak memiliki implementasi yang bertentangan, hanya tanda tangan.
3) Anda dapat membuat versi dan memisahkan antarmuka Anda secara independen dari implementasi Anda, memastikan kontrak terpenuhi.
4) Kode Anda dapat mengandalkan abstraksi daripada konkresi, memungkinkan injeksi ketergantungan cerdas, termasuk memasukkan uji coba, dll.
Ada banyak lagi alasan yang saya yakin, ini hanya beberapa.
Kelas abstrak memungkinkan Anda memiliki sebagian dasar beton untuk dikerjakan, ini tidak sama dengan antarmuka tetapi memiliki kualitasnya sendiri seperti kemampuan untuk membuat implementasi parsial menggunakan pola metode templat.
sumber
Sebagai contoh nyata jawaban @ user2211290:
Keduanya
Array
danList
memiliki antarmukaIList
. Di bawah ini kami memiliki astring[]
dan aList<string>
dan memeriksa keduanya dengan satu metode dengan menggunakan IList :sumber
Anda hanya dapat mewarisi dari satu kelas abstrak. Anda dapat mewarisi dari banyak antarmuka. Ini menentukan apa yang saya gunakan untuk sebagian besar kasus.
Keuntungan dari kelas abstrak adalah Anda dapat memiliki implementasi dasar. Namun, dalam kasus IDisposable, implementasi default tidak berguna, karena kelas dasar tidak tahu cara membersihkan semuanya dengan benar. Dengan demikian, sebuah antarmuka akan lebih cocok.
sumber
Kelas abstrak dan antarmuka adalah kontrak.
Ide kontrak adalah Anda menentukan beberapa perilaku. Jika Anda mengatakan Anda telah menerapkan, Anda telah menyetujui kontrak.
Pilihan abstrak atas antar muka adalah.
Semua keturunan non abstrak dari kelas abstrak akan mengimplementasikan kontrak.
melawan
Setiap kelas yang mengimplementasikan antarmuka akan mengimplementasikan kontrak.
Jadi, Anda menggunakan abstrak saat ingin menetapkan beberapa perilaku yang harus diterapkan oleh semua turunan dan menyelamatkan diri Anda sendiri dengan mendefinisikan antarmuka terpisah, tetapi sekarang semua yang memenuhi kontrak yang digabungkan secara efektif ini haruslah turunan.
sumber
Antarmuka adalah untuk membuat abstraksi (arketipe) dari abstraksi (kelas) dari realitas (objek).
Antarmuka adalah untuk menentukan persyaratan kontrak tanpa menyediakan implementasi yang disediakan oleh kelas.
Antarmuka adalah spesifikasi:
Antarmuka adalah artefak waktu desain untuk menentukan perilaku tidak bergerak dari konsep karena konsep itu sendiri dan statis.
Kelas adalah artefak waktu implementasi untuk menentukan struktur seluler dari realitas saat berinteraksi dan bergerak.
Apa itu antarmuka?
Ketika Anda mengamati kucing, Anda dapat mengatakan bahwa itu adalah hewan yang memiliki empat cakar, kepala, batang, ekor, dan rambut. Anda dapat melihat bahwa dia bisa berjalan, berlari, makan dan mengeong. Dan seterusnya.
Anda baru saja mendefinisikan antarmuka dengan propertinya dan operasinya. Karena itu, Anda belum menentukan modus operandi apa pun, tetapi hanya fitur dan kapabilitas tanpa mengetahui cara kerja segala sesuatunya: Anda telah menetapkan kemampuan dan perbedaan.
Karena itu, ini sebenarnya belum menjadi kelas meskipun di UML kami menyebutnya kelas dalam diagram kelas karena kami dapat mendefinisikan privat dan anggota yang dilindungi untuk mulai melihat artefak secara mendalam. Jangan bingung di sini karena di UML antarmuka adalah hal yang sedikit berbeda dari antarmuka di C #: itu seperti jalur akses parsial ke atom abstraksi. Karena itu kami mengatakan bahwa kelas dapat mengimplementasikan banyak antarmuka. Dengan demikian itu adalah hal yang sama, tetapi tidak, karena antarmuka dalam C # keduanya digunakan untuk mengabstraksi abstraksi dan untuk membatasi abstraksi ini sebagai titik akses. Ini dua kegunaan yang berbeda. Jadi kelas dalam UML mewakili antarmuka kopling penuh ke kelas pemrograman, sedangkan antarmuka UML mewakili antarmuka decoupling dari bagian kelas pemrograman. Memang, diagram kelas di UML tidak menangani implementasi dan semua artefaknya berada di tingkat antarmuka pemrograman. Sementara kami memetakan kelas UML ke kelas pemrograman, ini adalah transposisi abstraksi abstrak menjadi abstraksi konkret. Ada kehalusan yang menjelaskan dikotomi antara bidang desain dan bidang pemrograman. Jadi kelas dalam UML adalah kelas pemrograman dari sudut pandang antarmuka pemrograman sambil mempertimbangkan hal-hal yang tersembunyi di dalam.
Antarmuka juga memungkinkan untuk mensimulasikan beberapa warisan jika tidak tersedia dengan cara yang canggung. Misalnya, kelas kucing akan mengimplementasikan antarmuka kucing yang berasal dari antarmuka hewan. Kelas kucing ini juga akan mengimplementasikan antarmuka berikut: berjalan, berlari, makan, dan bersuara. Ini mengkompensasi tidak adanya banyak warisan di tingkat kelas, tetapi setiap kali Anda perlu menerapkan ulang semuanya dan Anda tidak dapat memfaktorkan kenyataan sebaik kenyataan itu sendiri melakukannya.
Untuk memahami bahwa kita dapat merujuk ke pengkodean Objek Pascal di mana Anda mendefinisikan dalam unit antarmuka dan bagian implementasi. Dalam antarmuka Anda menentukan tipe dan dalam implementasi Anda mengimplementasikan tipe:
Di sini, bagian antarmuka cocok dengan desain kelas UML sementara jenis Antarmuka dengan demikian adalah hal lain.
Jadi dalam bisnis kami, kami memiliki satu kata, antarmuka , untuk menominasikan dua hal yang berbeda tetapi serupa, dan ini merupakan sumber kebingungan.
Juga di C # misalnya, antarmuka pemrograman memungkinkan untuk mengkompensasi tidak adanya polimorfisme generik yang sebenarnya pada tipe terbuka tanpa benar-benar berhasil mencapai tujuan karena Anda kehilangan kemampuan yang diketik dengan kuat.
Bagaimanapun, antarmuka diperlukan untuk memungkinkan sistem yang tidak kompatibel untuk berkomunikasi tanpa mengkhawatirkan implementasi dan pengelolaan objek dalam memori seperti yang diperkenalkan dengan Model Objek Umum (Terdistribusi).
Apakah kelas itu?
Setelah mendefinisikan pengurangan realitas dari sudut pandang eksternal, Anda kemudian dapat mendeskripsikannya dari perspektif dalam: ini adalah kelas tempat Anda mendefinisikan pemrosesan data dan manajemen pesan untuk memungkinkan realitas yang telah Anda rangkum menjadi hidup dan berinteraksi terima kasih ke objek menggunakan instance.
Jadi di UML Anda menyadari pencelupan fraktal di roda mesin dan Anda menggambarkan status, interaksi, dan seterusnya untuk dapat menerapkan abstraksi dari fragmen realitas yang ingin Anda tangani.
Dengan demikian, kelas abstrak entah bagaimana setara dengan antarmuka dari sudut pandang kompilator.
Informasi lebih lanjut
Protokol (pemrograman berorientasi objek)
C # - Antarmuka
C # - Kelas
sumber
Izinkan saya memberi tahu Anda tentang pemanggang roti terbang.
Ada, tentu saja, banyak situasi di mana Anda dapat membangun sistem perangkat lunak yang berfungsi tanpa mendeklarasikan atau mengimplementasikan antarmuka sama sekali: desain perangkat lunak berorientasi objek apa pun dapat direalisasikan hanya dengan menggunakan kelas.
Kemudian lagi, sistem perangkat lunak apa pun juga dapat diimplementasikan dalam Bahasa Rakitan, atau lebih baik lagi dalam Kode Mesin. Alasan mengapa kami menggunakan mekanisme abstraksi adalah karena mekanisme tersebut cenderung mempermudah. Antarmuka adalah mekanisme abstraksi.
Jadi, kebetulan saja ada beberapa desain berorientasi objek non-sepele yang jauh lebih mudah diimplementasikan jika Anda menggunakan antarmuka, sehingga antarmuka praktis menjadi diperlukan dalam kasus tersebut.
Desain non-sepele ini berkaitan dengan multiple inheritance, yang, dalam bentuk "sebenarnya", adalah ketika sebuah kelas mewarisi tidak hanya dari satu kelas dasar, tetapi dari dua atau lebih kelas dasar. Bentuk sebenarnya ini tidak mungkin dilakukan di C #, tetapi sebelum bahasa seperti C # dan Java muncul, bahasa yang digunakan adalah C ++, yang sepenuhnya mendukung pewarisan ganda yang sebenarnya. Sayangnya, true multiple inheritance ternyata bukan ide yang sangat bagus, karena sangat mempersulit desain bahasanya, dan juga menimbulkan berbagai masalah, misalnya "Masalah Intan" yang terkenal. (Lihat "Apa masalah sebenarnya dengan multiple inheritance?" Jawaban oleh J Francis )
Jadi, jika seseorang ingin membangun kelas "pemanggang roti terbang", mereka akan mewarisi dari kelas "pemanggang roti" yang sudah ada dan juga dari kelas "pemanggang roti" yang sudah ada. Jenis masalah yang kemungkinan besar akan mereka hadapi adalah bahwa catu daya dari kelas pemanggang roti kemungkinan besar adalah stopkontak dinding, sedangkan catu daya dari kelas mesin terbang kemungkinan besar adalah makanan merpati, dan kelas baru yang dihasilkan akan entah bagaimana memiliki keduanya, atau tidak jelas mana yang akan dimiliki. (Masalah Berlian.)
Pencipta bahasa seperti C # dan Java memutuskan untuk tidak mengizinkan pewarisan ganda yang sebenarnya, untuk menjaga bahasanya tetap sederhana dan untuk menghindari jebakan seperti Masalah Berlian. Namun, beberapa bentuk pewarisan ganda masih diperlukan, (atau setidaknya sangat diinginkan,) jadi dalam bahasa ini mereka memperkenalkan antarmuka sebagai sarana untuk mendukung bentuk yang lebih kecil dari pewarisan ganda sambil menghindari masalah dan kompleksitas pewarisan ganda yang sebenarnya.
Dalam bentuk multiple inheritance yang lebih kecil ini, Anda tidak diperbolehkan memiliki kelas yang mewarisi dari lebih dari satu kelas dasar, tetapi setidaknya Anda dapat mewarisi dari satu atau lebih antarmuka. Jadi, jika Anda ingin membuat pemanggang roti terbang, Anda tidak dapat mewarisi kelas pemanggang roti yang ada dan kelas terbang yang sudah ada, tetapi yang dapat Anda lakukan adalah mewarisi dari kelas pemanggang roti yang sudah ada dan juga menampilkan antarmuka terbang yang Anda implementasikan sendiri, mungkin menggunakan cara apa pun yang telah Anda warisi dari pemanggang roti.
Jadi, kecuali jika Anda merasa perlu untuk membuat kelas yang menggabungkan dua set fungsionalitas yang berbeda dan tidak terkait, Anda tidak akan memerlukan bentuk multiple inheritance apa pun, jadi Anda tidak perlu mendeklarasikan, atau mengimplementasikan, antarmuka apa pun.
sumber
Antarmuka memungkinkan perancang kelas untuk membuat metode yang tersedia menjadi sangat jelas bagi pengguna akhir. Mereka juga merupakan bagian integral dari polimorfisme.
sumber
Saya tidak akan memposting definisi antarmuka terhadap kelas abstrak karena saya pikir Anda tahu betul teorinya dan saya berasumsi Anda tahu prinsip SOLID jadi mari kita praktis.
Seperti yang Anda ketahui, antarmuka tidak dapat memiliki kode apa pun sehingga perbedaannya cukup sederhana untuk dipahami.
jika Anda perlu menginisialisasi properti kelas Anda dengan menyediakan konstruktor atau Anda ingin memberikan bagian dari implementasi, kelas abstrak akan sesuai dengan antarmuka yang tidak mengizinkan Anda melakukan itu.
Jadi secara umum Anda harus lebih memilih kelas abstrak daripada antarmuka ketika Anda perlu menyediakan konstruktor atau kode apa pun ke klien yang akan mewarisi / memperluas kelas Anda.
sumber
Kelas abstrak dikelompokkan untuk entitas terkait dimana Antarmuka dapat digunakan untuk entitas yang tidak terkait.
Misalnya jika saya memiliki dua entitas mengatakan Hewan dan Manusia maka saya akan pergi ke Antarmuka di mana seolah-olah saya harus menjelaskan secara rinci tentang Harimau, Singa dan ingin berhubungan dengan Hewan maka akan memilih kelas Abstrak Hewan ..
akan terlihat seperti di bawah ini
sumber