Dalam salah satu wawancara saya, saya telah diminta untuk menjelaskan perbedaan antara Antarmuka dan Abstrak kelas.
Berikut ini's tanggapan saya:
Metode antarmuka Jawa yang secara implisit abstrak dan tidak memiliki implementasi. Java kelas abstrak dapat memiliki contoh metode yang menerapkan standar perilaku.
Variabel yang dideklarasikan dalam Java interface secara default final. Aplikasi kelas abstrak dapat mengandung non-final variabel.
Anggota Java interface publik secara default. Java abstrak kelas dapat memiliki biasa rasa dari anggota kelas seperti swasta, dilindungi, dll.
Java interface harus diimplementasikan menggunakan kata kunci "mengimplementasikan"; A Java kelas abstrak harus diperluas menggunakan kata kunci "meluas".
antarmuka Yang dapat memperpanjang Java interface-satunya, sebuah kelas abstrak dapat memperpanjang lain Jawa kelas dan melaksanakan beberapa Java interface.
Java kelas dapat menerapkan beberapa interface tetapi dapat memperpanjang hanya satu kelas abstrak.
Namun, pewawancara tidak puas, dan mengatakan kepada saya bahwa deskripsi ini diwakili "ilmu pengetahuan".
Dia meminta saya untuk lebih praktis respon, menjelaskan ketika saya akan memilih sebuah kelas abstrak di atas sebuah interface, menggunakan contoh-contoh praktis.
Di mana aku pergi salah?
Saya akan memberikan contoh pertama:
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
Sekarang misalkan anda memiliki 3 database dalam aplikasi anda. Kemudian masing-masing dan setiap pelaksanaan untuk database yang perlu menetapkan atas 2 metode:
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
Tapi bagaimana jika encryptPassword() tidak tergantung database, dan's yang sama untuk masing-masing kelas? Kemudian di atas tidak akan menjadi pendekatan yang baik.
Sebaliknya, mempertimbangkan pendekatan ini:
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
Sekarang di masing-masing kelas anak, kita hanya perlu untuk menerapkan salah satu metode - metode yang tergantung database.
Saya mencoba yang terbaik dan Berharap ini akan menghapus keraguan anda.
Tidak ada yang sempurna di dunia ini. Mereka mungkin telah mengharapkan lebih dari sebuah pendekatan praktis.
Tapi setelah penjelasan anda, anda bisa menambahkan garis-garis ini dengan pendekatan yang sedikit berbeda.
Antarmuka aturan (aturan karena anda harus memberikan sebuah implementasi untuk mereka yang anda bisa't mengabaikan atau menghindari, sehingga mereka dikenakan seperti aturan) yang bekerja sebagai pemahaman umum dokumen antara berbagai tim dalam pengembangan perangkat lunak.
Antarmuka yang memberikan ide apa yang harus dilakukan tapi tidak bagaimana hal itu akan dilakukan. Sehingga pelaksanaannya benar-benar tergantung pada pengembang dengan mengikuti aturan yang diberikan (cara memberikan tanda tangan dari metode).
Abstrak kelas mungkin berisi abstrak deklarasi, implementasi beton, atau keduanya.
Abstrak deklarasi seperti aturan yang harus diikuti dan implementasi konkret seperti pedoman (anda dapat menggunakannya seperti itu atau anda dapat mengabaikannya dengan meng-override dan memberikan anda implementasi sendiri untuk itu).
Selain itu metode yang sama dengan tanda tangan dapat mengubah perilaku dalam berbagai konteks disediakan sebagai antarmuka deklarasi sebagai aturan untuk melaksanakan sesuai dalam konteks yang berbeda.
Edit: Jawa 8 memfasilitasi untuk menentukan default dan statis metode dalam interface.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
Sekarang ketika kelas akan melaksanakan SomeInterface, hal ini tidak wajib untuk menyediakan implementasi untuk metode default antarmuka.
Jika kita memiliki interface lain dengan cara sebagai berikut:
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Jawa tidak memungkinkan memperluas beberapa kelas karena hasil yang di "Diamond Masalah" mana kompilator tidak dapat memutuskan mana superclass metode yang digunakan. Dengan metode default, berlian masalah akan muncul interface juga. Karena jika kelas ini menerapkan
SomeInterfaceOne and SomeInterfaceTwo
dan tidak menerapkan standar umum metode, compiler tidak bisa memutuskan mana yang untuk memilih. Untuk menghindari masalah ini, di jawa 8 itu adalah wajib untuk menerapkan standar umum metode antarmuka yang berbeda. Jika ada kelas yang menerapkan kedua interface di atas, harus menyediakan implementasi untuk defaultMethod() metode jika tidak compiler akan membuang waktu kompilasi kesalahan.
Anda membuat ringkasan yang baik dari perbedaan praktis dalam penggunaan dan implementasi tapi tidak mengatakan apa-apa tentang perbedaan makna.
An antarmuka ini adalah deskripsi dari perilaku pelaksana kelas akan memiliki. Pelaksana kelas memastikan, bahwa ia akan memiliki metode-metode yang dapat digunakan di atasnya. Hal ini pada dasarnya kontrak atau janji kelas harus membuat.
An abstrak kelas adalah dasar dari subclass yang berbeda yang berbagi perilaku yang tidak perlu berulang kali dibuat. Subclass harus menyelesaikan perilaku dan memiliki opsi untuk mengganti perilaku yang telah ditetapkan (asalkan tidak didefinisikan sebagai final
atau pribadi
).
Anda akan menemukan contoh yang baik di jawa.utilpaket yang mencakup antarmuka seperti
Daftardan kelas abstrak seperti
AbstractListyang sudah mengimplementasikan interface. The [dokumentasi resmi][1] menjelaskan
AbstractList` sebagai berikut:
kelas Ini menyediakan kerangka pelaksanaan Daftar antarmuka untuk meminimalkan upaya yang diperlukan untuk mengimplementasikan interface ini didukung oleh "random access" data store (seperti array).
Antarmuka terdiri dari singleton variabel (public static final) dan semua metode abstrak. Biasanya kita lebih memilih untuk menggunakan antarmuka secara real time ketika kita tahu apa yang harus dilakukan tapi don't tahu bagaimana untuk melakukannya.
Konsep ini dapat dipahami dengan lebih baik dengan contoh:
Pertimbangkan untuk Pembayaran hotel. Pembayaran dapat dilakukan dengan berbagai cara, seperti PayPal, kartu kredit dll. Jadi kita biasanya mengambil Pembayaran sebagai antarmuka kami yang berisi makePayment()
metode dan kartu kredit dan PayPal adalah dua implementasi kelas-kelas.
public interface Payment
{
void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
public void makePayment()
{
//some logic for PayPal payment
//e.g. Paypal uses username and password for payment
}
}
public class CreditCard implements Payment
{
public void makePayment()
{
//some logic for CreditCard payment
//e.g. CreditCard uses card number, date of expiry etc...
}
}
Dalam contoh di atas kartu kredit dan PayPal adalah dua implementasi kelas /strategi. Interface juga memungkinkan kita konsep multiple inheritance pada Java yang tidak dapat dicapai oleh sebuah kelas abstrak.
Kami memilih sebuah kelas abstrak ketika ada beberapa fitur yang kami tahu apa yang harus dilakukan, dan fitur lain yang kita tahu bagaimana untuk melakukan.
Perhatikan contoh berikut:
public abstract class Burger
{
public void packing()
{
//some logic for packing a burger
}
public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
public void price()
{
//set price for a veg burger.
}
}
public class NonVegBerger extends Burger
{
public void price()
{
//set price for a non-veg burger.
}
}
Jika kita menambahkan metode (beton/abstrak) di masa depan yang diberikan kelas abstrak, maka pelaksanaan kelas tidak perlu mengubah kode. Namun, jika kita menambahkan metode dalam sebuah antarmuka di masa depan, kita harus menambahkan implementasi untuk semua kelas yang dilaksanakan itu interface, jika tidak, waktu kompilasi kesalahan yang terjadi.
Ada perbedaan lain tapi ini adalah yang utama yang mungkin telah apa yang anda pewawancara diharapkan . Mudah-mudahan ini sangat membantu.
Jawa 8 perubahan antarmuka mencakup metode statis dan metode default di interface. Sebelum Java 8, kita bisa memiliki-satunya metode deklarasi di antarmuka. Tapi dari Jawa 8, kita dapat memiliki default metode dan statis metode dalam interface.
Setelah memperkenalkan Metode Standar, tampaknya bahwa antarmuka dan abstrak kelas yang sama. Namun, mereka masih berbeda konsep di Jawa 8.
kelas Abstrak dapat mendefinisikan konstruktor. Mereka lebih terstruktur dan dapat memiliki sebuah negara yang terkait dengan mereka. Sementara sebaliknya, default metode dapat diimplementasikan hanya dalam hal memohon lain antarmuka metode, dengan tidak ada referensi untuk implementasi tertentu's negara. Oleh karena itu, keduanya digunakan untuk tujuan yang berbeda dan memilih di antara dua benar-benar tergantung pada skenario konteks. Perbedaan Konseptual:
Abstrak kelas yang valid untuk skeletal (yaitu parsial) implementasi antarmuka tapi tidak harus ada tanpa antarmuka yang cocok. Jadi ketika abstrak kelas yang efektif dikurangi menjadi rendah visibilitas, rangka implementasi antarmuka, dapat default mengambil metode ini jauh juga? Jelas: Tidak Ada! Mengimplementasikan interface hampir selalu memerlukan beberapa atau semua dari orang-orang kelas-alat bangunan yang default metode kurangnya. Dan jika beberapa antarmuka tidak, hal ini jelas merupakan kasus khusus, yang seharusnya tidak menyesatkan anda. Antarmuka Default Metode di Jawa 8
Jawa 8 memperkenalkan "Default Metode" atau (Bek metode) fitur baru, yang memungkinkan pengembang untuk menambahkan metode baru untuk Antarmuka tanpa melanggar ada implementasi dari Antarmuka. Hal ini memberikan fleksibilitas untuk memungkinkan Antarmuka mendefinisikan implementasi yang akan digunakan sebagai default dalam situasi di mana beton Kelas gagal untuk memberikan sebuah implementasi untuk metode tersebut. Mari perhatikan contoh kecil untuk memahami cara kerjanya:
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
Berikut Kelas yang akan mengkompilasi berhasil di Java JDK 8,
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
Jika anda membuat sebuah instance dari OldInterfaceImpl:
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
Default metode yang tidak pernah final, tidak bisa disinkronkan dan tidak dapat menimpa Objek metode. Mereka selalu publik, yang sangat membatasi kemampuan untuk menulis pendek dan metode dapat digunakan kembali. Default metode yang dapat disediakan untuk sebuah Antarmuka tanpa mempengaruhi implementasi kelas-Kelas seperti itu termasuk implementasi. Jika masing-masing ditambahkan metode dalam sebuah Antarmuka yang didefinisikan dengan implementasi kemudian tidak melaksanakan Kelas terpengaruh. Pelaksana Kelas dapat mengganti default implementasi yang disediakan oleh Antarmuka. metode Default memungkinkan untuk menambahkan fungsi baru yang ada Interface tanpa melanggar lebih tua implementasi Antarmuka ini. Ketika kami memperluas antarmuka yang berisi metode standar, kita dapat melakukan langkah berikut,
- Tidak override metode standar dan akan mewarisi metode standar.
- Mengganti default metode yang mirip dengan metode lain kita override di subclass.
Redeclare metode standar seperti yang abstrak, yang berlaku untuk subclass menimpa.
ForEach metode kesalahan kompilasi diselesaikan dengan menggunakan Metode Standar
Untuk Java 8, JDK koleksi telah diperpanjang dan forEach metode ini ditambahkan ke seluruh koleksi (yang bekerja dalam hubungannya dengan lambdas). Dengan cara konvensional, kode seperti di bawah ini,
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
Karena ini hasil setiap pelaksanaan Kelas dengan mengkompilasi kesalahan oleh karena itu, metode standar ditambahkan dengan implementasinya dibutuhkan agar ada implementasi tidak harus diubah. The Interface Iterable dengan metode Standar adalah di bawah ini,
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
Sejak Kelas java dapat menerapkan beberapa Interface dan masing-masing Interface dapat menentukan default metode dengan metode yang sama tanda tangan, oleh karena itu, metode turunan dapat konflik dengan satu sama lain. Perhatikan contoh di bawah ini,
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
Kode di atas akan gagal untuk mengkompilasi dengan error berikut,
jawa: kelas Impl mewarisi terkait default untuk defaultMethod() dari jenis InterfaceA dan InterfaceB Dalam rangka untuk memperbaiki kelas ini, kita perlu untuk memberikan standar metode pelaksanaan:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
Selanjutnya, jika kita ingin memanggil implementasi default yang disediakan oleh super Antarmuka daripada kita sendiri implementasinya, kita dapat melakukannya sebagai berikut,
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
Antarmuka Java Metode Statis, kode contoh, metode statis vs default metode Jawa antarmuka statis metode ini mirip dengan metode standar kecuali bahwa kita tidak bisa mengesampingkan mereka dalam pelaksanaan kelas. Fitur ini membantu kita dalam menghindari hasil yang tidak diinginkan memetikan miskin implementasi dalam implementasi kelas-kelas. Mari kita melihat ke dalam ini dengan contoh sederhana.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
Sekarang mari kita lihat sebuah implementasi kelas yang memiliki isNull() metode dengan implementasi yang buruk.
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
Perhatikan bahwa isNull(String str) adalah sederhana metode kelas, itu tidak mengesampingkan antarmuka metode. Misalnya, jika kita akan menambahkan @Override penjelasan untuk isNull() metode, maka akan mengakibatkan kesalahan kompiler. Sekarang ketika kita akan menjalankan aplikasi, kita mendapatkan output sebagai berikut.
Antarmuka Null Check
Impl Null Check Jika kita membuat antarmuka metode dari statis ke default, kita akan mendapatkan output sebagai berikut. Impl Null Check
MyData Cetak::
Impl Null Check Jawa antarmuka statis metode ini terlihat dengan antarmuka metode saja, jika kita menghapus isNull() method dari MyDataImpl kelas, kita tidak akan dapat menggunakannya untuk MyDataImpl objek. Namun seperti yang lain metode statis, kita dapat menggunakan antarmuka statis metode yang menggunakan nama kelas. Misalnya, pernyataan yang benar akan:
boolean result = MyData.isNull("abc");
@FunctionalInterface
telah diperkenalkan untuk menandai sebuah antarmuka Fungsional Antarmuka. @FunctionalInterface
anotasi adalah fasilitas untuk menghindari kecelakaan penambahan abstrak metode fungsional antarmuka. Ini adalah opsional, tetapi praktik yang baik untuk menggunakannya.
Fungsional antarmuka yang lama ditunggu dan banyak dicari fitur dari Jawa 8 karena hal ini memungkinkan kita untuk menggunakan ekspresi lambda untuk instantiate mereka. Paket baru jawa.util.fungsi dengan sekelompok fungsional antarmuka ditambahkan untuk memberikan jenis target untuk ekspresi lambda dan metode referensi. Kami akan melihat ke fungsional antarmuka dan ekspresi lambda dalam posting masa depan.
Sumber Lokasi: Semua pernyataan anda adalah sah kecuali pernyataan pertama (setelah Jawa 8 release):
Metode antarmuka Jawa yang secara implisit abstrak dan tidak memiliki implementasi
Dari dokumentasi halaman:
Sebuah antarmuka adalah referensi jenis, mirip dengan kelas, yang dapat berisi hanya konstanta, metode tanda tangan, default metode, metode statis,dan bersarang jenis
Metode badan yang ada hanya untuk default metode statis dan metode.
Default metode:
Sebuah antarmuka dapat memiliki metode default, tetapi berbeda dari metode abstrak abstrak di kelas.
metode Default memungkinkan anda untuk menambahkan fungsi baru untuk antarmuka dari perpustakaan anda dan memastikan kompatibilitas biner dengan kode yang ditulis untuk versi yang lebih tua dari interface-interface tersebut.
Ketika anda memperluas antarmuka yang berisi metode standar, anda dapat melakukan hal-hal berikut:
abstrak
.Metode Statis:
Selain metode default, anda dapat menentukan statis metode dalam interface. (Metode statis adalah metode yang berhubungan dengan kelas di mana ia didefinisikan bukan dengan objek apapun. Setiap instance dari kelas berbagi metode statis.)
Hal ini membuat lebih mudah bagi anda untuk mengatur metode pembantu di perpustakaan;
Contoh kode dari halaman dokumentasi tentang antarmuka
memiliki statis
dan default
metode.
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
static ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Gunakan pedoman di bawah ini untuk memilih apakah akan menggunakan antarmuka atau kelas abstrak.
Interface:
Kelas abstrak:
Berbagi kode antara beberapa erat terkait kelas. Menetapkan adalah hubungan.
Berbagi umum negara antara terkait kelas ( negara dapat dimodifikasi dalam beton kelas)
Posting terkait:
https://stackoverflow.com/questions/761194/interface-vs-abstract-class-general-oo/33963650#33963650
Dengan pergi melalui contoh-contoh ini, anda dapat memahami bahwa
Terkait kelas dapat memiliki kemampuan melalui antarmuka tapi kelas terkait perubahan perilaku melalui perpanjangan dari kelas dasar.
Penjelasan anda terlihat baik, tapi mungkin itu tampak seperti anda sudah membaca itu semua dari sebuah buku? :-/
Apa yang saya'm lebih peduli tentang adalah, seberapa kuat anda contoh? Apa kau repot-repot untuk memasukkan hampir semua perbedaan antara abstrak dan interface?
Secara pribadi, saya akan menunjukkan link ini: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
untuk daftar lengkap dari perbedaan..
Semoga membantu anda dan semua pembaca lainnya di masa depan mereka wawancara
Junior banyak pengusaha yang membuat kesalahan dengan berpikir interface, abstrak dan konkret kelas sebagai sedikit variasi dari hal yang sama, dan memilih salah satu dari mereka murni alasan teknis: Apakah saya perlu beberapa warisan? Apakah saya membutuhkan beberapa tempat untuk menempatkan metode umum? Apakah saya perlu untuk repot-repot dengan sesuatu yang lain dari sekedar beton kelas? Ini adalah salah, dan tersembunyi dalam pertanyaan-pertanyaan ini adalah masalah utama: "aku". Ketika anda menulis kode untuk diri sendiri, oleh diri sendiri, anda jarang berpikir lainnya sekarang atau masa depan pengembang yang bekerja pada atau dengan kode anda. Interface dan kelas abstrak, meskipun tampaknya sama dari sudut pandang teknis, memiliki arti yang sama sekali berbeda dan tujuan.
Untuk menempatkan hal yang berbeda: beton kelas melakukan pekerjaan yang sebenarnya, dalam cara yang sangat spesifik. Misalnya, sebuah ArrayList
menggunakan bersebelahan area memori untuk menyimpan daftar objek secara kompak yang menawarkan cepat akses acak, iterasi, dan di tempat-perubahan, tapi mengerikan di insersi, penghapusan, dan kadang-kadang bahkan penambahan; sementara itu, LinkedList
menggunakan double-linked node untuk menyimpan daftar benda-benda yang bukan menawarkan cepat iterasi, di tempat perubahan, dan penyisipan/penghapusan/penambahan, tapi mengerikan di akses acak. Kedua jenis daftar yang dioptimalkan untuk kasus penggunaan yang berbeda, dan banyak hal bagaimana anda're akan menggunakannya. Bila anda're mencoba untuk memeras kinerja dari daftar yang anda're berat berinteraksi dengan, dan ketika memilih jenis dari daftar anda, anda harus hati-hati memilih mana yang anda're instantiating.
Di sisi lain, tingkat tinggi pengguna dari daftar don't benar-benar peduli bagaimana hal itu benar-benar dilaksanakan, dan mereka harus terisolasi dari rincian ini. Let's membayangkan bahwa Jawa didn't mengekspos Daftar
antarmuka, tetapi hanya punya beton Daftar
kelas yang's benar-benar apa yang LinkedList
sekarang. Semua pengembang Java akan disesuaikan kode mereka untuk menyesuaikan rincian pelaksanaan: menghindari akses acak, menambahkan cache untuk mempercepat akses, atau hanya diimplementasikan kembali ArrayList
pada mereka sendiri, meskipun akan kompatibel dengan semua kode lain yang benar-benar bekerja dengan Daftar
saja. Itu akan sangat mengerikan... Tapi sekarang bayangkan bahwa Jawa masters benar-benar menyadari bahwa linked list adalah mengerikan untuk sebagian besar sebenarnya kasus penggunaan, dan memutuskan untuk beralih ke array daftar untuk mereka hanya Daftar
kelas yang tersedia. Hal ini akan mempengaruhi kinerja dari setiap program Java di dunia, dan orang-orang yang tidak't menjadi bahagia tentang hal itu. Dan penyebab utama adalah bahwa rincian pelaksanaan yang tersedia, dan pengembang diasumsikan bahwa mereka rincian kontrak permanen bahwa mereka dapat bergantung pada. Ini adalah mengapa hal itu's penting untuk menyembunyikan implementasi detail, dan hanya unggul abstrak kontrak. Ini adalah tujuan dari sebuah antarmuka: menentukan jenis input metode yang menerima, dan apa output yang diharapkan, tanpa mengekspos semua keberanian yang akan menggoda programmer untuk mengubah kode mereka untuk menyesuaikan rincian internal yang dapat berubah-ubah dengan masa depan pembaruan.
Sebuah kelas abstrak adalah di tengah-tengah antara antarmuka dan beton kelas. Hal ini seharusnya untuk membantu implementasi berbagi umum atau membosankan kode. Misalnya, AbstractCollection
memberikan dasar implementasi untuk isEmpty
berdasarkan ukuran 0, berisi
seperti iterate dan bandingkan, addAll
seperti yang berulang add
, dan sebagainya. Hal ini memungkinkan implementasi yang fokus pada bagian-bagian penting yang membedakan antara mereka: bagaimana untuk benar-benar menyimpan dan mengambil data.
Antarmuka rendah kohesi gateway antara bagian yang berbeda dari kode. Mereka memungkinkan perpustakaan untuk eksis dan berkembang tanpa melanggar setiap pengguna perpustakaan ketika sesuatu perubahan secara internal. It's disebut Aplikasi Pemrograman Antarmuka, bukan Aplikasi Pemrograman Kelas. Pada skala yang lebih kecil, mereka juga memungkinkan beberapa pengembang untuk berkolaborasi berhasil pada proyek-proyek skala besar, dengan memisahkan modul yang berbeda melalui didokumentasikan dengan baik antarmuka.
Abstrak kelas tinggi kohesi pembantu untuk digunakan ketika mengimplementasikan sebuah interface, dengan asumsi beberapa tingkat rincian pelaksanaan. Selain itu, abstrak kelas yang digunakan untuk mendefinisikan SPIs, Penyedia Layanan Interface.
Perbedaan antara API dan SPI adalah halus, tapi penting: untuk API, fokusnya adalah pada siapa menggunakan itu, dan untuk SPI fokus pada siapa yang alat itu.
Menambahkan metode untuk API mudah, semua pengguna yang ada dari API masih akan mengkompilasi. Menambahkan metode SPI sulit, karena setiap penyedia layanan (implementasi konkret) akan memiliki untuk menerapkan metode-metode baru. Jika interface yang digunakan untuk mendefinisikan sebuah SPI, penyedia akan memiliki untuk merilis versi baru setiap kali SPI perubahan kontrak. Jika abstrak kelas yang digunakan sebagai gantinya, metode baru bisa dapat didefinisikan dalam hal ada metode abstrak, atau sebagai kosong membuang tidak dilaksanakan kecuali
rintisan, yang setidaknya akan memungkinkan versi yang lebih tua dari pelaksanaan pelayanan masih mengkompilasi dan menjalankan.
Meskipun Jawa 8 diperkenalkan metode default untuk interface, yang membuat garis antara interface dan kelas abstrak bahkan blurrier, ini bukan't sehingga implementasi dapat menggunakan kembali kode, tapi untuk membuatnya lebih mudah untuk mengubah antarmuka yang berfungsi baik sebagai API dan sebagai SPI (atau salah digunakan untuk mendefinisikan SPIs bukan abstrak kelas).
Rincian teknis yang disediakan di OP's jawaban yang dianggap "buku pengetahuan" karena ini biasanya pendekatan yang digunakan di sekolah dan dalam kebanyakan buku-buku tentang teknologi bahasa: apa a hal ini, tidak bagaimana untuk menggunakannya dalam praktek, terutama dalam aplikasi skala besar. Berikut ini's sebuah analogi: seharusnya pertanyaan itu:
Apa yang lebih baik untuk menyewa untuk prom night, mobil atau kamar hotel? Jawaban teknis kedengarannya seperti: Nah, di dalam mobil anda dapat melakukannya lebih cepat, tapi di sebuah kamar hotel, anda dapat melakukannya dengan lebih nyaman. Di sisi lain, kamar hotel ini hanya dalam satu tempat, sementara di mobil anda dapat melakukannya di lebih banyak tempat, seperti, let's mengatakan anda dapat pergi ke vista point untuk tampilan yang bagus, atau di sebuah drive-in teater, atau banyak tempat-tempat lain, atau bahkan di lebih dari satu tempat. Juga, hotel ini memiliki kamar mandi. Itu semua benar, tapi benar-benar merindukan poin yang mereka benar-benar dua hal yang berbeda, dan keduanya dapat digunakan pada waktu yang sama untuk tujuan yang berbeda, dan "tidak melakukan itu," aspek ini bukan hal yang paling penting tentang salah satu dari dua pilihan. Jawabannya tidak memiliki perspektif, hal itu menunjukkan belum matang cara berpikir, sementara benar menghadirkan benar "fakta".
Sebuah antarmuka adalah "kontrak" di mana kelas yang mengimplementasikan kontrak berjanji untuk menerapkan metode. Contoh di mana saya harus menulis sebuah antarmuka yang bukan dari kelas adalah ketika saya meng-upgrade permainan dari 2D ke 3D. Aku harus membuat sebuah antarmuka untuk berbagi kelas antara 2D dan 3D versi dari permainan.
package adventure;
import java.awt.*;
public interface Playable {
public void playSound(String s);
public Image loadPicture(String s);
}
Kemudian saya dapat menerapkan metode-metode yang berbasis pada lingkungan, sementara masih mampu untuk memanggil metode-metode dari objek yang doesn't tahu versi dari permainan yang sedang loading.
public class Petualangan extends JFrame implements Dimainkan
public class Dungeon3D meluas SimpleApplication mengimplementasikan Dimainkan
public class Main extends SimpleApplication mengimplementasikan AnimEventListener, ActionListener, Dimainkan
Biasanya, di gameworld, dunia dapat menjadi sebuah kelas abstrak yang melakukan metode permainan:
public abstract class World...
public Playable owner;
public Playable getOwner() {
return owner;
}
public void setOwner(Playable owner) {
this.owner = owner;
}
Bagaimana berpikir dengan cara berikut:
Jadi, ketika anda memiliki sebuah kelas abstrak Mamalia, sebuah subclass Manusia, dan sebuah antarmuka Mengemudi, maka anda bisa mengatakan
Saran saya adalah bahwa buku pengetahuan frase yang menunjukkan bahwa dia ingin mendengar perbedaan semantik antara keduanya (seperti orang lain di sini sudah disarankan).
Abstrak kelas tidak abstraksi murni bcz koleksi beton(menerapkan metode) serta diimplementasikan metode. Tapi Interface adalah abstraksi murni bcz ada hanya diimplementasikan metode tidak beton metode.
Mengapa Abstrak kelas?
Mengapa Interface?
An antarmuka adalah seperti satu set gen yang umum didokumentasikan untuk memiliki beberapa jenis efek: tes DNA akan memberitahu saya apakah saya've punya mereka - dan jika saya lakukan, saya dapat membuat publik itu diketahui bahwa I'm "operator" dan bagian dari perilaku saya atau negara akan sesuai dengan mereka. (Tapi tentu saja, saya mungkin memiliki banyak gen lain yang memberikan sifat-sifat yang luar lingkup ini.)
An abstrak kelas seperti nenek moyang mati dari single-seks spesies(): Dia dapat't akan dibawa untuk hidup tapi hidup (yaitu, non-abstrak*) keturunan mewarisi semua gen-nya.
(*) Untuk meregangkan metafora ini, let's mengatakan semua anggota spesies yang hidup sampai usia yang sama. Ini berarti semua leluhur dari nenek moyang mati juga harus mati - dan demikian juga, semua keturunan dari hidup nenek moyang yang harus tetap hidup.
Anda memilih Interface di Java untuk menghindari Diamond Masalah di multiple inheritance.
Jika anda ingin semua metode yang akan dilaksanakan oleh klien anda anda pergi untuk antarmuka. Itu berarti anda desain seluruh aplikasi di abstrak.
Anda memilih kelas abstrak jika anda sudah tahu apa kesamaan. Misalnya Mengambil sebuah kelas abstrak Mobil
. Pada tingkat yang lebih tinggi anda menerapkan mobil umum metode seperti calculateRPM()
. Ini adalah metode umum dan anda biarkan klien menerapkan perilaku sendiri seperti
calculateMaxSpeed()
dll. Mungkin anda akan menjelaskan dengan memberikan beberapa real time contoh-contoh yang anda jumpai dalam sehari-hari pekerjaan.
Saya melakukan wawancara untuk bekerja dan saya akan terlihat tidak baik pada jawaban anda juga (maaf tapi aku sangat jujur). Itu tidak terdengar seperti anda'telah membaca tentang perbedaan dan direvisi jawaban tapi mungkin anda belum pernah digunakan dalam praktek.
Penjelasan yang baik mengapa anda akan menggunakan masing-masing dapat menjadi jauh lebih baik daripada memiliki penjelasan yang tepat dari perbedaan. Pengusaha ultimatley ingin berlisensi uji coba untuk melakukan hal-hal yang tidak tahu mereka yang dapat sulit untuk menunjukkan dalam sebuah wawancara. Jawaban yang anda berikan akan lebih baik jika melamar teknis atau dokumentasi berdasarkan pekerjaan tetapi tidak seorang pengembang peran.
Best of luck dengan wawancara di masa depan.
Juga jawaban saya untuk pertanyaan ini adalah lebih lanjut tentang teknik wawancara daripada materi teknis youve yang disediakan. Mungkin mempertimbangkan membaca tentang hal itu. https://workplace.stackexchange.com/ dapat menjadi tempat yang sangat baik untuk hal semacam ini.
Perbedaan utama yang saya amati adalah bahwa kelas abstrak menyediakan kita dengan beberapa perilaku umum sudah dilaksanakan dan subclass hanya perlu mengimplementasikan fungsi tertentu yang sesuai untuk mereka. di mana untuk sebuah antarmuka hanya akan menentukan tugas-tugas apa yang harus dilakukan dan tidak ada implementasi yang akan diberikan oleh interface. Saya dapat mengatakan itu menentukan kontrak antara dirinya dan diimplementasikan di kelas.
Bahkan saya telah menghadapi pertanyaan yang sama dalam beberapa wawancara dan saya percaya itu membuat waktu anda sengsara untuk meyakinkan pewawancara. Jika saya melekat semua jawaban di atas maka saya perlu menambahkan satu lagi titik kunci untuk membuatnya lebih meyakinkan dan memanfaatkan OO yang terbaik
Dalam kasus anda tidak perencanaan modifikasi dalam aturan , untuk subclass yang harus diikuti, untuk masa depan yang panjang, pergi untuk antarmuka, anda tidak dapat memodifikasi dan jika anda melakukannya, anda perlu untuk pergi untuk perubahan di semua sub kelas, sedangkan, jika anda berpikir, anda ingin menggunakan kembali fungsi, menetapkan beberapa aturan dan juga membuatnya terbuka untuk modifikasi, pergi untuk kelas Abstrak.
Berpikir dengan cara ini, anda telah menggunakan layanan konsumsi atau anda telah memberikan beberapa kode untuk dunia dan Anda memiliki kesempatan untuk mengubah sesuatu, misalkan cek keamanan Dan Jika saya menjadi konsumen dari kode dan Suatu pagi setelah update , saya menemukan semua tanda baca dalam Eclipse, seluruh aplikasi ke bawah. Jadi untuk mencegah mimpi buruk, penggunaan Abstrak lebih dari Interface
Saya pikir ini mungkin meyakinkan Pewawancara untuk tingkat...Senang Wawancara di Depan.
Ketika saya mencoba untuk berbagi perilaku antara 2 berkaitan erat kelas, saya membuat sebuah class abstrak yang memegang perilaku umum dan berfungsi sebagai orang tua untuk kedua kelas.
Ketika saya mencoba untuk mendefinisikan Tipe, daftar metode yang pengguna objek saya dipercaya bisa memanggil, maka saya membuat sebuah antarmuka.
Misalnya, saya tidak akan pernah membuat sebuah kelas abstrak dengan 1 beton subclass karena abstrak kelas tentang pembagian perilaku. Tapi aku mungkin sangat baik membuat antarmuka dengan hanya satu implementasi. Pengguna dari kode saya tidak't tahu bahwa hanya ada satu implementasi. Memang, di masa mendatang mungkin ada beberapa implementasi, yang semuanya adalah subclass dari beberapa kelas abstrak yang tidak't bahkan ada ketika saya buat antarmuka.
Yang mungkin tampak sedikit terlalu kutu buku juga (meskipun aku belum pernah melihat itu menempatkan bahwa cara di mana saja yang saya ingat). Jika pewawancara (atau OP) benar-benar ingin lebih dari pengalaman pribadi saya itu, saya akan telah siap dengan anekdot dari sebuah antarmuka telah berkembang dari kebutuhan dan sebaliknya.
Satu hal lagi. Jawa 8 sekarang memungkinkan anda untuk menempatkan kode default ke antarmuka, lebih lanjut mengaburkan line antara interface dan kelas abstrak. Tapi dari apa yang saya lihat, fitur itu adalah berlebihan bahkan oleh pembuat Java core libraries. Fitur yang ditambahkan, dan memang demikian, untuk membuat itu mungkin untuk memperpanjang sebuah antarmuka tanpa menciptakan biner ketidakcocokan. Tapi jika anda membuat Jenis baru dengan mendefinisikan sebuah antarmuka, kemudian antarmuka harus HANYA sebuah antarmuka. Jika anda ingin juga memberikan kode umum, maka dengan segala cara membuat sebuah kelas helper (abstrak atau konkret). Don't akan mengacaukan antarmuka anda dari awal dengan fungsi yang anda mungkin ingin mengubah.
Perbedaan mendasar antara interface dan abstract class, interface mendukung multiple inheritance tapi kelas abstrak tidak.
Di kelas abstrak juga anda dapat memberikan semua metode abstrak seperti antarmuka.
mengapa kelas abstrak diperlukan?
Dalam beberapa skenario, saat memproses permintaan pengguna, kelas abstrak doesn't tahu apa niat pengguna. Dalam skenario itu, kami akan menentukan satu metode abstrak dalam kelas dan meminta pengguna yang memperluas kelas ini, silakan memberikan anda maksud dalam metode abstrak. Dalam hal ini kelas abstrak yang sangat berguna
Mengapa antarmuka yang diperlukan?
Let's mengatakan, saya punya pekerjaan yang saya don't memiliki pengalaman di daerah itu. Contoh, jika anda ingin membangun sebuah bangunan atau bendungan, maka apa yang akan anda lakukan dalam skenario itu?
Di sini saya don't repot-repot tentang logika bagaimana mereka dibangun. Akhir objek puas dengan kebutuhan saya atau tidak, itu hanya saya titik kunci.
Di sini anda persyaratan disebut antarmuka dan konstruktor dipanggil implementor.
Di kelas abstrak, anda dapat menulis standar pelaksanaan metode! Tapi dalam Antarmuka yang anda tidak bisa. Pada dasarnya, Dalam antarmuka yang ada murni virtual metode yang harus diimplementasikan oleh class yang mengimplementasikan interface.