Antarmuka vs Kelas Abstrak (OO umum)

1413

Saya baru-baru ini memiliki dua wawancara telepon di mana saya ditanya tentang perbedaan antara Interface dan kelas Abstrak. Saya telah menjelaskan setiap aspek dari mereka yang dapat saya pikirkan, tetapi tampaknya mereka menunggu saya untuk menyebutkan sesuatu yang spesifik, dan saya tidak tahu apa itu.

Dari pengalaman saya, saya pikir yang berikut ini benar. Jika saya kehilangan poin utama, tolong beri tahu saya.

Antarmuka:

Setiap Metode tunggal yang dideklarasikan dalam Antarmuka harus diimplementasikan dalam subkelas. Hanya Peristiwa, Delegasi, Properti (C #), dan Metode yang bisa ada di Interface. Sebuah kelas dapat mengimplementasikan beberapa Antarmuka.

Kelas Abstrak:

Hanya metode abstrak yang harus diimplementasikan oleh subkelas. Kelas abstrak dapat memiliki metode normal dengan implementasi. Kelas abstrak juga dapat memiliki variabel kelas selain Peristiwa, Delegasi, Properti, dan Metode. Kelas hanya dapat mengimplementasikan satu kelas abstrak hanya karena tidak adanya Multi-inheritance di C #.

  1. Setelah semua itu, pewawancara datang dengan pertanyaan "Bagaimana jika Anda memiliki kelas abstrak dengan hanya metode abstrak? Bagaimana itu berbeda dari antarmuka?" Saya tidak tahu jawabannya tapi saya pikir itu adalah warisan seperti yang disebutkan di atas kan?

  2. Pewawancara lain bertanya kepada saya bagaimana jika Anda memiliki variabel Publik di dalam antarmuka, bagaimana hal itu berbeda dari di Kelas Abstrak? Saya bersikeras Anda tidak dapat memiliki variabel publik di dalam antarmuka. Saya tidak tahu apa yang ingin dia dengar tetapi dia juga tidak puas.

Lihat Juga :

Houman
sumber
412
Meskipun saya pikir penting untuk mengetahui perbedaan antara keduanya, ini bukan pertanyaan wawancara yang bagus, imo. Kecuali jika pekerjaan itu menulis buku tentang topik-topik OO. Anda lebih baik tidak bekerja untuk kelelawar ding itu.
Alan
107
@Lan: Saya sebenarnya suka ini sebagai pertanyaan wawancara, tapi saya tidak akan memburu seseorang dengan cara ini - saya mungkin akan memposting lebih seperti "Di mana Anda akan memilih antarmuka daripada kelas dasar abstrak, ketika mendefinisikan hirarki? ", atau yang serupa.
Reed Copsey
11
Mungkin mereka mencari jawaban yang lebih fokus pada desain ... meskipun seperti Anda, saya akan memperlakukannya sebagai pertanyaan teknis.
CurtainDog
16
Perbedaan tabel yang bagus di sini: mindprod.com/jgloss/interfacevsabstract.html
Rajat_R
30
@Ave: I insisted you can't have a public variable inside an interface.Saya pikir antarmuka dapat memiliki variabel publik. Bahkan variabel dalam antarmuka secara otomatis bersifat publik dan final.
seorang Pembelajar

Jawaban:

746

Sementara pertanyaan Anda menunjukkan itu untuk "OO umum", sepertinya benar-benar berfokus pada penggunaan .NET dari istilah ini.

Dalam. NET (mirip untuk Java):

  • antarmuka tidak dapat memiliki negara atau implementasi
  • kelas yang mengimplementasikan antarmuka harus menyediakan implementasi dari semua metode antarmuka itu
  • kelas abstrak dapat berisi status (anggota data) dan / atau implementasi (metode)
  • kelas abstrak dapat diwarisi tanpa menerapkan metode abstrak (meskipun kelas turunannya adalah abstrak itu sendiri)
  • interface mungkin multi-inherit, kelas abstrak mungkin tidak (ini mungkin alasan konkret utama untuk ada secara terpisah dari kelas abtract - mereka mengizinkan implementasi multiple inheritance yang menghilangkan banyak masalah MI umum).

Sebagai istilah OO umum, perbedaannya tidak harus didefinisikan dengan baik. Sebagai contoh, ada programmer C ++ yang mungkin memiliki definisi kaku yang sama (interface adalah subset ketat dari kelas abstrak yang tidak dapat berisi implementasi), sementara beberapa mungkin mengatakan bahwa kelas abstrak dengan beberapa implementasi standar masih merupakan antarmuka atau non-abstrak kelas masih bisa mendefinisikan antarmuka.

Memang, ada idiom C ++ yang disebut Non-Virtual Interface (NVI) di mana metode publik adalah metode non-virtual yang 'dibuang' ke metode virtual pribadi:

Michael Burr
sumber
7
Terima kasih. Saya pikir karena jawaban Anda menyebutkan status + gambaran umum yang baik dari semua yang lain, saya menandai respons Anda sebagai jawaban akhir. Anda benar saya meminta OO umum, karena pewawancara pertama saya meminta OO umum, tetapi karena saya seorang pria C #, saya cenderung lupa itu. ;-) Juga terima kasih atas penjelasan C ++, seperti biasa c ++ membingungkan pikiran.
Houman
6
Saya pikir poin kunci dalam penjelasan yang diberikan Michael adalah bahwa ketika mengimplementasikan antarmuka, Anda HARUS mengimplementasikan semua anggota dalam antarmuka, tetapi ketika mewarisi dari kelas abstrak, TIDAK DIPERLUKAN oleh kelas anak untuk mengimplementasikan anggota induknya
Guillermo Gomez
82
+1: Saya berani bertaruh bahwa monyet-monyet yang menjadi tuan rumah wawancara bahkan tidak menyadari bahwa bahasa lain menerapkan OO secara berbeda.
Lightness Races dalam Orbit
2
@ JL Saya tidak melihat di mana masalahnya. Anda tampaknya bingung dengan metode abstrak dengan kelas abstrak. Metode abstrak tidak memiliki implementasi. Namun, di dalam kelas abstrak , beberapa metode bisa abstrak (yaitu tanpa implementasi) sementara beberapa yang lain memang bisa memiliki implementasi.
xji
19
Perhatikan bahwa di Java 8, Anda sekarang dapat memiliki metode default dan metode statis di antarmuka yang berarti bahwa antarmuka Java dapat memiliki implementasi. Rujukan di sini . Jelas Anda merujuk terutama ke .NET, jadi ini hanya pengamatan yang merujuk ke Jawa.
davtom
867

Bagaimana dengan analogi: ketika saya di Angkatan Udara, saya pergi ke pelatihan pilot dan menjadi pilot USAF (Angkatan Udara AS). Pada saat itu saya tidak memenuhi syarat untuk menerbangkan apa pun, dan harus mengikuti pelatihan jenis pesawat. Setelah saya memenuhi syarat, saya adalah seorang pilot (kelas abstrak) dan pilot C-141 (kelas beton). Di salah satu tugas saya, saya diberi tugas tambahan: Petugas Keselamatan. Sekarang saya masih seorang pilot dan pilot C-141, tetapi saya juga melakukan tugas-tugas Petugas Keselamatan (saya menerapkan ISafetyOfficer, jadi untuk berbicara). Seorang pilot tidak diharuskan menjadi petugas keselamatan, orang lain bisa melakukannya juga.

Semua pilot USAF harus mengikuti peraturan Angkatan Udara tertentu, dan semua pilot C-141 (atau F-16, atau T-38) adalah pilot USAF. Siapa pun bisa menjadi petugas keamanan. Jadi, untuk meringkas:

  • Pilot: kelas abstrak
  • C-141 Pilot: kelas beton
  • Petugas Keamanan: antarmuka

catatan tambahan: ini dimaksudkan sebagai analogi untuk membantu menjelaskan konsep, bukan rekomendasi pengkodean. Lihat berbagai komentar di bawah, pembahasannya menarik.

Jay
sumber
87
Saya sangat suka analogi ini, ia menggunakan contoh sederhana untuk menjelaskan topik yang sedikit rumit
Kevin Bowersox
13
Ini adalah cara terbaik untuk memahami terminologi OO yang kompleks. Singkatnya, semua teori hanya bernilai bila Anda dapat menggunakannya secara praktis. @Jay Anda melakukan rexample benar-benar mudah dipahami kemudian beberapa poin-poin (kebanyakan menembus pikiran daripada diserap!)
vs
54
Saya masih agak bingung. Katakanlah, Anda sekarang mendapatkan kualifikasi F-16 dan T-38, jadi sekarang kelas Jaytidak dapat mewarisi dari beberapa kelas (pilot C-141, pilot F-16 dan pilot T-38), apakah itu berarti bahwa kelas yang mana yang harus menjadi antarmuka? Terima kasih
Alex Okrushko
37
Banyak orang telah memberi +1 secara tepat pada komentar Alex, karena menunjukkan beberapa kelemahan dalam contoh ini. Pertama, saya akan mengatakan bahwa Jay akan menjadi turunan dari C-141Pilot daripada kelasnya sendiri. Selain itu, karena di USAF 99% dari semua pilot hanya memenuhi syarat dalam satu pesawat pada satu waktu (FCF dan pilot uji menjadi pengecualian penting) saya tidak mempertimbangkan beberapa kualifikasi dan bagaimana mungkin dilaksanakan. Seperti yang saya ketahui tentang seorang pilot yang, 50 tahun lalu, memenuhi syarat dalam 25 pesawat yang berbeda secara bersamaan, saya pikir itu mencontohkan bagaimana kita TIDAK ingin menggunakan banyak warisan.
Jay
20
Karena tidak mungkin bagi satu pilot untuk menerbangkan lebih dari satu pesawat pada satu waktu, itu akan menjadi peluang yang baik untuk menerapkan pola strategi. Pilot akan memiliki koleksi sertifikasi, dan memilih yang benar saat runtime. Sertifikasi akan dikodekan sebagai perilaku yang akan mengimplementasikan antarmuka IFlyPlane, dengan metode TakeOff, Land, Eject.
Michael Blackburn
221

Saya pikir jawaban yang mereka cari adalah perbedaan filosofis mendasar atau OPPS.

Warisan kelas abstrak digunakan ketika kelas turunan berbagi properti inti dan perilaku kelas abstrak. Jenis perilaku yang sebenarnya mendefinisikan kelas.

Di sisi lain warisan antarmuka digunakan ketika kelas-kelas berbagi perilaku periferal, yang tidak perlu mendefinisikan kelas turunan.

Untuk misalnya. Mobil dan Truk berbagi banyak properti inti dan perilaku kelas abstrak Automobile, tetapi mereka juga berbagi beberapa perilaku periferal seperti Menghasilkan knalpot yang bahkan kelas non-mobil seperti Bor atau PowerGenerators berbagi dan tidak serta merta mendefinisikan Mobil atau Truk , jadi Car, Truck, Driller dan PowerGenerator semuanya dapat berbagi antarmuka IExhaust yang sama.

Prasun
sumber
32
Saya pikir analogi yang lebih baik adalah "usesFuel" yang akan menunjukkan sifat kontrak antarmuka.
Pureferret
@ Pureferret jika acceleratemerupakan bagian dari perilaku inti kelas abstrak Automobile, maka saya tidak dapat mengatakan acceleratemenunjukkan sifat kontraknya . apa sifat kontrak? mengapa kata ini contractdiperkenalkan setiap kali kita berbicara tentang interface?
overexchange
@exchange karena biasanya antarmuka hanya di mana dua 'permukaan' bertemu, tetapi kata kontrak menyiratkan ada kesepakatan tentang bagaimana kedua 'permukaan' bertemu. Tidak masuk akal (setidaknya bagi saya) bahwa menghasilkan gas buang adalah sesuatu yang Anda 'setujui'. Tapi masuk akal (lagi untuk saya) bahwa Anda dapat setuju pada kebutuhan untuk menggunakan Bahan Bakar.
Pureferret
1
@ Pureferret saya mengajukan pertanyaan di tautan untuk hal yang sama
overexchange
1
@ Pureferret jika interfaceperlu memiliki perilaku periferal, lalu mengapa public interface List<E> extends Collection<E> {}dirancang untuk menggambarkan perilaku inti list? ini sebenarnya bertentangan dengan jawaban prasun. Keduanya Collection<E>dan List<E>merupakan antarmuka di sini.
overexchange
198

Pendek: Kelas abstrak digunakan untuk memodelkan hierarki kelas dengan kelas yang serupa (Misalnya Hewan dapat kelas abstrak dan Manusia, Singa, Harimau dapat kelas turunan konkret)

DAN

Antarmuka digunakan untuk Komunikasi antara 2 kelas yang sama / tidak serupa yang tidak peduli dengan jenis kelas yang mengimplementasikan Antarmuka (misalnya Tinggi dapat menjadi properti antarmuka dan dapat diimplementasikan oleh Manusia, Bangunan, Pohon. Tidak masalah jika Anda dapat makan , Anda bisa berenang, Anda bisa mati atau apa pun .. itu penting hanya hal yang Anda perlu memiliki Tinggi (implementasi di kelas Anda)).

Dhananjay
sumber
7
Saya sangat suka jawaban ini karena kadang-kadang sulit untuk menjawab "apa" yang berbeda antara hal-hal dengan melihat sesuatu yang lebih abstrak seperti niat , bukan hanya struktur (seperti secara struktural, antarmuka dan kelas abstrak murni hampir sama benda).
LostSalad
Sangat mudah untuk menyebutkan apa yang dapat dilakukan kelas abstrak vs antarmuka dalam bahasa tertentu, tetapi lebih sulit untuk membuat abstraksi untuk memberikan makna dan tanggung jawab pada objek dan apa yang Anda katakan benar-benar melanjutkan penggunaan konsep 2 dalam OO. Terima kasih!
Samuel
2
@ Dhananjay: saya melihat bagaimana Tinggi dapat terpisah dari konsep kelas Hewan dan dapat dari kelas lain yang berbeda, tetapi apa sebenarnya yang Anda maksud dengan "komunikasi" antara kelas? Itu hanya mendefinisikan Tinggi untuk kelasnya sendiri, benar?
TTT
77

Ada beberapa perbedaan lainnya -

Antarmuka tidak dapat memiliki implementasi konkret. Kelas dasar abstrak bisa. Ini memungkinkan Anda untuk memberikan implementasi konkret di sana. Ini dapat memungkinkan kelas dasar abstrak untuk benar-benar memberikan kontrak yang lebih ketat, sedangkan antarmuka hanya menggambarkan bagaimana kelas digunakan. (Kelas dasar abstrak dapat memiliki anggota non-virtual yang mendefinisikan perilaku, yang memberikan lebih banyak kontrol kepada penulis kelas dasar.)

Lebih dari satu antarmuka dapat diimplementasikan pada suatu kelas. Kelas hanya bisa berasal dari satu kelas dasar abstrak. Hal ini memungkinkan untuk hierarki polimorfik menggunakan antarmuka, tetapi tidak kelas dasar abstrak. Ini juga memungkinkan untuk pseudo-multi-inheritance menggunakan antarmuka.

Kelas dasar abstrak dapat dimodifikasi dalam v2 + tanpa merusak API. Perubahan pada antarmuka merusak perubahan.

[C # /. NET Specific] Antarmuka, tidak seperti kelas dasar abstrak, dapat diterapkan ke tipe nilai (struct). Structs tidak dapat diwarisi dari kelas dasar abstrak. Ini memungkinkan kontrak perilaku / pedoman penggunaan diterapkan pada tipe nilai.

Reed Copsey
sumber
5
+1 untuk titik kunci bahwa lebih dari satu antarmuka dapat diimplementasikan pada suatu kelas.
cgp
Itulah satu keuntungan nyata untuk antarmuka dibandingkan kelas dasar abstrak, IMO. Kalau tidak, saya setuju dengan pedoman desain .NET, yang sekarang mengatakan untuk "lebih suka kelas dasar abstrak daripada antarmuka"
Reed Copsey
Meskipun, akan sangat tertarik jika Anda dapat menambahkan titik bahwa itu juga antarmuka dapat diterapkan ke kelas mana pun.
cgp
1
@altCognito: Figur yang agak ditangani dengan paragraf kedua. Ini memang mengingatkan saya, bahwa antarmuka bekerja pada tipe nilai, jadi saya menambahkannya.
Reed Copsey
Terima kasih banyak atas deskripsi yang tepat ini. Ini memang sangat membantu. Saya baru disini. Sangat disayangkan Anda tidak dapat memilih dua tanggapan sebagai "jawaban". Satu hal yang membingungkan saya adalah penggunaan kelas Abstrak 'base' Anda. Semua kelas abstrak dimaksudkan untuk menjadi kelas dasar dari subkelas. Mengapa memberi nama 'basis' ekstra?
Houman
68

Warisan
Pertimbangkan mobil dan bus. Mereka adalah dua kendaraan yang berbeda. Tapi tetap saja, mereka berbagi beberapa sifat umum seperti mereka memiliki kemudi, rem, roda gigi, mesin dll.
Jadi dengan konsep warisan, ini dapat direpresentasikan sebagai berikut ...

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Sekarang Sepeda ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

Dan sebuah mobil ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

Itu semua tentang Warisan . Kami menggunakannya untuk mengklasifikasikan objek ke bentuk Basis yang lebih sederhana dan anak-anak mereka seperti yang kita lihat di atas.

Kelas Abstrak

Kelas abstrak adalah objek yang tidak lengkap . Untuk memahaminya lebih jauh, mari kita pertimbangkan analogi kendaraan sekali lagi.
Kendaraan dapat dikendarai. Baik? Tetapi kendaraan yang berbeda digerakkan dengan cara yang berbeda ... Misalnya, Anda tidak dapat mengendarai mobil sama seperti Anda mengendarai Sepeda.
Lantas bagaimana cara merepresentasikan fungsi penggerak kendaraan? Lebih sulit untuk memeriksa jenis kendaraan apa itu dan mengendarainya dengan fungsinya sendiri; Anda harus mengubah kelas Driver lagi dan lagi ketika menambahkan jenis kendaraan baru.
Di sinilah peran kelas dan metode abstrak. Anda dapat mendefinisikan metode drive sebagai abstrak untuk memberi tahu bahwa setiap anak yang diwariskan harus mengimplementasikan fungsi ini.
Jadi, jika Anda memodifikasi kelas kendaraan ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

Sepeda dan Mobil juga harus menentukan cara mengendarainya. Jika tidak, kode tidak akan dikompilasi dan kesalahan dilemparkan.
Singkatnya .. kelas abstrak adalah kelas sebagian tidak lengkap dengan beberapa fungsi tidak lengkap, yang harus diwariskan oleh anak-anak warisan mereka sendiri.

Antarmuka Antarmuka sama sekali tidak lengkap. Mereka tidak memiliki properti apa pun. Mereka hanya menunjukkan bahwa anak-anak yang diwariskan mampu melakukan sesuatu ...
Misalkan Anda memiliki berbagai jenis ponsel dengan Anda. Masing-masing dari mereka memiliki cara berbeda untuk melakukan fungsi yang berbeda; Mis: panggil seseorang. Pembuat telepon menentukan cara melakukannya. Di sini ponsel dapat memanggil nomor - artinya dial-bisa. Mari kita wakili ini sebagai antarmuka.

public interface Dialable {
    public void dial(Number n);
}

Di sini pembuat Dialable mendefinisikan cara memanggil nomor. Anda hanya perlu memberikan nomor untuk dial.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Dengan ini menggunakan antarmuka bukan kelas abstrak, penulis fungsi yang menggunakan Dialable tidak perlu khawatir tentang propertinya. Contoh: Apakah memiliki layar sentuh atau papan tombol, Apakah ini telepon darat atau telepon seluler tetap. Anda hanya perlu tahu apakah itu bisa diputar; apakah itu mewarisi (atau mengimplementasikan) antarmuka Dialable.

Dan yang lebih penting , jika suatu hari Anda mengganti Dialable dengan yang lain

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Anda dapat memastikan bahwa kode masih berfungsi dengan baik karena fungsi yang menggunakan dialable tidak (dan tidak bisa) bergantung pada detail selain yang ditentukan dalam antarmuka Dialable. Keduanya mengimplementasikan antarmuka Dialable dan itulah satu-satunya fungsi yang diperhatikan.

Antarmuka biasanya digunakan oleh pengembang untuk memastikan interoperabilitas (digunakan secara bergantian) di antara objek, sejauh mereka berbagi fungsi umum (sama seperti Anda dapat mengubah ke telepon rumah atau ponsel, sejauh Anda hanya perlu menekan nomor). Singkatnya, antarmuka adalah versi kelas abstrak yang jauh lebih sederhana, tanpa properti apa pun.
Juga, perhatikan bahwa Anda dapat mengimplementasikan (mewarisi) sebanyak mungkin antarmuka yang Anda inginkan tetapi Anda hanya dapat memperluas (mewarisi) kelas induk tunggal.

Info Lebih Lanjut Kelas abstrak vs. Antarmuka

fz_salam
sumber
Tidak benar bahwa "Antarmuka tidak memiliki properti".
Bigeyes
@Bigeyes, java tidak mengizinkan properti di antarmuka. Saya pikir itu sama dalam bahasa lain juga. Bisakah Anda jelaskan lebih lanjut?
fz_salam
Saya mengacu pada C # /. Net. Silakan lihat contohnya
Bigeyes
@Bigeyes untuk C # di mana antarmuka dapat memiliki properti, bukankah itu memperkenalkan kembali masalah pewarisan berganda? Apa yang terjadi ketika suatu kelas menggunakan banyak antarmuka yang telah mendefinisikan properti yang sama? Hanya ingin tahu terima kasih
stackPusher
@happycoder: re: "Di sini dengan menggunakan antarmuka alih-alih kelas abstrak, Anda tidak perlu khawatir tentang properti itu. Mis: Apakah memiliki layar sentuh atau dial pad, Apakah itu telepon darat atau ponsel tetap. Anda hanya perlu tahu apakah itu dialable; apakah itu mewarisi (atau mengimplementasikan) antarmuka Dialable. " - dapatkah Anda menunjukkan ini dalam contoh kode, juga tidak melihat bagaimana itu akan diwarisi ...
TTT
45

Jika Anda menganggap javasebagai bahasa OOP untuk menjawab pertanyaan ini, rilis Java 8 menyebabkan beberapa konten dalam jawaban di atas sebagai usang. Sekarang antarmuka java dapat memiliki metode standar dengan implementasi konkret.

Situs web Oracle menyediakan perbedaan utama antara interfacedan abstractkelas.

Pertimbangkan menggunakan kelas abstrak jika:

  1. Anda ingin berbagi kode di antara beberapa kelas yang terkait erat.
  2. Anda berharap bahwa kelas yang memperluas kelas abstrak Anda memiliki banyak metode atau bidang umum, atau memerlukan pengubah akses selain publik (seperti yang dilindungi dan pribadi).
  3. Anda ingin mendeklarasikan bidang non-statis atau non-final.

Pertimbangkan menggunakan antarmuka jika:

  1. Anda berharap bahwa kelas yang tidak terkait akan mengimplementasikan antarmuka Anda. Sebagai contoh, banyak objek yang tidak berhubungan dapat mengimplementasikan Serializableantarmuka.
  2. Anda ingin menentukan perilaku tipe data tertentu, tetapi tidak peduli tentang siapa yang mengimplementasikan perilakunya.
  3. Anda ingin memanfaatkan multiple inheritance of type.

Secara sederhana, saya ingin menggunakan

antarmuka: Untuk menerapkan kontrak dengan beberapa objek yang tidak terkait

kelas abstrak: Untuk menerapkan perilaku yang sama atau berbeda di antara beberapa objek terkait

Lihat contoh kode untuk memahami berbagai hal dengan jelas: Bagaimana seharusnya saya menjelaskan perbedaan antara kelas Interface dan abstrak?

Ravindra babu
sumber
33

Pewawancara menggonggong pohon aneh. Untuk bahasa seperti C # dan Java, ada perbedaan, tetapi dalam bahasa lain seperti C ++ tidak ada. Teori OO tidak membedakan keduanya, hanya sintaksis bahasa.

Kelas abstrak adalah kelas dengan implementasi dan antarmuka (metode virtual murni) yang akan diwariskan. Antarmuka umumnya tidak memiliki implementasi apa pun tetapi hanya fungsi virtual murni.

Dalam C # atau Java kelas abstrak tanpa implementasi berbeda dari antarmuka hanya dalam sintaks yang digunakan untuk mewarisi darinya dan fakta bahwa Anda hanya dapat mewarisi dari satu.

Steve Rowe
sumber
Saya ditanya pertanyaan yang sama seminggu yang lalu, saya tidak punya pengalaman dengan Java tapi saya telah bekerja dengan C ++ untuk sementara waktu sekarang. Pewawancara tidak menentukan bahasa sebelum mengajukan pertanyaan, jadi saya hanya menjelaskan bahwa antarmuka dalam kasus ini adalah kelas abstrak tanpa status atau implementasi apa pun. Saya setuju bahwa ini juga pertanyaan aneh.
dacabdi
31

Dengan mengimplementasikan antarmuka Anda mencapai komposisi ("memiliki-a" hubungan) alih-alih warisan ("is-a" hubungan). Itu adalah prinsip penting untuk diingat ketika datang ke hal-hal seperti pola desain di mana Anda perlu menggunakan antarmuka untuk mencapai komposisi perilaku, bukan warisan.

TheTXI
sumber
17
Antarmuka mencapai, IMO, lebih dari hubungan "Acts-as-a". Enkapsulasi menghasilkan komposisi yang lebih baik daripada antarmuka.
Reed Copsey
12
Saya tidak berpikir mengimplementasikan antarmuka akan berada di bawah komposisi.
Pavan Dittakavi
Plus, antarmuka lebih mungkin digunakan untuk mendeskripsikan "kemampuan", seperti IDisposable. Ini digunakan untuk berbagi fungsionalitas antara kelas bahwa kelas-kelas ini "dapat melakukan" sesuatu. Lebih banyak contoh IFlyable dapat diimplementasikan dengan burung dan pesawat. Tapi Bird mungkin berasal dari Class Creature tempat pesawat terbang berasal dari AirCraft.
Peter.Wang
26

saya akan menjelaskan Detail Kedalaman antarmuka dan class.if Abstrak Anda tahu gambaran umum tentang antarmuka dan kelas abstrak, maka pertanyaan pertama tiba di pikiran Anda ketika kita harus menggunakan Interface dan kapan kita harus menggunakan kelas Abstrak. Jadi silakan periksa penjelasan di bawah ini tentang kelas Interface dan Abstract.

  1. Kapan kita harus menggunakan Interface?

    jika Anda tidak tahu tentang implementasi hanya kami memiliki spesifikasi persyaratan maka kami pergi dengan Interface

  2. Kapan kita harus menggunakan Kelas Abstrak?

    jika Anda tahu implementasi tetapi tidak sepenuhnya (implementasi sebagian) maka kita pergi dengan kelas abstrak.

    Antarmuka

    setiap metode dengan abstrak publik standar berarti antarmuka adalah 100% abstrak murni.

    Abstrak

    dapat memiliki metode Beton dan metode Abstrak, apa itu metode Beton, yang memiliki implementasi di kelas Abstrak, kelas abstrak adalah kelas yang dinyatakan abstrak — mungkin atau mungkin tidak termasuk metode abstrak.

    Antarmuka

    Kami tidak dapat menyatakan antarmuka sebagai pribadi, terlindungi

    P. Mengapa kami tidak mendeklarasikan Interface sebagai pribadi dan terlindungi?

    Karena secara default metode antarmuka adalah abstrak publik dan karena itu kami tidak menyatakan antarmuka sebagai pribadi dan terlindungi.

    Metode antarmuka
    juga kami tidak dapat menyatakan antarmuka sebagai pribadi, dilindungi, final, statis, disinkronkan, asli .....

    saya akan memberikan alasan: mengapa kita tidak mendeklarasikan metode yang disinkronkan karena kita tidak dapat membuat objek antarmuka dan sinkronisasi bekerja pada objek sehingga dan alasan mengapa kita tidak mendeklarasikan metode yang disinkronkan Konsep transien juga tidak berlaku karena pekerjaan transien dengan disinkronkan.

    Abstrak

    kami dengan senang hati menggunakan statis final publik, swasta .... berarti tidak ada batasan yang berlaku secara abstrak.

    Antarmuka

    Variabel dideklarasikan di Antarmuka sebagai final statis publik secara default sehingga kami juga tidak dinyatakan sebagai variabel pribadi, terlindungi.

    Pengubah volatil juga tidak berlaku di antarmuka karena variabel antarmuka secara default variabel final dan final statis publik Anda tidak dapat mengubah nilai setelah menetapkan nilai menjadi variabel dan setelah Anda mendeklarasikan variabel ke antarmuka Anda harus menetapkan variabel.

    Dan variabel volatile terus berubah sehingga itu adalah opp. untuk final itu alasan kami tidak menggunakan variabel volatile di antarmuka.

    Abstrak

    Variabel abstrak tidak perlu dinyatakan final statis publik.

semoga artikel ini bermanfaat.

JegsVala
sumber
4
Saya tidak setuju dengan poin ini: Abstract class must have at lease one abstract method.Ini mungkin untuk memiliki kelas abstrak tanpa metode abstrak, selama Anda menerapkannya. REFERENSI: An abstract class is a class that is declared abstract—it may or may not include abstract methods.SUMBER REFERENSI: docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Devner
Anda berbicara tentang detail teknis dan implementasi, Anda tidak menjawab pertanyaan dalam hal OOP umum
Billal Begueradj
26

Berbicara secara konseptual, menjaga implementasi khusus bahasa, aturan, manfaat dan mencapai tujuan pemrograman apa pun dengan menggunakan siapa pun atau keduanya, dapat atau tidak dapat memiliki kode / data / properti, bla bla, warisan tunggal atau ganda, disamping semua

1- Abstrak (atau abstrak murni) Kelas dimaksudkan untuk mengimplementasikan hierarki. Jika objek bisnis Anda terlihat agak mirip secara struktural, hanya mewakili jenis hubungan orangtua-anak (hierarki), maka kelas pewarisan / abstrak akan digunakan. Jika model bisnis Anda tidak memiliki hierarki maka pewarisan tidak boleh digunakan (di sini saya tidak berbicara tentang logika pemrograman misalnya beberapa pola desain memerlukan pewarisan). Secara konseptual, kelas abstrak adalah metode untuk mengimplementasikan hierarki model bisnis dalam OOP, itu tidak ada hubungannya dengan Antarmuka, sebenarnya membandingkan kelas Abstrak dengan Antarmuka tidak ada artinya karena keduanya secara konseptual sama sekali berbeda, itu ditanyakan dalam wawancara hanya untuk memeriksa konsep karena kelihatannya keduanya menyediakan fungsionalitas yang agak sama ketika implementasi yang bersangkutan dan kami programmer biasanya lebih menekankan pada pengkodean. [Ingatlah juga bahwa Abstraksi berbeda dari Kelas Abstrak].

2- an Antarmuka adalah kontrak, fungsionalitas bisnis lengkap yang diwakili oleh satu atau lebih set fungsi. Itulah mengapa ini diterapkan dan tidak diwariskan. Objek bisnis (bagian dari hierarki atau tidak) dapat memiliki sejumlah fungsi bisnis lengkap. Ini tidak ada hubungannya dengan kelas abstrak yang berarti warisan secara umum. Misalnya, manusia dapat MENJALANKAN, seekor gajah dapat MENJALANKAN, seekor burung dapat MENJALANKAN, dan sebagainya, semua objek dari hierarki yang berbeda ini akan mengimplementasikan antarmuka RUN atau antarmuka EAT atau SPEAK. Jangan masuk ke implementasi karena Anda mungkin mengimplementasikannya sebagai memiliki kelas abstrak untuk setiap jenis yang mengimplementasikan antarmuka ini. Objek hierarki apa pun dapat memiliki fungsi (antarmuka) yang tidak ada hubungannya dengan hierarki.

Saya percaya, Antarmuka tidak diciptakan untuk mencapai beberapa warisan atau untuk mengekspos perilaku publik, dan juga, kelas abstrak murni tidak mengesampingkan antarmuka tetapi Antarmuka adalah fungsi yang dapat dilakukan objek (melalui fungsi antarmuka itu) dan Kelas Abstrak mewakili suatu induk dari hierarki untuk menghasilkan anak-anak yang memiliki struktur inti (properti + fungsi) dari orangtua

Ketika Anda ditanya tentang perbedaannya, itu sebenarnya perbedaan konseptual bukan perbedaan dalam implementasi spesifik bahasa kecuali diminta secara eksplisit.

Saya percaya, kedua pewawancara mengharapkan satu garis perbedaan langsung antara keduanya dan ketika Anda gagal mereka mencoba mengarahkan Anda ke perbedaan ini dengan menerapkan SATU sebagai LAINNYA.

Bagaimana jika Anda memiliki kelas abstrak dengan metode abstrak saja?

bjan
sumber
Itu cukup meringkas jawaban untuk pertanyaan ini dengan cukup baik.
pranavn
fungsi diimplementasikan vs struktur diperpanjang, bagus!
harshvchawla
21

Untuk .Net,

Jawaban Anda terhadap pewawancara kedua juga merupakan jawaban untuk yang pertama ... Kelas abstrak dapat memiliki implementasi, DAN negara, antarmuka tidak dapat ...

EDIT: Pada catatan lain, saya bahkan tidak akan menggunakan frase 'subclass' (atau frase 'inheritance') untuk menggambarkan kelas yang 'didefinisikan untuk mengimplementasikan' sebuah antarmuka. Bagi saya, antarmuka adalah definisi kontrak yang harus dipatuhi oleh kelas jika telah didefinisikan untuk 'mengimplementasikan' antarmuka itu. Itu tidak mewarisi apa pun ... Anda harus menambahkan semuanya sendiri, secara eksplisit.

Charles Bretana
sumber
2
Iya! Negara! Itulah yang dimaksud pewawancara kedua dengan cara anehnya mengatakan "variabel publik" di dalam antarmuka. Astaga! Kelas Abstrak dapat memiliki status, antarmuka tidak bisa! Dan ya, semua orang setuju pada perbedaan antara cara-cara pewarisan mereka juga, yang saya lupa sebutkan tetapi sudah tahu nanti. :) Terimakasih semuanya!
Houman
4
Lebih dari sekadar menyatakan .... Kelas abstrak dapat memiliki IMPLEMENTASI. yaitu, mereka dapat memiliki metode dengan kode di dalamnya yang benar-benar berjalan dan melakukan sesuatu, yang akan diwarisi dan dieksekusi oleh instance dari kelas dasar ... Tidak demikian dengan antarmuka
Charles Bretana
Bahkan lebih dari itu, di satu sisi, kelas-kelas Abstrak BISA instantiated, mereka hanya harus dipakai menggunakan definisi kelas turunan, tidak secara langsung. Tetapi variabel state yang didefinisikan dalam kelas abstrak adalah instantiated pada objek yang dibuat dengan membuat instance turunan kelas. Instance ini adalah turunan dari kelas abstrak dan juga turunan dari kelas turunan - ini adalah turunannya. Semua ini tidak benar untuk sebuah antarmuka.
Charles Bretana
Ketika Anda membuat instance kelas yang didefinisikan untuk mengimplementasikan antarmuka, itu bukan "instance" dari antarmuka itu, semua sintaks yang dilakukan adalah menyebabkan kompiler memeriksa kode untuk kelas dan memastikan bahwa setiap perilaku (metode, properti , event, eventHandler, dll.) yang didefinisikan oleh antarmuka telah diimplementasikan dalam kode untuk kelas.
Charles Bretana
20

Antarmuka : harus digunakan jika Anda ingin menyiratkan aturan tentang komponen yang mungkin terkait atau tidak

Pro:

  1. Mengizinkan beberapa pewarisan
  2. Memberikan abstraksi dengan tidak mengekspos objek apa yang digunakan dalam konteks
  3. memberikan konsistensi dengan tanda tangan spesifik kontrak

Cons:

  1. Harus menerapkan semua kontrak yang ditentukan
  2. Tidak dapat memiliki variabel atau delegasi
  3. Setelah didefinisikan tidak dapat diubah tanpa merusak semua kelas

Kelas Abstrak : harus digunakan di mana Anda ingin memiliki beberapa perilaku dasar atau standar atau implementasi untuk komponen yang terkait satu sama lain

Pro:

  1. Lebih cepat dari antarmuka
  2. Memiliki fleksibilitas dalam implementasi (Anda dapat mengimplementasikannya sepenuhnya atau sebagian)
  3. Dapat dengan mudah diubah tanpa merusak kelas yang diturunkan

Cons:

  1. Tidak bisa dipakai
  2. Tidak mendukung multiple inheritance
webmaster bourax
sumber
Tentukan lebih cepat. Apakah ini penting? Apa artinya itu? opcode untuk pemanggilan fungsi pada kelas abstrak lebih cepat dari opcode untuk pemanggilan fungsi pada suatu antarmuka?
denis631
@ denis631 kelas abstrak sedikit lebih cepat daripada antarmuka karena pencarian dan panggilan terlibat dalam metode antarmuka. baca coderanch.com/t/503450/java/abstract-class-faster-interface
bourax webmaster
17

Saya pikir mereka tidak menyukai respons Anda karena Anda memberikan perbedaan teknis alih-alih desain. Pertanyaannya seperti pertanyaan troll untuk saya. Bahkan, antarmuka dan kelas abstrak memiliki sifat yang sama sekali berbeda sehingga Anda tidak dapat benar-benar membandingkannya. Saya akan memberi Anda visi saya tentang apa peran antarmuka dan apa peran kelas abstrak.

antarmuka: digunakan untuk memastikan kontrak dan membuat kopling rendah antar kelas untuk memiliki aplikasi yang lebih dapat dikelola, terukur dan dapat diuji.

kelas abstrak: hanya digunakan untuk memfaktisasi beberapa kode antar kelas dengan responsabilitas yang sama. Perhatikan bahwa ini adalah alasan utama mengapa multiple-inheritance adalah hal yang buruk dalam OOP, karena kelas tidak seharusnya menangani banyak tanggung jawab (gunakan komposisi sebagai gantinya).

Jadi interface memiliki peran arsitektural yang nyata sedangkan kelas abstrak hampir hanya detail implementasi (jika Anda menggunakannya dengan benar tentu saja).

Gnucki
sumber
13
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

Documents dengan jelas mengatakan bahwa jika kelas abstrak hanya berisi deklarasi metode abstrak, itu harus dinyatakan sebagai antarmuka.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Variabel di Antarmuka secara statis publik dan final. Pertanyaan dapat dibingkai seperti bagaimana jika semua variabel di kelas abstrak adalah publik? Yah mereka masih bisa menjadi tidak statis dan tidak final tidak seperti variabel dalam antarmuka.

Akhirnya saya akan menambahkan satu poin lagi ke yang disebutkan di atas - kelas abstrak masih kelas dan jatuh di pohon warisan tunggal sedangkan antarmuka dapat hadir dalam banyak pewarisan.

Aniket Thakur
sumber
13
  1. Antarmuka:
    • Kami tidak menerapkan (atau mendefinisikan) metode, kami melakukannya di kelas turunan.
    • Kami tidak mendeklarasikan variabel anggota dalam antarmuka.
    • Antarmuka mengungkapkan hubungan HAS-A. Itu berarti mereka adalah topeng benda.
  2. Kelas abstrak:
    • Kita dapat mendeklarasikan dan mendefinisikan metode dalam kelas abstrak.
    • Kami menyembunyikan konstruktornya. Itu berarti tidak ada objek yang dibuat darinya secara langsung.
    • Kelas abstrak dapat menampung variabel anggota.
    • Kelas turunan mewariskan ke kelas abstrak yang berarti objek dari kelas turunan tidak bertopeng, itu diturunkan ke kelas abstrak. Hubungan dalam kasus ini adalah IS-A.

Ini pendapat saya.

nautilusvn
sumber
12

Disalin dari CLR via C # oleh Jeffrey Richter ...

Saya sering mendengar pertanyaan, "Haruskah saya mendesain tipe dasar atau antarmuka?" Jawabannya tidak selalu jelas.

Berikut adalah beberapa panduan yang mungkin membantu Anda:

■■ IS-A vs. Hubungan CAN-DO Suatu tipe hanya dapat mewarisi satu implementasi. Jika tipe turunan tidak dapat mengklaim hubungan IS-A dengan tipe dasar, jangan gunakan tipe dasar; gunakan antarmuka. Antarmuka menyiratkan hubungan CAN-DO. Jika fungsionalitas CAN-DO tampaknya milik berbagai jenis objek, gunakan antarmuka. Misalnya, suatu tipe dapat mengonversi instans dari dirinya sendiri ke tipe lain (IConvertible), suatu tipe dapat membuat serial contoh itu sendiri (ISerializable), dll. Perhatikan bahwa tipe nilai harus diturunkan dari System.ValueType, dan oleh karena itu, mereka tidak dapat diturunkan dari kelas dasar yang sewenang-wenang. Dalam hal ini, Anda harus menggunakan hubungan CAN-DO dan mendefinisikan antarmuka.

■■ Kemudahan penggunaan Biasanya lebih mudah bagi Anda sebagai pengembang untuk menentukan tipe baru yang berasal dari tipe dasar daripada menerapkan semua metode antarmuka. Tipe dasar dapat menyediakan banyak fungsi, sehingga tipe turunan mungkin hanya membutuhkan modifikasi yang relatif kecil untuk perilakunya. Jika Anda menyediakan antarmuka, tipe baru harus mengimplementasikan semua anggota.

■■ Implementasi yang konsisten Tidak peduli seberapa baik kontrak antarmuka didokumentasikan, sangat tidak mungkin bahwa setiap orang akan menerapkan kontrak 100 persen dengan benar. Bahkan, COM menderita masalah ini, itulah sebabnya beberapa objek COM bekerja dengan benar hanya dengan Microsoft Word atau Windows Internet Explorer. Dengan menyediakan tipe dasar dengan implementasi default yang baik, Anda mulai menggunakan tipe yang berfungsi dan diuji dengan baik; Anda kemudian dapat memodifikasi bagian yang perlu modifikasi.

■■ Versi Jika Anda menambahkan metode ke tipe dasar, tipe turunan mewarisi metode baru, Anda mulai menggunakan tipe yang berfungsi, dan kode sumber pengguna bahkan tidak perlu dikompilasi ulang. Menambahkan anggota baru ke antarmuka memaksa pewaris antarmuka untuk mengubah kode sumbernya dan mengkompilasi ulang.

Deepak Mishra
sumber
1
@AbdullahShoaib adalah-dan siapa saja yang bisa melakukan tetapi tidak bisa melakukan, ada perbedaan di sini. inilah alasan dasarnya, kita membutuhkan antarmuka. perilaku can-do juga akan menjadi bagian dari abstract classitu.
overexchange
10

Antarmuka mendefinisikan kontrak untuk layanan atau serangkaian layanan. Mereka menyediakan polimorfisme secara horizontal di mana dua kelas yang benar-benar tidak terkait dapat mengimplementasikan antarmuka yang sama tetapi digunakan secara bergantian sebagai parameter dari jenis antarmuka yang mereka implementasikan, karena kedua kelas telah berjanji untuk memenuhi serangkaian layanan yang ditentukan oleh antarmuka. Antarmuka tidak memberikan detail implementasi.

Kelas abstrak mendefinisikan struktur dasar untuk sub cabang, dan implementasi parsial opsional. Kelas abstrak menyediakan polimorfisme secara vertikal, tetapi terarah, bahwa setiap kelas yang mewarisi kelas abstrak dapat diperlakukan sebagai turunan dari kelas abstrak tersebut tetapi tidak sebaliknya. Kelas abstrak dapat dan sering mengandung rincian implementasi, tetapi tidak dapat dibuat sendiri - hanya subclass mereka yang dapat "baru".

C # memang memungkinkan untuk warisan antarmuka juga, ingatlah.

joelmdev
sumber
1
Menggunakan istilah horisontal dan vertikal membuatnya sangat jelas untuk membayangkan perbedaannya.
Infinity
10

Sebagian besar jawaban berfokus pada perbedaan teknis antara Kelas Abstrak dan Antarmuka, tetapi karena secara teknis, antarmuka pada dasarnya adalah sejenis kelas abstrak (satu tanpa data atau implementasi), saya pikir perbedaan konseptual jauh lebih menarik, dan mungkin itulah yang pewawancara mengejar.

Sebuah Antarmuka adalah kesepakatan . Ini menentukan: "ini adalah bagaimana kita akan berbicara satu sama lain". Itu tidak dapat memiliki implementasi apa pun karena itu tidak seharusnya memiliki implementasi apa pun. Itu kontrak. Ini seperti .hfile header di C.

Sebuah Kelas Abstrak adalah implementasi lengkap . Kelas mungkin atau mungkin tidak mengimplementasikan antarmuka, dan kelas abstrak tidak harus mengimplementasikannya sepenuhnya. Kelas abstrak tanpa implementasi apa pun tidak berguna, tetapi sepenuhnya legal.

Pada dasarnya setiap kelas, abstrak atau tidak, adalah tentang apa yang , sedangkan antarmuka adalah tentang bagaimana Anda menggunakannya . Sebagai contoh: Animalmungkin kelas abstrak yang menerapkan beberapa fungsi metabolisme dasar, dan menentukan metode abstrak untuk bernafas dan bergerak tanpa memberikan implementasi, karena ia tidak tahu apakah ia harus bernapas melalui insang atau paru-paru, dan apakah ia terbang, berenang, berjalan atau merangkak. Mount, di sisi lain, mungkin saja sebuah Antarmuka, yang menentukan bahwa Anda dapat menunggangi hewan, tanpa mengetahui jenis hewan apa itu (atau apakah itu binatang sama sekali!).

Fakta bahwa di balik layar, sebuah antarmuka pada dasarnya adalah kelas abstrak dengan hanya metode abstrak, tidak masalah. Secara konseptual, mereka mengisi peran yang sama sekali berbeda.

mcv
sumber
10

Karena Anda mungkin telah mendapatkan pengetahuan teoretis dari para ahli, saya tidak menghabiskan banyak kata untuk mengulang semua yang ada di sini, tetapi izinkan saya menjelaskan dengan contoh sederhana di mana kita dapat menggunakan / tidak dapat menggunakan Interfacedan Abstract class.

Pertimbangkan Anda sedang merancang aplikasi untuk mendaftar semua fitur Mobil. Di berbagai titik Anda membutuhkan pewarisan yang sama, karena beberapa properti seperti DigitalFuelMeter, Pendingin Ruangan, Penyesuaian kursi, dll. Adalah hal yang umum untuk semua mobil. Demikian juga, kita memerlukan pewarisan untuk beberapa kelas hanya karena beberapa properti seperti sistem pengereman (ABS, EBD) hanya berlaku untuk beberapa mobil.

Kelas di bawah ini bertindak sebagai kelas dasar untuk semua mobil:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Anggaplah kita memiliki kelas yang terpisah untuk setiap Mobil.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Pertimbangkan kita membutuhkan metode untuk mewarisi teknologi Pengereman untuk mobil Verna dan Cruze (tidak berlaku untuk Alto). Meski sama-sama menggunakan teknologi pengereman, "teknologinya" berbeda. Jadi kami membuat kelas abstrak di mana metode ini akan dinyatakan sebagai Abstrak dan harus diimplementasikan di kelas anak-anaknya.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Sekarang kami mencoba mewarisi dari kelas abstrak ini dan jenis sistem pengereman diterapkan di Verna dan Cruze:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

Lihat masalah di dua kelas di atas? Mereka mewarisi dari beberapa kelas yang C # .Net tidak mengizinkan meskipun metode ini diterapkan pada anak-anak. Di sinilah kebutuhan Interface.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

Dan implementasinya diberikan di bawah ini:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Sekarang Verna dan Cruze dapat mencapai banyak warisan dengan jenis teknologi pengeremannya sendiri dengan bantuan Antarmuka.

Sarath Avanavu
sumber
4
Ini adalah salah satu penjelasan terbaik karena contoh-contohnya.
Adam Mendoza
2
Ini masuk akal bagi saya tanpa memeras otak. Saya hanya mencoba memberikan contoh mobil untuk murid-murid saya. Terima kasih telah meluangkan waktu untuk menyatukan ini.
tazboy
9

Antarmuka adalah cara yang ringan untuk menegakkan perilaku tertentu. Itu adalah salah satu cara untuk berpikir.

fastcodejava
sumber
8

Jawaban ini terlalu panjang.

  • Antarmuka adalah untuk mendefinisikan perilaku.

  • Kelas abstrak adalah untuk mendefinisikan sesuatu itu sendiri, termasuk perilakunya. Itu sebabnya kami terkadang membuat kelas abstrak dengan beberapa properti tambahan mewarisi antarmuka.

Ini juga menjelaskan mengapa Java hanya mendukung pewarisan tunggal untuk kelas tetapi tidak membatasi antarmuka. Karena benda konkret tidak bisa menjadi hal yang berbeda, tetapi dapat memiliki perilaku yang berbeda.

K.Miao
sumber
7

1) Sebuah antarmuka dapat dilihat sebagai Kelas Abstrak murni, adalah sama, tetapi meskipun demikian, tidak sama untuk mengimplementasikan antarmuka dan mewarisi dari kelas abstrak. Saat Anda mewarisi dari kelas abstrak murni ini, Anda mendefinisikan hierarki -> warisan, jika Anda mengimplementasikan antarmuka yang bukan, dan Anda dapat mengimplementasikan sebanyak mungkin antarmuka yang Anda inginkan, tetapi Anda hanya dapat mewarisi dari satu kelas.

2) Anda bisa mendefinisikan properti dalam sebuah antarmuka, sehingga kelas yang mengimplementasikan antarmuka itu harus memiliki properti itu.

Sebagai contoh:

  public interface IVariable
  {
      string name {get; set;}
  }

Kelas yang mengimplementasikan antarmuka itu harus memiliki properti seperti itu.

MRFerocius
sumber
7

Meskipun pertanyaan ini sudah cukup lama, saya ingin menambahkan satu hal lain yang mendukung antarmuka:

Antarmuka dapat disuntikkan menggunakan alat Injeksi Ketergantungan mana injeksi kelas Abstrak didukung oleh sangat sedikit.

py2020
sumber
1
Saya yakin maksud Anda alat DI dapat menyuntikkan kelas yang mengimplementasikan antarmuka. Beberapa alat seperti itu juga dapat menyuntikkan kelas yang berasal dari kelas abstrak, atau Anda mengatakan itu tidak mungkin?
John Saunders
6

Dari jawaban saya yang lain , sebagian besar berurusan dengan kapan harus menggunakan satu versus yang lain:

Dalam pengalaman saya, antarmuka paling baik digunakan ketika Anda memiliki beberapa kelas yang masing-masing perlu menanggapi metode atau metode yang sama sehingga mereka dapat digunakan secara bergantian oleh kode lain yang akan ditulis terhadap antarmuka umum kelas-kelas tersebut. Penggunaan antarmuka yang terbaik adalah ketika protokol penting tetapi logika yang mendasari mungkin berbeda untuk setiap kelas. Jika Anda akan menggandakan logika, pertimbangkan kelas abstrak atau warisan kelas standar sebagai gantinya.

Adam Alexander
sumber
6

Tipe Antarmuka vs. Kelas Dasar Abstrak

Diadaptasi dari buku Pro C # 5.0 dan .NET 4.5 Framework .

Jenis antarmuka mungkin tampak sangat mirip dengan kelas dasar abstrak. Ingatlah bahwa ketika suatu kelas ditandai sebagai abstrak, ia dapat mendefinisikan sejumlah anggota abstrak untuk menyediakan antarmuka polimorfik untuk semua jenis turunan. Namun, bahkan ketika sebuah kelas mendefinisikan satu set anggota abstrak, itu juga bebas untuk menentukan sejumlah konstruktor, data lapangan, anggota nonabstrak (dengan implementasi), dan sebagainya. Antarmuka, di sisi lain, hanya berisi definisi anggota abstrak. Antarmuka polimorfik yang dibuat oleh kelas induk abstrak menderita dari satu batasan utama yaitu hanya tipe turunan yang mendukung anggota yang ditentukan oleh induk abstrak. Namun, dalam sistem perangkat lunak yang lebih besar, sangat umum untuk mengembangkan beberapa hierarki kelas yang tidak memiliki induk yang sama di luar System.Object. Mengingat bahwa anggota abstrak dalam kelas dasar abstrak hanya berlaku untuk tipe turunan, kami tidak memiliki cara untuk mengonfigurasi jenis dalam hierarki yang berbeda untuk mendukung antarmuka polimorfik yang sama. Sebagai contoh, anggap Anda telah mendefinisikan kelas abstrak berikut:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Dengan definisi ini, hanya anggota yang memperluas CloneableType yang dapat mendukung metode Clone (). Jika Anda membuat kumpulan kelas baru yang tidak memperluas kelas dasar ini, Anda tidak bisa mendapatkan antarmuka polimorfik ini. Juga, Anda mungkin ingat bahwa C # tidak mendukung multiple inheritance untuk kelas. Oleh karena itu, jika Anda ingin membuat MiniVan yang merupakan-Mobil dan merupakan-CloneableType, Anda tidak dapat melakukannya:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Seperti yang Anda tebak, tipe antarmuka datang untuk menyelamatkan. Setelah antarmuka didefinisikan, antarmuka dapat diimplementasikan oleh kelas atau struktur apa pun, dalam hierarki apa pun, dalam ruang nama apa pun atau perakitan apa pun (ditulis dalam bahasa pemrograman .NET apa pun). Seperti yang Anda lihat, antarmuka sangat polimorfik. Pertimbangkan antarmuka .NET standar bernama ICloneable, yang didefinisikan dalam System namespace. Antarmuka ini mendefinisikan metode tunggal bernama Clone ():

public interface ICloneable
{
object Clone();
}
Kata Roohullah Allem
sumber
6

Jawaban untuk pertanyaan kedua: publicvariabel didefinisikan dalam interfaceadalah static finalsecara default sedangkan publicvariabel di abstractkelas adalah variabel instansi.

Ravindra babu
sumber
6

Tentunya penting untuk memahami perilaku antarmuka dan kelas abstrak dalam OOP (dan bagaimana bahasa menanganinya), tetapi saya pikir juga penting untuk memahami apa arti setiap istilah. Bisakah Anda bayangkan ifperintah tidak bekerja persis seperti arti dari istilah itu? Juga, sebenarnya beberapa bahasa mengurangi, bahkan lebih lagi, perbedaan antara antarmuka dan abstrak ... jika suatu hari kedua istilah tersebut beroperasi hampir secara identik, setidaknya Anda dapat menentukan sendiri di mana (dan mengapa) salah satu dari mereka harus Digunakan untuk.

Jika Anda membaca beberapa kamus dan font lain, Anda mungkin menemukan arti berbeda untuk istilah yang sama tetapi memiliki beberapa definisi umum. Saya pikir dua makna yang saya temukan di situs ini benar-benar bagus dan cocok.

Antarmuka:

Suatu hal atau keadaan yang memungkinkan elemen yang terpisah dan kadang-kadang tidak kompatibel untuk berkoordinasi secara efektif.

Abstrak:

Sesuatu yang memusatkan pada dirinya sendiri kualitas-kualitas esensial dari sesuatu yang lebih luas atau lebih umum, atau dari beberapa hal; esensi.

Contoh:

Anda membeli mobil dan butuh bahan bakar.

masukkan deskripsi gambar di sini

Model mobil Anda adalah XYZ, yang bergenre ABC, jadi itu adalah mobil beton, contoh spesifik dari mobil. Mobil bukanlah benda nyata. Bahkan, itu adalah seperangkat standar abstrak (kualitas) untuk membuat objek tertentu. Singkatnya, Mobil adalah kelas abstrak , ini adalah "sesuatu yang memusatkan pada dirinya sendiri kualitas esensial dari sesuatu yang lebih luas atau lebih umum" .

Satu-satunya bahan bakar yang cocok dengan spesifikasi manual mobil harus digunakan untuk mengisi tangki mobil. Pada kenyataannya, tidak ada yang membatasi Anda untuk memasukkan bahan bakar tetapi mesin akan bekerja dengan baik hanya dengan bahan bakar yang ditentukan, jadi lebih baik untuk mengikuti persyaratannya. Persyaratan mengatakan bahwa ia menerima, seperti mobil lain dengan genre yang sama ABC, satu set bahan bakar standar.

Dalam tampilan Berorientasi Objek, bahan bakar untuk genre ABCtidak boleh dinyatakan sebagai kelas karena tidak ada bahan bakar konkret untuk genre mobil tertentu di luar sana. Meskipun mobil Anda dapat menerima Bahan Bakar kelas abstrak atau VehicularFuel, Anda harus ingat bahwa hanya bahan bakar kendaraan Anda saja yang memenuhi spesifikasi, yang menerapkan persyaratan dalam manual mobil Anda. Singkatnya, mereka harus mengimplementasikan antarmuka ABCGenreFuel , yang "... mengaktifkan elemen yang terpisah dan terkadang tidak kompatibel untuk berkoordinasi secara efektif" .

Tambahan

Selain itu, saya pikir Anda harus mengingat arti dari istilah kelas, yaitu (dari situs yang sama yang disebutkan sebelumnya):

Kelas:

Sejumlah orang atau benda dianggap membentuk kelompok dengan alasan atribut, karakteristik, kualitas, atau sifat yang sama; jenis;

Dengan cara ini, sebuah kelas (atau kelas abstrak) seharusnya tidak hanya mewakili atribut umum (seperti antarmuka), tetapi beberapa jenis grup dengan atribut umum. Antarmuka tidak perlu mewakili sejenis. Itu harus mewakili atribut umum. Dengan cara ini, saya pikir kelas dan kelas abstrak dapat digunakan untuk mewakili hal-hal yang seharusnya tidak sering mengubah aspeknya, seperti manusia sebagai mamalia, karena ia mewakili beberapa jenis. Jenis tidak boleh mengubah diri mereka sesering itu.

Felypp Oliveira
sumber
1
terlalu banyak bulu, jangan membuatnya terdengar lebih membingungkan orang daripada yang sudah mungkin terjadi.
ganjeii
5

Dari Coding Perspective

Antarmuka dapat menggantikan Kelas Abstrak jika Kelas Abstrak hanya memiliki metode abstrak. Kalau tidak mengubah kelas Abstrak ke antarmuka berarti bahwa Anda akan kehilangan kode re-usability yang disediakan Warisan.

Dari Perspektif Desain

Simpan sebagai Kelas Abstrak jika itu adalah hubungan "Apakah" dan Anda memerlukan subset atau semua fungsi. Simpan sebagai Antarmuka jika hubungan "Harus Dilakukan".

Putuskan apa yang Anda butuhkan: hanya penegakan kebijakan, atau penggunaan kembali kode DAN kebijakan.

Vivek Vermani
sumber
3

Beberapa perbedaan lain:

Kelas abstrak dapat memiliki metode statis, properti, bidang dll. Dan operator, antarmuka tidak bisa. Operator cor memungkinkan casting ke / dari kelas abstrak tetapi tidak mengizinkan casting ke / dari antarmuka.

Jadi cukup banyak Anda dapat menggunakan kelas abstrak sendiri bahkan jika itu tidak pernah diterapkan (melalui anggota statisnya) dan Anda tidak dapat menggunakan antarmuka sendiri dengan cara apa pun.

Orlin Petrov
sumber
di Java, antarmuka dapat memiliki variabel anggota tetapi secara default mereka menjadi statis publik. Jadi antarmuka dapat memiliki bidang statis
Jitendra Vispute
Ya antarmuka dapat memiliki bidang statis. TAPI antarmuka tidak dapat memiliki metode statis.
seorang Pembelajar