Antarmuka memungkinkan Anda untuk membuat kode yang mendefinisikan metode kelas yang mengimplementasikannya. Namun Anda tidak dapat menambahkan kode apa pun ke metode tersebut.
Kelas abstrak memungkinkan Anda untuk melakukan hal yang sama, bersama dengan menambahkan kode ke metode.
Sekarang jika Anda dapat mencapai tujuan yang sama dengan kelas abstrak, mengapa kita bahkan memerlukan konsep antarmuka?
Saya telah diberitahu bahwa itu ada hubungannya dengan teori OO dari C ++ ke Java, yang merupakan dasar dari hal-hal OO PHP. Apakah konsep ini berguna di Java tetapi tidak di PHP? Apakah ini hanya cara agar tidak ada placeholder yang berserakan di kelas abstrak? Apakah saya melewatkan sesuatu?
Jawaban:
Seluruh titik antarmuka adalah untuk memberi Anda fleksibilitas agar kelas Anda dipaksa untuk mengimplementasikan banyak antarmuka, tetapi masih tidak memungkinkan pewarisan berganda. Masalah dengan mewarisi dari beberapa kelas banyak dan beragam dan halaman wikipedia merangkumnya dengan cukup baik.
Antarmuka adalah kompromi. Sebagian besar masalah dengan pewarisan berganda tidak berlaku untuk kelas dasar abstrak, jadi sebagian besar bahasa modern saat ini menonaktifkan banyak warisan namun memanggil antarmuka kelas dasar abstrak dan memungkinkan kelas untuk "mengimplementasikan" sebanyak yang mereka inginkan.
sumber
Konsep ini berguna di sekitar dalam pemrograman berorientasi objek. Bagi saya, saya menganggap antarmuka sebagai kontrak. Selama kelas saya dan kelas Anda menyetujui kontrak tanda tangan metode ini, kami dapat "antarmuka". Adapun kelas abstrak yang saya lihat sebagai kelas dasar yang mematikan beberapa metode dan saya perlu mengisi rinciannya.
sumber
Mengapa Anda membutuhkan antarmuka, jika sudah ada kelas abstrak? Untuk mencegah multiple inheritance (dapat menyebabkan banyak masalah yang diketahui).
Salah satu masalah tersebut:
Sumber: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem
Mengapa / Kapan menggunakan antarmuka? Contoh ... Semua mobil di dunia memiliki antarmuka (metode) yang sama ...
AccelerationPedalIsOnTheRight()
,BrakePedalISOnTheLeft()
. Bayangkan setiap merek mobil memiliki "metode" yang berbeda dari merek lain. BMW akan memiliki rem di sisi kanan, dan Honda akan memiliki rem di sisi kiri kemudi. Orang-orang harus belajar bagaimana "metode" ini bekerja setiap kali mereka akan membeli merek mobil yang berbeda. Karena itu, sebaiknya memiliki antarmuka yang sama di beberapa "tempat".Apa yang dilakukan antarmuka untuk Anda (mengapa seseorang bahkan menggunakannya)? Antarmuka mencegah Anda membuat "kesalahan" (meyakinkan Anda bahwa semua kelas yang mengimplementasikan antarmuka tertentu, semua akan memiliki metode yang ada di antarmuka).
Dengan cara ini,
Create()
metode akan selalu digunakan dengan cara yang sama. Tidak masalah jika kita menggunakanMySqlPerson
kelas atauMongoPerson
kelas. Cara kami menggunakan metode tetap sama (antarmuka tetap sama).Sebagai contoh, ini akan digunakan seperti ini (di mana-mana dalam kode kami):
Dengan cara ini, sesuatu seperti ini tidak dapat terjadi:
Jauh lebih mudah untuk mengingat satu antarmuka dan menggunakan yang sama di mana-mana, daripada beberapa yang berbeda.
Dengan cara ini, bagian dalam
Create()
metode dapat berbeda untuk kelas yang berbeda, tanpa memengaruhi kode "luar", yang memanggil metode ini. Yang perlu diketahui kode luar adalah bahwa metode tersebutCreate()
memiliki 1 parameter ($personObject
), karena itulah cara kode luar akan menggunakan / memanggil metode tersebut. Kode luar tidak peduli apa yang terjadi di dalam metode; hanya perlu tahu cara menggunakannya / menyebutnya.Anda dapat melakukan ini tanpa antarmuka juga, tetapi jika Anda menggunakan antarmuka, itu "lebih aman" (karena mencegah Anda membuat kesalahan). Antarmuka meyakinkan Anda bahwa metode ini
Create()
akan memiliki tanda tangan yang sama (tipe yang sama dan jumlah parameter yang sama) di semua kelas yang mengimplementasikan antarmuka. Dengan cara ini Anda dapat yakin bahwa kelas APAPUN yang mengimplementasikanIPersonService
antarmuka, akan memiliki metodeCreate()
(dalam contoh ini) dan hanya perlu 1 parameter ($personObject
) untuk dipanggil / digunakan.Kelas yang mengimplementasikan antarmuka harus mengimplementasikan semua metode, yang antarmuka / miliki.
Saya harap saya tidak mengulangi terlalu banyak.
sumber
Perbedaan antara menggunakan antarmuka dan kelas abstrak lebih berkaitan dengan organisasi kode bagi saya, daripada penegakan oleh bahasa itu sendiri. Saya sering menggunakannya ketika menyiapkan kode untuk bekerja dengan pengembang lain sehingga mereka tetap dalam pola desain yang dimaksud. Antarmuka adalah semacam "desain berdasarkan kontrak" di mana kode Anda setuju untuk merespons serangkaian panggilan API yang ditentukan yang mungkin berasal dari kode yang tidak Anda miliki.
Meskipun warisan dari kelas abstrak adalah relasi "adalah", itu tidak selalu seperti yang Anda inginkan, dan mengimplementasikan antarmuka lebih merupakan relasi "bertindak seperti". Perbedaan ini bisa sangat signifikan dalam konteks tertentu.
Sebagai contoh, katakanlah Anda memiliki Akun kelas abstrak dari mana banyak kelas lain diperluas (jenis akun dan sebagainya). Ini memiliki seperangkat metode tertentu yang hanya berlaku untuk grup tipe itu. Namun, beberapa subkelas akun ini menerapkan Versionable, atau Listable, atau Editable sehingga mereka dapat dilemparkan ke dalam pengontrol yang berharap untuk menggunakan API tersebut. Kontroler tidak peduli jenis objek apa itu
Sebaliknya, saya juga dapat membuat objek yang tidak diperluas dari Akun, katakanlah kelas abstrak Pengguna, dan masih menerapkan Listable dan Editable, tetapi tidak Versionable, yang tidak masuk akal di sini.
Dengan cara ini, saya mengatakan bahwa subkelas FooUser BUKAN akun, tetapi TIDAK bertindak seperti objek yang Dapat Diedit. Demikian juga BarAccount meluas dari Akun, tetapi bukan subkelas Pengguna, tetapi mengimplementasikan Editable, Listable dan juga Versionable.
Menambahkan semua API untuk Editable, Listable dan Versionable ke dalam kelas abstrak itu sendiri tidak hanya akan berantakan dan jelek, tetapi juga akan menduplikasi antarmuka umum dalam Akun dan Pengguna, atau memaksa objek Pengguna saya untuk mengimplementasikan Versionable, mungkin hanya untuk melempar pengecualian.
sumber
Antarmuka pada dasarnya adalah cetak biru untuk apa yang dapat Anda buat. Mereka menentukan metode apa yang harus dimiliki suatu kelas , tetapi Anda dapat membuat metode tambahan di luar batasan itu.
Saya tidak yakin apa yang Anda maksud dengan tidak dapat menambahkan kode ke metode - karena Anda bisa. Apakah Anda menerapkan antarmuka ke kelas abstrak atau kelas yang memperluasnya?
Metode dalam antarmuka yang diterapkan pada kelas abstrak perlu diimplementasikan di kelas abstrak tersebut. Namun menerapkan antarmuka itu ke kelas perluasan dan metode hanya perlu diimplementasikan di kelas perluasan. Saya bisa salah di sini - saya tidak menggunakan antarmuka sesering mungkin / seharusnya.
Saya selalu menganggap antarmuka sebagai pola untuk pengembang eksternal atau aturan tambahan untuk memastikan semuanya benar.
sumber
Anda akan menggunakan antarmuka dalam PHP:
$object instanceof MyInterface
Car
objek ca sekarangstart()
,stop()
(EngineInterface) ataugoRight()
,goLeft()
(Steering interface)dan hal-hal lain yang tidak dapat saya pikirkan saat ini
Nomor 4 itu mungkin kasus penggunaan yang paling jelas bahwa Anda tidak dapat mengatasi dengan kelas abstrak.
Dari Thinking in Java:
sumber
Antarmuka ada bukan sebagai dasar di mana kelas dapat diperluas tetapi sebagai peta fungsi yang diperlukan.
Berikut ini adalah contoh penggunaan antarmuka di mana kelas abstrak tidak cocok:
Katakanlah saya memiliki aplikasi kalender yang memungkinkan pengguna untuk mengimpor data kalender dari sumber eksternal. Saya akan menulis kelas untuk menangani mengimpor setiap jenis sumber data (ical, rss, atom, json) Masing-masing kelas akan menerapkan antarmuka umum yang akan memastikan mereka semua memiliki metode umum yang dibutuhkan aplikasi saya untuk mendapatkan data.
Kemudian ketika pengguna menambahkan feed baru saya dapat mengidentifikasi jenis feed itu dan menggunakan kelas yang dikembangkan untuk jenis itu untuk mengimpor data. Setiap kelas yang ditulis untuk mengimpor data untuk umpan tertentu akan memiliki kode yang sama sekali berbeda, mungkin ada sangat sedikit kesamaan antara kelas di luar kenyataan bahwa mereka diharuskan untuk mengimplementasikan antarmuka yang memungkinkan aplikasi saya untuk mengkonsumsinya. Jika saya menggunakan kelas abstrak, saya bisa dengan mudah mengabaikan fakta bahwa saya belum menimpa metode getEvents () yang kemudian akan merusak aplikasi saya dalam contoh ini sedangkan menggunakan antarmuka tidak akan membiarkan aplikasi saya berjalan jika ada salah satu metode didefinisikan dalam antarmuka tidak ada di kelas yang mengimplementasikannya. Aplikasi saya tidak perlu peduli kelas apa yang digunakannya untuk mendapatkan data dari umpan,
Untuk mengambil langkah ini lebih jauh, antarmuka terbukti sangat berguna ketika saya kembali ke aplikasi kalender saya dengan maksud menambahkan jenis umpan lain. Menggunakan antarmuka ImportableFeed berarti saya dapat terus menambahkan lebih banyak kelas yang mengimpor berbagai jenis umpan hanya dengan menambahkan kelas baru yang mengimplementasikan antarmuka ini. Ini memungkinkan saya untuk menambahkan banyak fungsionalitas tanpa harus menambahkan massal yang tidak perlu ke aplikasi inti saya karena aplikasi inti saya hanya bergantung pada keberadaan metode publik yang tersedia yang diperlukan oleh antarmuka, selama kelas impor umpan baru saya mengimplementasikan antarmuka ImportableFeed maka saya tahu saya bisa menjatuhkannya di tempat dan terus bergerak.
Ini hanyalah permulaan yang sangat sederhana. Saya kemudian dapat membuat antarmuka lain yang semua kelas kalender saya dapat diminta untuk mengimplementasikan yang menawarkan fungsionalitas lebih spesifik untuk jenis umpan yang ditangani kelas. Contoh bagus lainnya adalah metode untuk memverifikasi jenis umpan, dll.
Ini melampaui pertanyaan tetapi karena saya menggunakan contoh di atas: Antarmuka datang dengan masalah mereka sendiri jika digunakan dengan cara ini. Saya menemukan diri saya perlu untuk memastikan output yang dikembalikan dari metode yang diterapkan untuk mencocokkan antarmuka dan untuk mencapai ini saya menggunakan IDE yang membaca blok PHPDoc dan menambahkan tipe kembali sebagai petunjuk jenis dalam blok PHPDoc antarmuka yang kemudian akan menerjemahkan ke kelas konkret yang mengimplementasikannya. Kelas-kelas saya yang mengkonsumsi output data dari kelas-kelas yang mengimplementasikan antarmuka ini maka paling tidak tahu itu mengharapkan array yang dikembalikan dalam contoh ini:
Tidak banyak ruang untuk membandingkan kelas dan antarmuka abstrak. Antarmuka hanyalah peta yang ketika diimplementasikan membutuhkan kelas untuk memiliki satu set antarmuka publik.
sumber
Antarmuka tidak hanya untuk memastikan pengembang menerapkan metode tertentu. Idenya adalah karena kelas-kelas ini dijamin memiliki metode tertentu, Anda dapat menggunakan metode ini bahkan jika Anda tidak tahu tipe sebenarnya dari kelas tersebut. Contoh:
Dalam banyak kasus, tidak masuk akal untuk menyediakan kelas dasar, abstrak atau tidak, karena implementasinya sangat bervariasi dan tidak berbagi kesamaan apa pun selain beberapa metode.
Bahasa yang diketik secara dinamis memiliki gagasan "bebek-mengetik" di mana Anda tidak perlu antarmuka; Anda bebas untuk berasumsi bahwa objek memiliki metode yang Anda panggil. Ini mengatasi masalah dalam bahasa yang diketik secara statis di mana objek Anda memiliki beberapa metode (dalam contoh saya, baca ()), tetapi tidak mengimplementasikan antarmuka.
sumber
Menurut pendapat saya, antarmuka harus lebih disukai daripada kelas abstrak non-fungsional. Saya tidak akan terkejut jika bahkan akan ada pertunjukan di sana, karena hanya ada satu objek yang dipakai, alih-alih parsing dua, menggabungkan mereka (meskipun, saya tidak yakin, saya tidak akrab dengan cara kerja bagian dalam. dari OOP PHP).
Memang benar bahwa antarmuka kurang bermanfaat / bermakna dibandingkan dengan, katakanlah, Java. Di sisi lain, PHP6 akan memperkenalkan bahkan lebih banyak tiping tipe, termasuk tiping tip untuk nilai balik. Ini harus menambah nilai pada antarmuka PHP.
tl; dr: interface mendefinisikan daftar metode yang perlu diikuti (pikirkan API), sementara kelas abstrak memberikan beberapa fungsi dasar / umum, yang disempurnakan oleh subkelas untuk kebutuhan spesifik.
sumber
Dalam PHP Anda dapat menerapkan beberapa antarmuka dengan memisahkannya dengan koma (saya pikir, saya tidak menemukan solusi yang bersih).
Adapun beberapa kelas abstrak Anda bisa memiliki beberapa abstrak saling memperluas satu sama lain (sekali lagi, saya tidak sepenuhnya yakin tentang itu tetapi saya pikir saya pernah melihatnya di suatu tempat sebelumnya). Satu-satunya hal yang Anda tidak dapat memperpanjang adalah kelas final.
sumber
Antarmuka tidak akan memberikan kode Anda peningkatan kinerja apa pun atau apa pun seperti itu, tetapi mereka dapat berupaya keras untuk membuatnya dapat dipertahankan. Memang benar bahwa kelas abstrak (atau bahkan kelas non-abstrak) dapat digunakan untuk membuat antarmuka ke kode Anda, tetapi antarmuka yang tepat (yang Anda tentukan dengan kata kunci dan yang hanya berisi tanda tangan metode) jelas lebih mudah untuk memilah dan membaca.
Yang sedang berkata, saya cenderung menggunakan kebijaksanaan ketika memutuskan apakah akan menggunakan antarmuka di kelas atau tidak. Kadang-kadang saya ingin implementasi metode default, atau variabel yang akan umum untuk semua subclass.
Tentu saja, poin tentang implementasi multi-antarmuka juga bagus. Jika Anda memiliki kelas yang mengimplementasikan beberapa antarmuka, Anda bisa menggunakan objek kelas itu sebagai tipe berbeda di aplikasi yang sama.
Namun, fakta bahwa pertanyaan Anda adalah tentang PHP, membuat segalanya sedikit lebih menarik. Mengetik ke antarmuka masih tidak terlalu perlu di PHP, di mana Anda bisa memberi makan apa saja dengan metode apa pun, apa pun tipenya. Anda dapat mengetik parameter metode secara statis, tetapi beberapa di antaranya rusak (String, saya percaya, menyebabkan beberapa masalah). Pasangkan ini dengan fakta bahwa Anda tidak dapat mengetik sebagian besar referensi lain, dan tidak ada banyak nilai dalam mencoba memaksa pengetikan statis di PHP ( pada titik ini ). Dan karena itu, nilai antarmuka dalam PHP , pada titik inijauh lebih sedikit daripada di bahasa yang diketik lebih kuat. Mereka memiliki manfaat keterbacaan, tetapi sedikit lainnya. Implementasi berganda bahkan tidak bermanfaat, karena Anda masih harus mendeklarasikan metode dan memberi mereka tubuh dalam implementor.
sumber
Di bawah ini adalah poin untuk Antarmuka PHP
Kode contoh:
sumber
Kami melihat bahwa kelas dan antarmuka abstrak serupa karena menyediakan metode abstrak yang harus diterapkan di kelas anak. Namun, mereka masih memiliki perbedaan berikut:
Semoga ini bisa membantu siapa pun untuk mengerti!
sumber
Antarmuka seperti gen Anda.
Kelas abstrak seperti orang tua Anda yang sebenarnya.
Tujuannya adalah turun temurun, tetapi dalam kasus kelas abstrak vs antarmuka, apa yang diwariskan lebih spesifik.
sumber
Saya tidak tahu tentang bahasa lain, apa konsep antarmuka di sana. Tetapi untuk PHP, saya akan mencoba yang terbaik untuk menjelaskannya. Sabar saja, dan Tolong beri komentar jika ini membantu.
Peraturan
Sekarang mari kita ambil contoh. Misalkan kita memiliki dua mainan: satu adalah Anjing, dan satu lagi adalah Kucing.
Seperti kita ketahui gonggongan anjing, dan kucing mew. Keduanya memiliki metode bicara yang sama, tetapi dengan fungsi atau implementasi yang berbeda. Misalkan kita memberi pengguna remote control yang memiliki tombol bicara.
Ini kasus yang baik untuk menggunakan antarmuka, bukan kelas abstrak karena implementasinya berbeda. Mengapa? Ingat
Jika Anda perlu mendukung kelas anak dengan menambahkan beberapa metode non-abstrak, Anda harus menggunakan kelas abstrak. Jika tidak, antarmuka akan menjadi pilihan Anda.
sumber