( Untuk keperluan pertanyaan ini, ketika saya mengatakan 'antarmuka' yang saya maksud adalah konstruk bahasainterface
, dan bukan 'antarmuka' dalam arti kata lain, yaitu metode publik yang ditawarkan kelas kepada dunia luar untuk berkomunikasi dengan dan memanipulasi itu. )
Kopling longgar dapat dicapai dengan memiliki objek bergantung pada abstraksi bukan jenis beton.
Hal ini memungkinkan untuk lepas kopling karena dua alasan utama: 1- abstraksi lebih kecil kemungkinannya untuk berubah daripada jenis beton, yang berarti kode dependen lebih kecil kemungkinannya untuk dipatahkan. 2- jenis beton yang berbeda dapat digunakan saat runtime, karena mereka semua sesuai dengan abstraksi. Jenis beton baru juga dapat ditambahkan nanti tanpa perlu mengubah kode dependen yang ada.
Sebagai contoh, pertimbangkan kelas Car
dan dua subclass Volvo
dan Mazda
.
Jika kode Anda bergantung pada a Car
, ia bisa menggunakan a Volvo
atau a Mazda
selama runtime. Juga nanti subkelas tambahan dapat ditambahkan tanpa perlu mengubah kode dependen.
Juga, Car
- yang merupakan abstraksi - kecil kemungkinannya berubah daripada Volvo
atau Mazda
. Mobil pada umumnya sama untuk beberapa waktu, tetapi Volvo dan Mazda jauh lebih mungkin untuk berubah. Yaitu abstraksi lebih stabil daripada jenis beton.
Semua ini untuk menunjukkan bahwa saya memahami apa itu kopling longgar dan bagaimana hal itu dicapai dengan bergantung pada abstraksi dan bukan pada konkretsi. (Jika saya menulis sesuatu yang tidak akurat, tolong katakan demikian).
Yang tidak saya mengerti adalah ini:
Abstraksi dapat berupa superclasses atau antarmuka.
Jika demikian, mengapa antarmuka secara khusus dipuji karena kemampuan mereka untuk memungkinkan kopling longgar? Saya tidak melihat perbedaannya dengan menggunakan superclass.
Satu-satunya perbedaan yang saya lihat adalah: 1- Antarmuka tidak dibatasi oleh pewarisan tunggal, tapi itu tidak ada hubungannya dengan topik kopling longgar. 2- Antarmuka lebih 'abstrak' karena mereka tidak memiliki logika implementasi sama sekali. Tapi tetap saja, saya tidak mengerti mengapa itu membuat perbedaan besar.
Tolong jelaskan kepada saya mengapa antarmuka dikatakan hebat dalam memungkinkan kopling longgar, sedangkan superclasses sederhana tidak.
sumber
interfaces are essential for single-inheritance languages like Java and C# because that's the only way in which you can aggregate different behaviors into a single class
(yang membuat saya perbandingan dengan C ++, di mana antarmuka hanya kelas dengan fungsi virtual murni).Jawaban:
Terminologi: Saya akan merujuk pada konstruksi bahasa
interface
sebagai antarmuka , dan antarmuka jenis atau objek sebagai permukaan (karena tidak ada istilah yang lebih baik).Benar.
Tidak sepenuhnya benar. Bahasa saat ini umumnya tidak mengantisipasi bahwa abstraksi akan berubah (walaupun ada beberapa pola desain untuk mengatasinya). Memisahkan spesifik dari hal - hal umum adalah abstraksi. Ini biasanya dilakukan oleh beberapa lapisan abstraksi . Lapisan ini dapat diubah ke beberapa spesifik lain tanpa melanggar kode yang dibangun di atas abstraksi ini - kopling longgar tercapai. Contoh Non-OOP: Suatu
sort
rutin dapat diubah dari Quicksort di versi 1 ke Tim Sort di versi 2. Kode yang hanya tergantung pada hasil yang diurutkan (yaitu dibangun berdasarkansort
abstraksi) karena itu dipisahkan dari implementasi penyortiran yang sebenarnya.Apa yang saya sebut permukaan di atas adalah bagian umum dari abstraksi. Sekarang terjadi di OOP bahwa satu objek terkadang harus mendukung banyak abstraksi. Contoh yang tidak terlalu optimal: Java
java.util.LinkedList
mendukung keduaList
antarmuka yaitu tentang abstraksi "teratur, dapat diindeks koleksi", dan mendukungQueue
antarmuka yang (secara kasar) adalah tentang abstraksi "FIFO".Bagaimana suatu objek dapat mendukung banyak abstraksi?
C ++ tidak memiliki antarmuka, tetapi memiliki banyak pewarisan, metode virtual, dan kelas abstrak. Abstraksi kemudian dapat didefinisikan sebagai kelas abstrak (yaitu kelas yang tidak dapat segera dipakai) yang menyatakan, tetapi tidak mendefinisikan metode virtual. Kelas yang mengimplementasikan spesifik abstraksi kemudian dapat mewarisi dari kelas abstrak dan mengimplementasikan metode virtual yang diperlukan.
Masalahnya di sini adalah bahwa pewarisan berganda dapat menyebabkan masalah intan , di mana urutan di mana kelas dicari untuk implementasi metode (MRO: metode resolusi urutan) dapat menyebabkan "kontradiksi". Ada dua tanggapan untuk ini:
Tetapkan perintah yang waras dan tolak perintah yang tidak bisa diluruskan dengan bijaksana. The C3 MRO cukup masuk akal dan bekerja dengan baik. Itu diterbitkan tahun 1996.
Ambil rute yang mudah dan tolak beberapa warisan di seluruh.
Java mengambil opsi yang terakhir dan memilih warisan perilaku tunggal. Namun, kita masih membutuhkan kemampuan suatu objek untuk mendukung banyak abstraksi. Oleh karena itu, antarmuka harus digunakan yang tidak mendukung definisi metode, hanya deklarasi.
Hasilnya adalah bahwa MRO jelas (lihat saja setiap superclass secara berurutan), dan bahwa objek kita dapat memiliki beberapa permukaan untuk sejumlah abstraksi.
Ini ternyata agak tidak memuaskan, karena cukup sering sedikit perilaku adalah bagian dari permukaan. Pertimbangkan sebuah
Comparable
antarmuka:Ini sangat user-friendly (API yang bagus dengan banyak metode yang mudah), tetapi membosankan untuk diimplementasikan. Kami ingin antarmuka hanya menyertakan
cmp
, dan menerapkan metode lain secara otomatis dalam hal satu metode yang diperlukan. Mixin , tetapi yang lebih penting Ciri-ciri [ 1 ], [ 2 ] menyelesaikan masalah ini tanpa jatuh ke dalam perangkap pewarisan berganda.Ini dilakukan dengan mendefinisikan komposisi sifat sehingga sifat-sifat tersebut tidak benar-benar berakhir mengambil bagian dalam MRO - sebagai gantinya metode yang didefinisikan disusun ke dalam kelas pelaksana.
The
Comparable
antarmuka dapat dinyatakan dalam Scala sebagaiKetika sebuah kelas kemudian menggunakan sifat itu, metode lain ditambahkan ke definisi kelas:
Begitu
Inty(4) cmp Inty(6)
juga akan-2
danInty(4) lt Inty(6)
akan terjaditrue
.Banyak bahasa memiliki beberapa dukungan untuk sifat-sifat, dan bahasa apa pun yang memiliki "Metaobject Protocol (MOP)" dapat memiliki sifat ditambahkan ke dalamnya. Pembaruan Java 8 baru-baru ini menambahkan metode default yang mirip dengan ciri-ciri (metode dalam antarmuka dapat memiliki implementasi fallback sehingga opsional untuk menerapkan kelas untuk mengimplementasikan metode ini).
Sayangnya, sifat-sifat adalah penemuan yang cukup baru (2002), dan dengan demikian cukup langka dalam bahasa arus utama yang lebih besar.
sumber
Pertama, subtyping dan abstraksi adalah dua hal yang berbeda. Subtipe hanya berarti bahwa saya dapat mengganti nilai satu jenis dengan nilai dari jenis lain - kedua jenis tersebut tidak perlu abstrak.
Lebih penting lagi, subclass memiliki ketergantungan langsung pada detail implementasi superclass mereka. Itu jenis kopling terkuat yang ada. Faktanya, jika kelas dasar tidak dirancang dengan mempertimbangkan warisan, perubahan ke kelas dasar yang tidak mengubah perilakunya masih dapat memecahkan subclass, dan tidak ada cara untuk mengetahui apriori jika kerusakan akan terjadi. Ini dikenal sebagai masalah kelas dasar yang rapuh .
Menerapkan antarmuka tidak membuat Anda berpasangan dengan apa pun kecuali antarmuka itu sendiri, yang tidak mengandung perilaku.
sumber
you want an object named A to depend on an abstraction named B instead of a concrete implementation of that abstraction named C
Anda berasumsi bahwa kelas entah bagaimana tidak abstrak. Abstraksi adalah segala sesuatu yang menyembunyikan detail implementasi, sehingga kelas dengan bidang pribadi sama abstraknya dengan antarmuka dengan metode publik yang sama.Ada sambungan antara kelas induk dan anak, karena anak bergantung pada orangtua.
Katakanlah kita memiliki kelas A, dan kelas B mewarisi darinya. Jika kita masuk ke kelas A dan mengubah banyak hal, kelas B juga berubah.
Katakanlah kita memiliki antarmuka I, dan kelas B mengimplementasikannya. Jika kita mengubah antarmuka I, maka meskipun kelas B mungkin tidak mengimplementasikannya lagi, kelas B tidak berubah.
sumber