Katakanlah kita memiliki kelas abstrak dan biarkan kelas ini hanya memiliki metode abstrak. Apakah kelas abstrak ini berbeda dari antarmuka yang hanya memiliki metode yang sama?
Apa yang ingin saya ketahui adalah apakah ada perbedaan baik secara filosofis, obyektif dan dalam implementasi bahasa pemrograman yang mendasari antara Kelas Abstrak dengan hanya anggota abstrak dan Antarmuka yang setara?
Jawaban:
Secara teknis, perbedaannya tidak terlalu signifikan tetapi, secara konseptual, mereka adalah hal yang sepenuhnya berbeda dan yang mengarah ke perbedaan teknis yang disebutkan orang lain.
Superclass abstrak persis seperti apa kedengarannya, itu adalah tipe umum yang dimiliki oleh banyak jenis lainnya, seperti Kucing dan Anjing adalah Hewan.
Antarmuka juga persis seperti apa itu, itu adalah antarmuka di mana kelas lain dapat berkomunikasi dengan objek. Jika Anda ingin membuat Cat Walk, Anda boleh, karena Cat mengimplementasikan antarmuka CanWalk. Sama untuk Kadal, meskipun mereka berjalan sangat berbeda. Ular, di sisi lain, tidak menerapkan CanWalk, jadi Anda tidak bisa mengatakannya kepada Walk. Sementara itu, Lizard dan Snake (atau mungkin subclass yang lebih eksplisit - saya bukan ahli) mungkin akan melepaskan kulit mereka, dan dengan demikian mengimplementasikan CanShed, sementara Kucing tidak bisa melakukan itu.
Tetapi mereka semua tetap Hewan dan memiliki beberapa sifat umum, seperti apakah mereka hidup atau mati.
Inilah sebabnya mengapa semua metode pada antarmuka harus diimplementasikan sebagai publik (atau secara eksplisit, dalam C #). Karena apa gunanya antarmuka yang tersembunyi dari antarmuka kelas dengan objek? Itu juga mengapa Anda dapat memiliki banyak antarmuka ke objek, bahkan ketika suatu bahasa tidak mendukung banyak pewarisan.
Untuk kembali ke pertanyaan Anda, ketika Anda melihatnya seperti ini, jarang ada alasan untuk memiliki superclass yang sepenuhnya abstrak.
sumber
Dalam sebagian besar bahasa OOP, kelas implementasi hanya dapat berasal dari satu kelas abstrak, tetapi mengimplementasikan beberapa antarmuka.
sumber
Dalam bahasa seperti C ++ yang memungkinkan pewarisan berganda, dan tidak memiliki antarmuka, kelas abstrak di mana semua metode abstrak dapat berfungsi sebagai antarmuka. Saya belum pernah bekerja dengan C ++ sebanyak itu, tapi saya kira multiple inheritance dapat menyebabkan masalah ketika ada metode dengan nama yang sama di kelas dasar.
Dalam bahasa seperti PHP dan C #, antarmuka menyediakan cara untuk mencapai polimorfisme yang sama, meskipun saya tidak suka menyebutnya "warisan" karena ada perbedaan konseptual antara mewarisi kelas abstrak dan mengimplementasikan antarmuka. Antarmuka menghilangkan masalah konflik, karena mereka sendiri tidak memberikan implementasi.
Antarmuka berfungsi sebagai kontrak ke dunia luar, sementara kelas abstrak dapat memberikan implementasi, meskipun jika digunakan untuk "memalsukan" antarmuka, kemungkinan besar tidak akan.
Perbedaan konseptual utama adalah bahwa ketika suatu kelas mewarisi kelas lain (abstrak atau tidak), ada hubungan "adalah", jadi a
Car
adalahVehicle
danDog
adalahAnimal
. Dengan antarmuka, objek itulah yang penting. Jadi keduanyaCar
danDog
bisaMove()
dan konsumen tahu itu karena mereka menerapkanMovable
, tetapi Mobil jelas bukanDog
, atauAnimal
. Dan implementasi langkah akan berbeda (roda vs kaki) tetapi kode konsumsi tidak dan tidak boleh peduli. Antarmuka adalah semua tentang kode yang dikonsumsi, bukan implementasi.Poin utama adalah jika Anda memiliki antarmuka dalam bahasa pilihan Anda, gunakan mereka untuk hal-hal yang ada di sana. Jika tidak (seperti di C ++), Anda bisa memalsukannya dengan menggunakan kelas abstrak murni.
sumber
Dog
danCat
sedang .Kelas abstrak dapat menampilkan metode yang dilindungi abstrak (dalam bahasa saya bekerja dengan), dalam metode antarmuka biasanya selalu publik. Apakah perbedaan ini memungkinkan eksploitasi yang bermanfaat, saya tidak tahu.
Sunting Saya pertama kali berpikir bahwa metode abstrak pribadi tidak ada gunanya, tetapi sekarang saya ingat bahwa itu dapat digunakan untuk memastikan bahwa metode itu tidak pernah dipanggil. Dengan cara ini Anda dapat mencegah bahwa konstruktor salinan suatu objek dipanggil.
sumber
Ya, mereka berbeda. Kalau tidak, desainer bahasa tidak akan menyediakan keduanya. Saya tahu dua bahasa yang memisahkan kelas dan antarmuka: Java dan C #, klon mutan Java. Para perancang menciptakan antarmuka untuk menghindari mendukung pewarisan banyak kelas. Sebagian besar bahasa lain mendukung pewarisan banyak kelas dan akibatnya tidak memisahkan kelas dan antarmuka.
sumber
Saya pikir perbedaan utamanya adalah: Dalam kelas abstrak - bahkan jika semua metode semuanya abstrak mereka masih dapat memberikan data anggota (variabel instan) dan beberapa kode ke kelas yang mengimplementasikannya (dalam bentuk metode pribadi atau konstruktor), blok statis; melakukan bagian dari pekerjaan untuk sub-kelas dan membantu mereka dalam implementasi.
Satu efek samping positif: kode ada di satu tempat sehingga satu tempat membuat koreksi. sub kelas hanya dapat memanggil metode kelas super dan kemudian melakukan sesuatu yang lain atau tidak sama sekali jika tindakan kelas super cukup untuk kasus mereka. Super class menginginkan setiap sub kelas untuk membuat keputusan ini sehingga telah menandai semua implementasinya sebagai abstrak (beberapa juga bisa kosong)
Tidak relevan dengan pertanyaan: tetapi memiliki antarmuka berarti satu kelas dapat mengimplementasikan dua kontrak yang berbeda. Jadi itu adalah keuntungan dari antarmuka kelas super abstrak
sumber