Apakah ada perbedaan antara antarmuka dan kelas abstrak yang hanya memiliki metode abstrak?

9

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?

yfklon
sumber
bahasa apa?
kevin cline
sejauh yang saya tahu, pertanyaan Anda dijawab dua kali : di sini dan di sini . Dan kedua jawaban ini adalah agnostik bahasa, tidak ada yang spesifik untuk C # sana
nyamuk
3
@blank Saya tidak setuju dengan status Duplikat yang diterapkan pada pertanyaan Anda, jadi saya buka kembali. Selanjutnya saya mengedit pertanyaan Anda untuk lebih memperjelas apa yang saya yakin Anda tanyakan.
maple_shaft

Jawaban:

22

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.

pdr
sumber
4
+1, meski kucing jauh lebih menyebalkan daripada ular atau kadal.
Matthew Flynn
Secara teknis: Metode abstrak dapat dibuat dilindungi. Metode antarmuka tidak bisa.
Jacques Koorts
19

Dalam sebagian besar bahasa OOP, kelas implementasi hanya dapat berasal dari satu kelas abstrak, tetapi mengimplementasikan beberapa antarmuka.

herzmeister
sumber
3
paling? mana yang kamu hitung? Sebagian besar bahasa OOP yang saya tahu tidak memiliki antarmuka atau kelas abstrak. C ++ hanya memiliki kelas abstrak.
kevin cline
10
@kevincline: mungkin C #, Java, dan VB.NET.
tammers
1
@ kevincline, saya pikir hanya ada kekurangan "memiliki keduanya". IIRC, di Ada, motivasi untuk antarmuka adalah bahwa, desainer tidak menginginkan fitur pewarisan berganda yang umum tetapi kasus khusus antarmuka dianggap terlalu penting untuk tidak disediakan.
Pemrogram
@tdammers: LOL. Itu hanya lelucon, bukan?
kevin cline
3

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 Caradalah Vehicledan Dogadalah Animal. Dengan antarmuka, objek itulah yang penting. Jadi keduanya Cardan Dogbisa Move()dan konsumen tahu itu karena mereka menerapkan Movable, tetapi Mobil jelas bukan Dog, atau Animal. 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.

Ivan Pintar
sumber
Antarmuka adalah tipe juga, sehingga Anda bisa memiliki IAnimal yang keduanya Dogdan Cat sedang .
Amy Blankenship
Anda bisa, tetapi menurut saya, antarmuka adalah tentang perilaku yang terpapar ke dunia luar, dan tidak begitu banyak tentang apa objeknya. Warisan menyiratkan bahwa sesuatu adalah jenis sesuatu yang lain (Kucing adalah Hewan). Antarmuka hanya mengatakan apa yang bisa dilakukan objek itu. Itu sebabnya saya ingin mengatakan bahwa sesuatu "mengimplementasikan" daripada "mewarisi dari" sebuah antarmuka, yang akan dikatakan oleh sebagian besar orang .Net yang pernah bekerja sama dengan saya (saya kira karena sintaksnya sama untuk pewarisan dan implementasi).
Ivan Pintar
2

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.

Thomas
sumber
1
Metode virtual (override-mampu) yang dilindungi dapat berguna untuk kelas yang merupakan bagian dari kerangka kerja atau sesuatu seperti itu. Dengan begitu mereka memastikan bahwa kode kustom di kelas yang mewarisi abstrak menyediakan fungsionalitas itu. Meskipun ini juga dapat dicapai dengan mewarisi antarmuka pada kelas dasar tetapi tidak benar-benar menerapkan metodenya
Ivan Pintar
Ya, saya sedang memikirkan sesuatu seperti itu, tetapi tidak memiliki pengalaman dengan itu, jadi tidak bisa menilai. Terima kasih atas masukannya.
Thomas
Hanya sebuah catatan. Dalam beberapa bahasa, metode virtual pribadi dapat ditimpa dalam kelas turunan.
Johan Boulé
2

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.

kevin cline
sumber
2

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

tgkprog
sumber
1
Bukankah metode abstrak didefinisikan tanpa implementasi apa pun, dan membiarkan implementasinya ke kelas-kelas pewarisan?
Ivan Pintar
ya Anda benar maka saya kira itu hanya variabel, konstruktor dan metode statis & pribadi jika Anda menghitungnya
tgkprog
@Pinetree, dalam praktiknya sebagian besar waktu Anda akan menginginkan setidaknya sedikit "nyata" kode di Kelas Abstrak Anda (setidaknya dalam bahasa yang saya gunakan, yang tidak memiliki konstruksi khusus untuk Kelas Abstrak).
Amy Blankenship
@AmyBlankenship ya, sebagian besar waktu kelas abstrak memang memiliki kode "nyata" (itulah tujuan mereka ada). Tapi saya mengacu pada metode abstrak, dalam konteks kelas abstrak murni yang berfungsi sebagai antarmuka dalam bahasa seperti C ++, yang tidak memiliki antarmuka.
Ivan Pintar