Bagaimana seharusnya saya menjelaskan perbedaan antara Interface dan kelas Abstrak?

469

Dalam salah satu wawancara saya, saya diminta untuk menjelaskan perbedaan antara Interface dan kelas Abstrak .

Inilah tanggapan saya:

Metode antarmuka Java secara implisit abstrak dan tidak dapat memiliki implementasi. Kelas abstrak Java dapat memiliki metode instan yang mengimplementasikan perilaku default.

Variabel yang dideklarasikan dalam antarmuka Java secara default final. Kelas abstrak dapat berisi variabel non-final.

Anggota antarmuka Java bersifat publik secara default. Kelas abstrak Java dapat memiliki cita rasa anggota kelas seperti privat, dilindungi, dll.

Antarmuka Java harus diimplementasikan menggunakan kata kunci "implement"; Kelas abstrak Java harus diperluas menggunakan kata kunci "extends".

Antarmuka hanya dapat memperluas antarmuka Java lainnya, kelas abstrak dapat memperluas kelas Java lainnya dan mengimplementasikan beberapa antarmuka Java.

Kelas Java dapat mengimplementasikan banyak antarmuka tetapi hanya dapat memperluas satu kelas abstrak.

Namun, pewawancara tidak puas, dan mengatakan kepada saya bahwa deskripsi ini mewakili " pengetahuan kutu buku ".

Dia meminta saya untuk tanggapan yang lebih praktis, menjelaskan kapan saya akan memilih kelas abstrak dari sebuah antarmuka, menggunakan contoh-contoh praktis .

Di mana saya salah?

Pemikir
sumber
32
Mungkin jawaban Anda sepertinya Anda mengatakan sesuatu yang tidak Anda mengerti? Bisa jadi Anda hanya perlu mengubah gaya bercerita menjadi sesuatu yang lebih mirip kata-kata Anda sendiri.
Kirill Kobelev
19
Anda menjawab dengan daftar (cukup benar) perbedaan teknis. Pewawancara kemungkinan besar mencari jawaban yang lebih konseptual (misalnya, atas dasar apa seseorang akan memilih antara menggunakan antarmuka dan kelas abstrak).
Ted Hopp
15
Anda lupa mengatakan bahwa kelas abstrak memiliki konstruktor, meskipun Anda tidak dapat membuat instance kelas abstrak, const. digunakan oleh kelas anak. Antarmuka menunjukkan "apa" tetapi tidak "bagaimana" karena mereka mendefinisikan kontrak (daftar metode) saat abst. kelas juga dapat menunjukkan "bagaimana" (menerapkan met.). Menggunakan int. Anda dapat meniru multiple inheritance (kelas dapat mengimplementasikan multiple int. tetapi hanya memperpanjang satu kelas). Menggunakan int. Anda dapat memiliki tipe dasar untuk dif. keluarga: Flyer f = Pesawat baru (); Flyer f2 = Burung baru (); Bird and Plane tidak sesuai dengan famili yang sama tetapi keduanya dapat terbang (adalah flyer).
Francisco Goldenstein
7
Pada antarmuka java8 dapat berisi metode .. jadi di luar konsep OO ini yang disebut "perbedaan" dapat berubah setiap hari.
pembawa cincin
15
Saya tidak punya masalah dengan jawaban Anda, dan saya pikir pewawancara tidak punya urusan untuk mencibir 'pengetahuan buku'. Pewawancara tidak selalu tahu jawaban yang benar untuk pertanyaan yang mereka ajukan, dan beberapa wawancara hanya berfungsi untuk memperingatkan Anda agar tidak bekerja di sana.
Marquis of Lorne

Jawaban:

513

Saya akan memberi Anda contoh pertama:

public interface LoginAuth{
   public String encryptPassword(String pass);
   public void checkDBforUser();
}

Misalkan Anda memiliki 3 database dalam aplikasi Anda. Maka setiap implementasi untuk database itu perlu mendefinisikan 2 metode di atas:

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
}

Tetapi bagaimana jika encryptPassword()tidak tergantung pada basis data, dan itu sama untuk setiap kelas? Maka hal di atas tidak akan menjadi pendekatan yang baik.

Sebagai gantinya, pertimbangkan 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 setiap kelas anak, kita hanya perlu menerapkan satu metode - metode yang bergantung pada basis data.

Bera Vimal
sumber
97
Saya tidak yakin ini benar-benar menjelaskan perbedaan ... pasti itu teknik yang bagus. Saya kira itu juga layak menunjukkan bahwa Java 8 akhirnya mengakui bahwa C ++ benar dan beberapa pewarisan dapat dilakukan dan dapat digunakan dan antarmuka sekarang dapat mendefinisikan tidak hanya tanda tangan fungsi tetapi juga menyediakan implementasi standar. Karena itu, lebih baik menggunakan antarmuka.
thecoshman
1
@thecoshman Apa bedanya jika saya mendekati masalah seperti pada jawabannya (kelas abstrak dengan satu metode diimplementasikan dan abstrak lainnya) atau mendefinisikan antarmuka dengan implementasi metode default? Pada dasarnya, apa yang ingin saya katakan adalah bahwa Anda menulis bahwa 'menggunakan antarmuka akan lebih disukai' dan pertanyaan saya adalah - mengapa?
Neutrino
1
Jadi, saya kira itu adil untuk mengatakan bahwa dengan antarmuka, implementasi dari apa yang telah didefinisikan sampai ke kelas yang benar-benar mengimplementasikan antarmuka, sedangkan hal-hal dalam kelas abstrak adalah "inti" untuk kelas yang memperluas kelas; yaitu, itu tidak berubah.
orrymr
4
@Neutrino Meskipun Java memungkinkan Anda untuk mengimplementasikan beberapa antarmuka, masing-masing menawarkan implementasi standar untuk fungsi, Anda masih dapat memperluas satu kelas saja. Dengan demikian, menggunakan antarmuka dapat memberikan lebih banyak fleksibilitas bagi mereka yang ingin menggunakannya, bersama dengan antarmuka lainnya.
thecoshman
3
@HiradNikoo Maaf atas komentar terlambat, tapi saya baru saja menemukan utas ini. Anda juga dapat menganggap warisan kelas sebagai hubungan IS-A, sedangkan antarmuka menandakan "memiliki fungsi tertentu".
Alexander Jank
206

Tidak ada yang sempurna di dunia ini. Mereka mungkin mengharapkan lebih dari pendekatan praktis.

Tetapi setelah penjelasan Anda, Anda dapat menambahkan baris-baris ini dengan pendekatan yang sedikit berbeda.

  1. Antarmuka adalah aturan (aturan karena Anda harus memberikan implementasi kepada mereka yang tidak dapat Anda abaikan atau hindari, sehingga diberlakukan seperti aturan) yang berfungsi sebagai dokumen pemahaman bersama di antara berbagai tim dalam pengembangan perangkat lunak.

  2. Antarmuka memberikan ide apa yang harus dilakukan tetapi tidak bagaimana itu akan dilakukan. Jadi implementasi sepenuhnya tergantung pada pengembang dengan mengikuti aturan yang diberikan (artinya diberikan tanda tangan metode).

  3. Kelas abstrak dapat berisi deklarasi abstrak, implementasi konkret, atau keduanya.

  4. Deklarasi abstrak seperti aturan yang harus diikuti dan implementasi konkret seperti panduan (Anda dapat menggunakannya sebagaimana adanya atau Anda dapat mengabaikannya dengan menimpa dan memberikan implementasi Anda sendiri padanya).

  5. Selain itu metode mana dengan tanda tangan yang sama dapat mengubah perilaku dalam konteks yang berbeda disediakan sebagai deklarasi antarmuka sebagai aturan untuk diterapkan sesuai dalam konteks yang berbeda.

Sunting: Java 8 memudahkan untuk mendefinisikan metode default dan statis di antarmuka.

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

Sekarang ketika sebuah kelas akan mengimplementasikan SomeInterface, itu tidak wajib untuk memberikan implementasi untuk metode antarmuka standar.

Jika kami memiliki antarmuka lain dengan metode berikut:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java tidak mengizinkan perluasan beberapa kelas karena menghasilkan "Masalah Berlian" di mana kompiler tidak dapat memutuskan metode superclass mana yang akan digunakan. Dengan metode default, masalah berlian akan muncul untuk antarmuka juga. Karena jika suatu kelas mengimplementasikan keduanya

SomeInterfaceOne and SomeInterfaceTwo

dan tidak menerapkan metode standar umum, kompiler tidak dapat memutuskan mana yang akan dipilih. Untuk menghindari masalah ini, di java 8 itu wajib untuk menerapkan metode standar umum dari antarmuka yang berbeda. Jika ada kelas yang mengimplementasikan kedua antarmuka di atas, itu harus menyediakan implementasi untuk metode defaultMethod () jika tidak, kompiler akan membuang kesalahan waktu kompilasi.

Shailesh Saxena
sumber
11
+1, ini benar-benar jawaban yang baik untuk menghindari kebingungan. Tapi saya tidak melihat tautan apa pun dan tidak tahu mengapa Anda mengutip kalimat-kalimat berharga itu. Jadikan sebagai poin jika memungkinkan :).
Suresh Atta
Baca komentar saya di atas tentang meniru beberapa pewarisan menggunakan antarmuka dan menggunakan antarmuka untuk memiliki tipe dasar untuk kelas keluarga yang berbeda. Saya pikir pewawancara ingin mendengar jawaban seperti itu dari yang diwawancarai.
Francisco Goldenstein
Komentar Anda juga menunjukkan contoh penggunaan antarmuka yang baik. Saya menulis, apa yang saya rasakan saat bekerja sehari-hari. Kata-kata ini mungkin tidak profesional atau akurat. Tapi itu yang saya tahu setelah bekerja erat dengan kelas abstrak & antarmuka dalam coding harian saya.
Shailesh Saxena
4. Implementasi konkret juga merupakan aturan, memiliki implementasi standar.
Luten
@ Luten: Sesuai pengetahuan saya, Jika Anda dapat menghindari / mengabaikan aturan tanpa masalah, itu harus menjadi pedoman, bukan aturan. Tolong koreksi saya jika saya salah.
Shailesh Saxena
168

Anda membuat ringkasan yang baik tentang perbedaan praktis dalam penggunaan dan implementasi tetapi tidak mengatakan apa-apa tentang perbedaan makna.

Sebuah antarmuka adalah deskripsi dari perilaku kelas pelaksana akan memiliki. Kelas implementasi memastikan, bahwa ia akan memiliki metode ini yang dapat digunakan di dalamnya. Itu pada dasarnya adalah kontrak atau janji yang harus dibuat kelas.

Sebuah kelas abstrak adalah dasar untuk subclass yang berbeda bahwa perilaku saham yang tidak perlu berulang kali dibuat. Subclass harus menyelesaikan perilaku dan memiliki opsi untuk mengesampingkan perilaku yang telah ditentukan (selama itu tidak didefinisikan sebagai finalatau private).

Anda akan menemukan contoh-contoh bagus dalam java.utilpaket yang menyertakan antarmuka seperti Listdan kelas abstrak seperti AbstractListyang sudah mengimplementasikan antarmuka. The dokumentasi resmi menjelaskan AbstractListsebagai berikut:

Kelas ini menyediakan implementasi kerangka dari antarmuka Daftar untuk meminimalkan upaya yang diperlukan untuk mengimplementasikan antarmuka ini yang didukung oleh penyimpanan data "akses acak" (seperti array).

Daniel Lerps
sumber
16
Ini seharusnya jawabannya. Bukan daftar detail, tetapi konsep dasar yang membuat perbedaan antara antarmuka dan kelas abstrak, tidak hanya di Jawa tetapi secara umum.
edc65
1
Ini sangat bagus. Tentu saja jawaban orang lain juga bagus. Tapi ini memberi tahu Anda informasi utama tentang abstractkata kunci, yaitu ketika kompiler melihat ini, mereka tahu, informasi berikut tidak lengkap dan membutuhkan implementasi . Antarmuka selalu tidak lengkap, tetapi kelas abstrak adalah abstrak karena mereka harus memiliki incomplete (abstract)metode.
Rakib
85

Antarmuka terdiri dari variabel singleton (public static final) dan metode abstrak publik. Kami biasanya lebih suka menggunakan antarmuka secara real time ketika kami tahu apa yang harus dilakukan tetapi tidak tahu bagaimana melakukannya .

Konsep ini dapat lebih dipahami dengan contoh:

Pertimbangkan kelas Pembayaran. Pembayaran dapat dilakukan dengan banyak cara, seperti PayPal, kartu kredit, dll. Jadi kami biasanya mengambil Pembayaran sebagai antarmuka kami yang berisi makePayment()metode dan CreditCard dan PayPal adalah dua kelas implementasi.

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 CreditCard dan PayPal adalah dua kelas / strategi implementasi. Antarmuka juga memungkinkan kita konsep pewarisan berganda di Jawa yang tidak dapat diselesaikan oleh kelas abstrak.

Kami memilih kelas abstrak ketika ada beberapa fitur yang kami tahu harus melakukan apa, dan fitur lain yang kami tahu caranya .

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 (konkret / abstrak) di masa depan ke kelas abstrak yang diberikan, maka kelas implementasi tidak perlu mengubah kode-kodenya. Namun, jika kita menambahkan metode di antarmuka di masa mendatang, kita harus menambahkan implementasi ke semua kelas yang mengimplementasikan antarmuka itu, jika tidak, kompilasi kesalahan waktu terjadi.

Ada perbedaan lain tetapi ini adalah perbedaan besar yang mungkin seperti yang diharapkan pewawancara Anda. Semoga ini bermanfaat.

Satya
sumber
1
Baiklah, jawaban ini sangat masuk akal, dan cukup jelas dengan contohnya, ketika kita memilih antara interfacedan abstract class.
MAC
"apa yang harus dilakukan tetapi tidak tahu bagaimana melakukannya" ketika kita mendefinisikan sebuah metode tanpa membuat implementasi apa pun di dalamnya "void makePayment ();", sembari mendefinisikan implementasi metode di kelas yang akan mengimplementasikan antarmuka.
Abdel-Raouf
45

Perbedaan antara kelas Abstact dan antarmuka

  1. Kelas abstrak versus antarmuka di Java 8
  2. Perbedaan Konseptual:

Metode Default Antarmuka di Java 8

  1. Apa itu Metode Default?
  2. Kesalahan kompilasi metode ForEach diselesaikan menggunakan Metode Default
  3. Metode Default dan Beberapa Masalah Ambiguitas Warisan
  4. Poin penting tentang metode default antarmuka java:

Metode Statis Antarmuka Java

  1. Metode Antarmuka Java Interface, contoh kode, metode statis vs metode standar
  2. Poin penting tentang metode statis antarmuka java:

Antarmuka Fungsional Java



Kelas abstrak versus antarmuka di Java 8

Java 8 perubahan antarmuka termasuk metode statis dan metode default di antarmuka. Sebelum Java 8, kita hanya bisa menggunakan deklarasi metode di antarmuka. Tetapi dari Java 8, kita dapat memiliki metode default dan metode statis di antarmuka.

Setelah memperkenalkan Metode Default, tampaknya antarmuka dan kelas abstrak sama. Namun, konsep mereka masih berbeda di Jawa 8.

Kelas abstrak dapat mendefinisikan konstruktor. Mereka lebih terstruktur dan dapat memiliki keadaan yang terkait dengannya. Sebaliknya, metode default hanya dapat diimplementasikan dalam hal memanggil metode antarmuka lainnya, tanpa referensi ke kondisi implementasi tertentu. Oleh karena itu, keduanya digunakan untuk tujuan yang berbeda dan memilih di antara keduanya benar-benar tergantung pada konteks skenario.

Perbedaan Konseptual:

Kelas abstrak berlaku untuk implementasi skeletal (yaitu parsial) dari antarmuka tetapi tidak boleh ada tanpa antarmuka yang cocok.

Jadi ketika kelas abstrak secara efektif direduksi menjadi visibilitas rendah, implementasi kerangka antarmuka, dapatkah metode standar juga mengambilnya? Jelas: Tidak! Menerapkan antarmuka hampir selalu membutuhkan beberapa atau semua alat pembangun kelas yang kurang dimiliki metode standar. Dan jika beberapa antarmuka tidak, itu jelas merupakan kasus khusus, yang seharusnya tidak membuat Anda tersesat.

Metode Default Antarmuka di Java 8

Java 8 memperkenalkan " Metode Default " atau (metode Defender) fitur baru, yang memungkinkan pengembang untuk menambahkan metode baru ke Antarmuka tanpa merusak implementasi Antarmuka yang ada. Ini memberikan fleksibilitas untuk memungkinkan Interface mendefinisikan implementasi yang akan digunakan sebagai default dalam situasi di mana Kelas konkret gagal menyediakan implementasi untuk metode itu.

Mari kita 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");
    }
}

Kelas berikut akan berhasil dikompilasi di Java JDK 8,

public class OldInterfaceImpl implements OldInterface {
    public void existingMethod() {
     // existing implementation is here…
    }
}

Jika Anda membuat instance dari OldInterfaceImpl:

OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod(); 

Metode Bawaan:

Metode default tidak pernah final, tidak dapat disinkronkan dan tidak bisa menimpa metode Object. Mereka selalu bersifat publik, yang sangat membatasi kemampuan untuk menulis metode pendek dan dapat digunakan kembali.

Metode default dapat diberikan ke Antarmuka tanpa memengaruhi Kelas implementasi karena mencakup implementasi. Jika setiap metode ditambahkan dalam Interface yang didefinisikan dengan implementasi maka tidak ada Kelas pelaksana yang terpengaruh. Kelas pelaksana dapat mengganti implementasi default yang disediakan oleh Antarmuka.

Metode default memungkinkan untuk menambahkan fungsionalitas baru ke Antarmuka yang ada tanpa melanggar implementasi yang lebih lama dari Antarmuka ini.

Saat kami memperluas antarmuka yang berisi metode default, kami dapat melakukan yang berikut,

  1. Tidak mengganti metode default dan akan mewarisi metode default.
  2. Timpa metode default yang serupa dengan metode lain yang kami timpa dalam subkelas.
  3. Redeclare metode default sebagai abstrak, yang memaksa subclass untuk menimpanya.

Kesalahan kompilasi metode ForEach diselesaikan menggunakan Metode Default

Untuk Java 8, koleksi JDK telah diperluas dan metode forEach ditambahkan ke seluruh koleksi (yang bekerja bersama dengan lambdas). Dengan cara konvensional, kode tersebut terlihat seperti di bawah ini,

public interface Iterable<T> {
    public void forEach(Consumer<? super T> consumer);
}

Karena hasil ini setiap Kelas pelaksana dengan kesalahan kompilasi, metode default ditambahkan dengan implementasi yang diperlukan agar implementasi yang ada tidak boleh diubah.

Antarmuka Iterable dengan metode Default di bawah ini,

public interface Iterable<T> {
    public default void forEach(Consumer
                   <? super T> consumer) {
        for (T t : this) {
            consumer.accept(t);
        }
    }
}

Mekanisme yang sama telah digunakan untuk menambahkan Stream di Antarmuka JDK tanpa melanggar Kelas pelaksana.


Metode Default dan Beberapa Masalah Ambiguitas Warisan

Karena Kelas java dapat mengimplementasikan beberapa Antarmuka dan setiap Antarmuka dapat menentukan metode default dengan metode tanda tangan yang sama, oleh karena itu, metode yang diwariskan dapat saling bertentangan.

Pertimbangkan 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 dikompilasi dengan kesalahan berikut,

java: class Impl mewarisi default yang tidak terkait untuk defaultMethod () dari jenis InterfaceA dan InterfaceB

Untuk memperbaiki kelas ini, kita perlu menyediakan implementasi metode default:

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
    }
}

Lebih lanjut, jika kita ingin menjalankan implementasi default yang disediakan oleh salah satu Antarmuka super daripada implementasi kita sendiri, kita dapat melakukannya sebagai berikut,

public class Impl implements InterfaceA, InterfaceB {
    public void defaultMethod(){
        // existing code here..
        InterfaceA.super.defaultMethod();
    }
}

Kami dapat memilih implementasi default atau keduanya sebagai bagian dari metode baru kami.

Poin penting tentang metode default antarmuka java:

  1. Metode default antarmuka Java akan membantu kami dalam memperluas antarmuka tanpa takut merusak kelas implementasi.
  2. Metode standar antarmuka Java telah menjembatani perbedaan antara antarmuka dan kelas abstrak.
  3. Metode standar antarmuka Java 8 akan membantu kita menghindari kelas utilitas, seperti semua metode kelas Koleksi dapat disediakan di antarmuka itu sendiri.
  4. Metode standar antarmuka Java akan membantu kami dalam menghapus kelas implementasi dasar, kami dapat memberikan implementasi standar dan kelas implementasi dapat memilih mana yang akan ditimpa.
  5. Salah satu alasan utama untuk memperkenalkan metode default di antarmuka adalah untuk meningkatkan API Koleksi di Jawa 8 untuk mendukung ekspresi lambda.
  6. Jika ada kelas dalam hierarki memiliki metode dengan tanda tangan yang sama, maka metode standar menjadi tidak relevan. Metode default tidak dapat menggantikan metode dari java.lang.Object. Alasannya sangat sederhana, itu karena Object adalah kelas dasar untuk semua kelas java. Jadi, bahkan jika kita memiliki metode kelas Objek didefinisikan sebagai metode default di antarmuka, itu akan sia-sia karena metode kelas Objek akan selalu digunakan. Itu sebabnya untuk menghindari kebingungan, kita tidak dapat memiliki metode default yang menimpa metode kelas Objek.
  7. Metode default antarmuka Java juga disebut sebagai Metode Defender atau metode ekstensi Virtual.

Tautan Sumber Daya:

  1. Antarmuka dengan metode default vs kelas Abstrak di Java 8
  2. Kelas abstrak versus antarmuka di era JDK 8
  3. Evolusi antarmuka melalui metode ekstensi virtual

Metode Statis Antarmuka Java

Metode Antarmuka Java Interface, contoh kode, metode statis vs metode standar

Metode statis antarmuka Java mirip dengan metode default kecuali bahwa kita tidak bisa menimpanya di kelas implementasi. Fitur ini membantu kita menghindari hasil yang tidak diinginkan jika implementasi buruk di kelas implementasi. Mari kita lihat 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 kelas implementasi yang memiliki metode isNull () 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 metode kelas sederhana, itu tidak mengesampingkan metode antarmuka. Sebagai contoh, jika kita akan menambahkan anotasi @Override ke metode isNull (), itu akan menghasilkan kesalahan kompiler.

Sekarang ketika kita akan menjalankan aplikasi, kita mendapatkan output berikut.

Antarmuka Null Check

Impl Null Check

Jika kita membuat metode antarmuka dari statis ke default, kita akan mendapatkan output berikut.

Impl Null Check

MyData Print ::

Impl Null Check

Metode statis antarmuka Java hanya dapat dilihat oleh metode antarmuka, jika kita menghapus metode isNull () dari kelas MyDataImpl, kita tidak akan dapat menggunakannya untuk objek MyDataImpl. Namun seperti metode statis lainnya, kita dapat menggunakan metode statis antarmuka menggunakan nama kelas. Misalnya, pernyataan yang valid adalah:

boolean result = MyData.isNull("abc");

Poin penting tentang metode statis antarmuka java:

  1. Metode statis antarmuka Java adalah bagian dari antarmuka, kita tidak dapat menggunakannya untuk objek implementasi kelas.
  2. Metode statis antarmuka Java baik untuk menyediakan metode utilitas, misalnya cek kosong, penyortiran koleksi, dll.
  3. Metode statis antarmuka Java membantu kami menyediakan keamanan dengan tidak mengizinkan kelas implementasi menimpa mereka.
  4. Kita tidak dapat mendefinisikan metode statis antarmuka untuk metode kelas Objek, kita akan mendapatkan kesalahan kompiler sebagai "Metode statis ini tidak dapat menyembunyikan metode contoh dari Objek". Ini karena itu tidak diizinkan di java, karena Object adalah kelas dasar untuk semua kelas dan kita tidak dapat memiliki satu metode statis tingkat kelas dan metode contoh lain dengan tanda tangan yang sama.
  5. Kita dapat menggunakan metode statis antarmuka java untuk menghapus kelas utilitas seperti Koleksi dan memindahkan semua metode statis itu ke antarmuka yang sesuai, yang akan mudah ditemukan dan digunakan.

Antarmuka Fungsional Java

Sebelum saya menyimpulkan posting, saya ingin memberikan pengantar singkat untuk antarmuka Fungsional. Antarmuka dengan tepat satu metode abstrak dikenal sebagai Antarmuka Fungsional.

Anotasi baru @FunctionalInterfacetelah diperkenalkan untuk menandai antarmuka sebagai Antarmuka Fungsional. @FunctionalInterfaceanotasi adalah fasilitas untuk menghindari penambahan metode abstrak yang tidak disengaja dalam antarmuka fungsional. Ini opsional tetapi praktik yang baik untuk menggunakannya.

Antarmuka fungsional sudah lama ditunggu dan banyak dicari fitur Java 8 karena memungkinkan kita untuk menggunakan ekspresi lambda untuk instantiate mereka. Paket java.util.function baru dengan banyak antarmuka fungsional ditambahkan untuk menyediakan tipe target untuk ekspresi lambda dan referensi metode. Kami akan melihat antarmuka fungsional dan ekspresi lambda di posting mendatang.

Lokasi Sumber Daya:

  1. Java 8 Interface Changes - metode statis, metode standar
SkyWalker
sumber
8
Saya benar-benar mencari jenis jawaban yang diperbarui ini. Terima kasih atas tanggapan yang cepat.
Ravindra babu
41

Semua pernyataan Anda valid kecuali pernyataan pertama Anda (setelah rilis Java 8):

Metode antarmuka Java secara implisit abstrak dan tidak dapat memiliki implementasi

Dari halaman dokumentasi :

Antarmuka adalah tipe referensi, mirip dengan kelas, yang hanya dapat berisi konstanta, tanda tangan metode, metode default, metode statis, dan tipe bertingkat

Badan metode hanya ada untuk metode default dan metode statis.

Metode standar:

Antarmuka dapat memiliki metode default , tetapi berbeda dari metode abstrak di kelas abstrak.

Metode default memungkinkan Anda untuk menambahkan fungsionalitas baru ke antarmuka perpustakaan Anda dan memastikan kompatibilitas biner dengan kode yang ditulis untuk versi yang lebih lama dari antarmuka tersebut.

Saat Anda memperluas antarmuka yang berisi metode default, Anda dapat melakukan hal berikut:

  1. Tidak menyebutkan metode default sama sekali, yang memungkinkan antarmuka Anda yang diperluas mewarisi metode default.
  2. Deklarasikan ulang metode default, yang membuatnya abstract.
  3. Tetapkan ulang metode default, yang menimpanya.

Metode Statis:

Selain metode default, Anda dapat menentukan metode statis di antarmuka. (Metode statis adalah metode yang dikaitkan dengan kelas di mana ia didefinisikan daripada dengan objek apa pun. Setiap instance kelas berbagi metode statisnya.)

Ini memudahkan Anda untuk mengatur metode pembantu di perpustakaan Anda;

Contoh kode dari halaman dokumentasi tentang interfacememiliki staticdan defaultmetode.

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.

Antarmuka:

  1. Untuk menentukan kontrak (lebih disukai tanpa kewarganegaraan - maksud saya tidak ada variabel)
  2. Untuk menghubungkan kelas yang tidak terkait dengan memiliki kemampuan.
  3. Untuk mendeklarasikan variabel konstanta publik ( state immutable )

Kelas abstrak:

  1. Bagikan kode di antara beberapa kelas yang terkait erat. Itu menetapkan adalah suatu hubungan.

  2. Berbagi keadaan umum di antara kelas terkait (negara dapat dimodifikasi dalam kelas beton)

Posting terkait:

Antarmuka vs Kelas Abstrak (OO umum)

Implements vs extends: Kapan digunakan? Apa bedanya?

Dengan melihat contoh-contoh ini, Anda dapat memahaminya

Kelas yang tidak terkait dapat memiliki kemampuan melalui antarmuka tetapi kelas terkait mengubah perilaku melalui ekstensi kelas dasar.

Ravindra babu
sumber
Apa maksud Anda mengatakan "kontrak tanpa kewarganegaraan"? Ini item 1 tentang antarmuka
Maksim Dmitriev
1
Tidak adanya keadaan yang bisa berubah. Karena antarmuka dapat memiliki konstanta, data dapat dimutasi tidak seperti kelas abstrak
Ravindra babu
1
Koreksi dalam pernyataan di atas. Dalam antarmuka, data tidak dapat dimutasi seperti kelas abstrak
Ravindra babu
2
ini jawaban terbaik Tidak hanya mengatasi Java8, tetapi juga menjelaskan dalam situasi tertentu apa Anda akan menggunakan salah satunya.
Shuklaswag
Konsep statelessdalam antarmuka adalah hit yang bagus. Antarmuka tidak dapat memiliki keadaan apa pun (Antarmuka dapat memiliki konstanta tetapi bersifat final / statis sehingga tidak dapat diubah).
Kaihua
22

Penjelasan Anda terlihat bagus, tetapi mungkin itu terlihat seperti Anda membaca semuanya dari buku teks? : - /

Yang lebih saya pedulikan adalah, seberapa solid contoh Anda? Apakah Anda repot-repot memasukkan hampir semua perbedaan antara abstrak dan antarmuka?

Secara pribadi, saya akan menyarankan tautan ini: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

untuk daftar perbedaan lengkap ..

Semoga ini membantu Anda dan semua pembaca lainnya dalam wawancara di masa depan

VictorCreator
sumber
1
tautan dibagikan benar-benar luar biasa
Premraj
Anda dapat memberikan implementasi default di antarmuka java menggunakan kata kunci default
Ogen
21

Banyak pengembang junior membuat kesalahan dengan memikirkan antarmuka, kelas abstrak dan konkret sebagai sedikit variasi dari hal yang sama, dan memilih salah satunya murni dengan alasan teknis: Apakah saya memerlukan banyak pewarisan? Apakah saya perlu tempat untuk meletakkan metode umum? Apakah saya perlu repot dengan sesuatu selain kelas yang konkret? Ini salah, dan tersembunyi dalam pertanyaan-pertanyaan ini adalah masalah utama: "Saya" . Ketika Anda menulis kode untuk diri sendiri, Anda jarang memikirkan pengembang lain saat ini atau di masa depan yang sedang mengerjakan atau dengan kode Anda.

Antarmuka dan kelas abstrak, meskipun tampaknya serupa dari sudut pandang teknis, memiliki arti dan tujuan yang sama sekali berbeda.

Ringkasan

  1. Antarmuka mendefinisikan kontrak yang beberapa implementasi akan memenuhi untuk Anda .

  2. Kelas abstrak menyediakan perilaku default yang dapat digunakan kembali oleh implementasi Anda .

Dua poin di atas adalah yang saya cari saat wawancara, dan merupakan ringkasan yang cukup ringkas. Baca terus untuk detail lebih lanjut.

Ringkasan alternatif

  1. Antarmuka adalah untuk mendefinisikan API publik
  2. Kelas abstrak adalah untuk penggunaan internal, dan untuk mendefinisikan SPI

Contohnya

Dengan kata lain: Kelas konkret melakukan pekerjaan yang sebenarnya, dengan cara yang sangat spesifik. Sebagai contoh, sebuah ArrayListmenggunakan area memori yang berdekatan untuk menyimpan daftar objek dalam cara yang kompak yang menawarkan akses acak cepat, iterasi, dan perubahan di tempat, tetapi mengerikan dalam penyisipan, penghapusan, dan kadang-kadang bahkan penambahan; sementara itu, aLinkedListmenggunakan node yang terhubung ganda untuk menyimpan daftar objek, yang sebaliknya menawarkan iterasi cepat, perubahan di tempat, dan penyisipan / penghapusan / penambahan, tetapi mengerikan pada akses acak. Kedua jenis daftar ini dioptimalkan untuk berbagai kasus penggunaan, dan sangat penting bagaimana Anda akan menggunakannya. Saat Anda mencoba memeras kinerja dari daftar yang sangat berinteraksi dengan Anda, dan ketika memilih jenis daftar terserah Anda, Anda harus hati-hati memilih yang mana yang Anda instantiating.

Di sisi lain, pengguna tingkat tinggi dari daftar tidak benar-benar peduli bagaimana itu sebenarnya diterapkan, dan mereka harus diisolasi dari perincian ini. Mari kita bayangkan bahwa Java tidak mengekspos Listantarmuka, tetapi hanya memiliki Listkelas nyata yang sebenarnya LinkedListsekarang. Semua pengembang Java akan menyesuaikan kodenya agar sesuai dengan detail implementasi: hindari akses acak, tambahkan cache untuk mempercepat akses, atau cukup implementasi ulang ArrayListsendiri, meskipun itu tidak sesuai dengan semua kode lain yang Listhanya berfungsi dengan baik . Itu akan mengerikan ... Tapi sekarang bayangkan bahwa master Java benar-benar menyadari bahwa daftar tertaut mengerikan untuk sebagian besar kasus penggunaan aktual, dan memutuskan untuk beralih ke daftar array hanya untuk merekaListkelas tersedia. Ini akan memengaruhi kinerja setiap program Java di dunia, dan orang-orang tidak akan senang karenanya. Dan penyebab utamanya adalah detail implementasi tersedia, dan pengembang berasumsi bahwa detail itu adalah kontrak permanen yang dapat mereka andalkan. Inilah sebabnya mengapa penting untuk menyembunyikan detail implementasi, dan hanya mendefinisikan kontrak abstrak. Ini adalah tujuan dari sebuah antarmuka: tentukan input apa yang diterima suatu metode, dan output seperti apa yang diharapkan, tanpa memaparkan semua nyali yang akan menggoda programmer untuk mengubah kode mereka agar sesuai dengan detail internal yang mungkin berubah dengan pembaruan di masa mendatang. .

Kelas abstrak berada di tengah-tengah antara antarmuka dan kelas konkret. Seharusnya membantu implementasi berbagi kode umum atau membosankan. Misalnya, AbstractCollectionmemberikan implementasi dasar untuk isEmptyberdasarkan ukuran adalah 0, containsseperti iterate dan bandingkan, addAllseperti diulang add, dan sebagainya. Ini memungkinkan implementasi fokus pada bagian-bagian penting yang membedakan di antara mereka: bagaimana sebenarnya menyimpan dan mengambil data.

Perspektif lain: API versus SPI

Antarmuka adalah gateway kohesi rendah antara berbagai bagian kode. Mereka memungkinkan perpustakaan ada dan berkembang tanpa merusak setiap pengguna perpustakaan ketika sesuatu berubah secara internal. Ini disebut Antarmuka Pemrograman Aplikasi , bukan Kelas Pemrograman Aplikasi. Pada skala yang lebih kecil, mereka juga memungkinkan banyak pengembang untuk berkolaborasi dengan sukses pada proyek-proyek skala besar, dengan memisahkan berbagai modul melalui antarmuka yang terdokumentasi dengan baik.

Kelas abstrak adalah pembantu kohesi tinggi yang akan digunakan saat mengimplementasikan antarmuka, dengan asumsi beberapa tingkat detail implementasi. Atau, kelas abstrak digunakan untuk mendefinisikan SPI, Antarmuka Penyedia Layanan.

Perbedaan antara API dan SPI adalah halus, tetapi penting: untuk API, fokusnya adalah pada siapa yang menggunakannya , dan untuk SPI fokusnya adalah pada siapa yang mengimplementasikannya .

Menambahkan metode ke API mudah, semua pengguna API yang ada masih akan dikompilasi. Menambahkan metode ke SPI sulit, karena setiap penyedia layanan (implementasi konkret) harus menerapkan metode baru. Jika antarmuka digunakan untuk mendefinisikan SPI, penyedia harus merilis versi baru setiap kali kontrak SPI berubah. Jika kelas abstrak digunakan sebagai gantinya, metode baru dapat didefinisikan dalam hal metode abstrak yang ada, atau sebagai throw not implemented exceptionbertopik kosong , yang setidaknya akan memungkinkan versi yang lebih lama dari implementasi layanan untuk tetap dikompilasi dan dijalankan.

Catatan tentang Java 8 dan metode default

Meskipun Java 8 memperkenalkan metode default untuk antarmuka, yang membuat garis antara antarmuka dan kelas abstrak bahkan lebih blurrier, ini bukan agar implementasi dapat menggunakan kembali kode, tetapi untuk membuatnya lebih mudah untuk mengubah antarmuka yang berfungsi baik sebagai API dan sebagai SPI (atau salah digunakan untuk mendefinisikan SPI, bukan kelas abstrak).

"Pengetahuan buku"

Rincian teknis yang diberikan dalam jawaban OP dianggap "pengetahuan buku" karena ini biasanya pendekatan yang digunakan di sekolah dan di sebagian besar buku teknologi tentang bahasa: apa itu, bukan bagaimana menggunakannya dalam praktik, terutama dalam aplikasi skala besar .

Inilah analogi: seharusnya pertanyaannya adalah:

Apa yang lebih baik untuk disewa untuk malam prom, mobil atau kamar hotel?

Jawaban teknisnya seperti:

Nah, di mobil Anda bisa melakukannya lebih cepat, tetapi di kamar hotel Anda bisa melakukannya dengan lebih nyaman. Di sisi lain, kamar hotel hanya di satu tempat, sementara di mobil Anda dapat melakukannya di lebih banyak tempat, seperti, katakanlah Anda dapat pergi ke titik pemandangan untuk pemandangan yang indah, atau di teater drive-in, atau banyak tempat lain, atau bahkan di lebih dari satu tempat. Juga, kamar hotel memiliki shower.

Itu semua benar, tetapi sepenuhnya merindukan poin bahwa mereka adalah dua hal yang sama sekali berbeda, dan keduanya dapat digunakan pada saat yang sama untuk tujuan yang berbeda, dan aspek "melakukannya" bukanlah hal yang paling penting tentang salah satu dari dua opsi tersebut. . Jawabannya tidak memiliki perspektif, itu menunjukkan cara berpikir yang tidak matang, sementara benar menyajikan "fakta".

Sergiu Dumitriu
sumber
Apakah maksud Anda "kopling rendah"?
user2418306
@ user2418306 Tidak, kohesi adalah istilah yang lebih umum yang mencakup kopling, meskipun keduanya sinonim, dan salah satu istilah itu akan berfungsi.
Sergiu Dumitriu
9

Bagaimana dengan berpikir dengan cara berikut:

  • Hubungan antara kelas dan kelas abstrak bertipe "is-a"
  • Hubungan antara kelas dan antarmuka bertipe "has-a"

Jadi ketika Anda memiliki kelas abstrak Mamalia, Manusia subkelas, dan antarmuka Mengemudi, maka Anda bisa mengatakan

  • setiap manusia adalah mamalia
  • setiap Manusia memiliki-a Mengemudi (perilaku)

Saran saya adalah ungkapan pengetahuan buku menunjukkan bahwa ia ingin mendengar perbedaan semantik antara keduanya (seperti yang sudah disarankan orang lain di sini).

akohout
sumber
9

Antarmuka adalah "kontrak" di mana kelas yang mengimplementasikan kontrak berjanji untuk mengimplementasikan metode. Contoh di mana saya harus menulis antarmuka bukan kelas adalah ketika saya meningkatkan permainan dari 2D ke 3D. Saya harus membuat antarmuka untuk berbagi kelas antara versi 2D dan 3D game.

package adventure;
import java.awt.*;
public interface Playable {
    public void playSound(String s);
    public Image loadPicture(String s);    
}

Lalu saya bisa menerapkan metode yang didasarkan pada lingkungan, sementara masih bisa memanggil metode-metode dari objek yang tidak tahu versi permainan yang memuat.

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable

Biasanya, di gameworld, dunia bisa menjadi kelas abstrak yang melakukan metode pada permainan:

public abstract class World...

    public Playable owner;

    public Playable getOwner() {
        return owner;
    }

    public void setOwner(Playable owner) {
        this.owner = owner;
    }
Niklas R.
sumber
6

Kelas abstrak bukan abstraksi murni karena koleksi betonnya (metode yang diterapkan) serta metode yang tidak diterapkan. Tetapi Antarmuka adalah abstraksi murni karena hanya ada metode yang tidak diimplementasikan bukan metode konkret.

Mengapa kelas abstrak?

  1. Jika pengguna ingin menulis fungsionalitas umum untuk semua objek.
  2. Kelas abstrak adalah pilihan terbaik untuk implementasi ulang di masa depan yang menambahkan lebih banyak fungsi tanpa mempengaruhi pengguna akhir.

Mengapa Antarmuka?

  1. Jika pengguna ingin menulis fungsionalitas yang berbeda, itu akan menjadi fungsionalitas yang berbeda pada objek.
  2. Antarmuka adalah pilihan terbaik yang jika tidak perlu mengubah persyaratan setelah antarmuka telah diterbitkan.
Sarfaraz Ahamad
sumber
5

Sebuah antarmuka seperti satu set gen yang didokumentasikan publik untuk memiliki beberapa jenis efek: tes A DNA akan memberitahu saya apakah saya punya mereka - dan jika saya lakukan, saya secara terbuka dapat membuatnya diketahui bahwa aku seorang "pembawa "Dan sebagian dari perilaku atau keadaan saya akan sesuai dengan mereka. (Tapi tentu saja, saya mungkin memiliki banyak gen lain yang memberikan sifat di luar lingkup ini.)

Sebuah kelas abstrak seperti nenek moyang mati dari spesies tunggal-seks (*): Dia tidak dapat dibawa ke kehidupan, tetapi hidup (yaitu non-abstrak ) mewarisi keturunan semua gen-nya.

(*) Untuk meregangkan metafora ini, katakanlah semua anggota spesies hidup pada usia yang sama. Ini berarti semua leluhur leluhur yang mati juga harus mati - dan demikian pula, semua keturunan leluhur yang hidup haruslah hidup.

Steve Chambers
sumber
4

Saya melakukan wawancara untuk bekerja dan saya akan melihat jawaban Anda juga tidak baik (maaf tapi saya sangat jujur). Kedengarannya seperti Anda telah membaca tentang perbedaan dan merevisi jawaban, tetapi mungkin Anda belum pernah menggunakannya dalam praktik.

Penjelasan yang baik tentang mengapa Anda akan menggunakan masing-masing bisa jauh lebih baik daripada memiliki penjelasan yang tepat tentang perbedaannya. Pengusaha ultimatley ingin programmer untuk melakukan hal-hal yang tidak mengenal mereka yang mungkin sulit ditunjukkan dalam sebuah wawancara. Jawaban yang Anda berikan akan baik jika melamar pekerjaan berbasis teknis atau dokumentasi tetapi bukan peran pengembang.

Semoga sukses dengan wawancara di masa depan.

Juga jawaban saya untuk pertanyaan ini lebih tentang teknik wawancara daripada materi teknis yang Anda berikan. Mungkin pertimbangkan untuk membacanya. https://workplace.stackexchange.com/ dapat menjadi tempat yang sangat baik untuk hal semacam ini.

Adrian
sumber
1
Bisakah Anda memberi tahu saya bagaimana Anda menjawabnya? Mungkin itu bisa membantu saya.
code_fish
memberi Anda jawaban menawarkan jauh lebih sedikit daripada membantu Anda menyelesaikannya, pada dasarnya memberikan contoh praktis kapan Anda akan menggunakan masing-masing dan menjelaskan mengapa masing-masing cocok untuk tugas yang berbeda.
Adrian
4

Anda memilih Antarmuka di Jawa untuk menghindari Masalah Intan di beberapa pewarisan .

Jika Anda ingin semua metode Anda diterapkan oleh klien Anda, Anda pergi untuk antarmuka. Ini berarti Anda mendesain seluruh aplikasi secara abstrak.

Anda memilih kelas abstrak jika Anda sudah tahu kesamaan. Misalnya Ambil kelas abstrak Car. Pada level yang lebih tinggi Anda menerapkan metode mobil umum seperti calculateRPM(). Ini adalah metode yang umum dan Anda membiarkan klien menerapkan perilakunya seperti
calculateMaxSpeed()dll. Mungkin Anda akan menjelaskan dengan memberikan beberapa contoh waktu nyata yang Anda temui dalam pekerjaan Anda sehari-hari.

MaheshVarma
sumber
3

Perbedaan utama yang saya amati adalah bahwa kelas abstrak memberi kita beberapa perilaku umum yang sudah dilaksanakan dan subkelas hanya perlu mengimplementasikan fungsionalitas khusus yang sesuai dengan mereka. sedangkan untuk antarmuka hanya akan menentukan tugas apa yang perlu dilakukan dan tidak ada implementasi yang diberikan oleh antarmuka. Saya dapat mengatakan itu menentukan kontrak antara dirinya dan kelas yang diimplementasikan.


sumber
3

Bahkan saya telah menghadapi pertanyaan yang sama dalam beberapa wawancara dan percayalah, membuat waktu Anda menyedihkan untuk meyakinkan pewawancara. Jika saya melekatkan semua jawaban dari atas maka saya perlu menambahkan satu poin kunci lagi untuk membuatnya lebih meyakinkan dan memanfaatkan OO yang terbaik

Jika Anda tidak merencanakan modifikasi apa pun dalam aturan , untuk subclass yang harus diikuti, untuk masa depan yang panjang, pergi untuk antarmuka, karena Anda tidak dapat memodifikasi di dalamnya dan jika Anda melakukannya, Anda harus pergi untuk perubahan di semua sub kelas lainnya, sedangkan, jika Anda berpikir, Anda ingin menggunakan kembali fungsionalitas, menetapkan beberapa aturan dan juga membuatnya terbuka untuk modifikasi , pilih kelas Abstrak.

Pikirkan dengan cara ini, Anda telah menggunakan layanan yang dapat dikonsumsi atau Anda telah memberikan beberapa kode kepada dunia dan Anda memiliki kesempatan untuk mengubah sesuatu, misalkan pemeriksaan keamanan Dan Jika saya menjadi konsumen kode dan Suatu pagi setelah pembaruan, saya temukan semua tanda baca di Eclipse saya, seluruh aplikasi sedang down. Jadi untuk mencegah mimpi buruk seperti itu, gunakan Abstract over Interfaces

Saya pikir ini mungkin meyakinkan Pewawancara sampai batas ... Selamat Wawancara Di Depan.

vinod bazari
sumber
2

Ketika saya mencoba untuk berbagi perilaku antara 2 kelas yang terkait erat, saya membuat kelas abstrak yang memegang perilaku umum dan berfungsi sebagai induk bagi kedua kelas.

Ketika saya mencoba mendefinisikan Tipe, daftar metode yang dapat dipanggil oleh pengguna objek saya, lalu saya membuat antarmuka.

Sebagai contoh, saya tidak akan pernah membuat kelas abstrak dengan 1 subkelas konkret karena kelas abstrak adalah tentang perilaku berbagi. Tapi saya mungkin bisa membuat antarmuka dengan hanya satu implementasi. Pengguna kode saya tidak akan tahu bahwa hanya ada satu implementasi. Memang, dalam rilis mendatang mungkin ada beberapa implementasi, yang semuanya adalah subkelas dari beberapa kelas abstrak baru yang bahkan tidak ada ketika saya membuat antarmuka.

Itu mungkin tampak agak terlalu kutu buku juga (meskipun saya belum pernah melihatnya menempatkannya di mana pun yang saya ingat). Jika pewawancara (atau OP) benar-benar menginginkan lebih banyak pengalaman pribadi saya tentang hal itu, saya akan siap dengan anekdot dari antarmuka yang telah berevolusi karena kebutuhan dan sebaliknya.

Satu hal lagi. Java 8 sekarang memungkinkan Anda untuk memasukkan kode default ke antarmuka, lebih jauh mengaburkan garis antara antarmuka dan kelas abstrak. Tetapi dari apa yang saya lihat, fitur itu terlalu sering digunakan bahkan oleh pembuat perpustakaan inti Java. Fitur itu ditambahkan, dan memang demikian, untuk memungkinkan untuk memperluas antarmuka tanpa membuat ketidakcocokan biner. Tetapi jika Anda membuat Tipe baru dengan mendefinisikan antarmuka, maka antarmuka tersebut HANYA sebuah antarmuka. Jika Anda ingin juga memberikan kode umum, maka tentu saja buatlah kelas pembantu (abstrak atau konkret). Jangan mengacaukan antarmuka Anda dari awal dengan fungsionalitas yang mungkin ingin Anda ubah.

Teto
sumber
2

Perbedaan mendasar antara antarmuka dan kelas abstrak adalah, antarmuka mendukung multiple inheritance tetapi kelas abstrak tidak.

Di kelas abstrak juga Anda dapat menyediakan semua metode abstrak seperti antarmuka.

mengapa kelas abstrak diperlukan?

Dalam beberapa skenario, saat memproses permintaan pengguna, kelas abstrak tidak tahu niat pengguna apa. Dalam skenario itu, kami akan mendefinisikan satu metode abstrak di kelas dan meminta pengguna yang memperluas kelas ini, harap berikan niat Anda dalam metode abstrak. Dalam hal ini kelas abstrak sangat berguna

Mengapa antarmuka diperlukan?

Katakanlah, saya punya pekerjaan yang saya tidak punya pengalaman di bidang itu. Contoh, jika Anda ingin membangun sebuah bangunan atau bendungan, lalu apa yang akan Anda lakukan dalam skenario itu?

  1. Anda akan mengidentifikasi apa saja persyaratan Anda dan membuat kontrak dengan persyaratan itu.
  2. Kemudian panggil Tender untuk membangun proyek Anda
  3. Siapa yang pernah membangun proyek, yang harus memenuhi persyaratan Anda. Tetapi logika konstruksinya berbeda dari satu vendor ke vendor lainnya.

Di sini saya tidak peduli tentang logika bagaimana mereka membangun. Objek akhir memenuhi persyaratan saya atau tidak, itu hanya poin kunci saya.

Di sini persyaratan Anda disebut antarmuka dan konstruktor disebut implementor.

Dharisi Suresh
sumber
2

Dalam beberapa kata, saya akan menjawab seperti ini:

  • warisan melalui hierarki kelas menyiratkan warisan negara ;
  • sedangkan pewarisan melalui antarmuka adalah warisan perilaku ;

Kelas abstrak dapat diperlakukan sebagai sesuatu di antara dua kasus ini (memperkenalkan beberapa keadaan tetapi juga mengharuskan Anda untuk mendefinisikan perilaku), kelas yang sepenuhnya abstrak adalah antarmuka (ini adalah pengembangan lebih lanjut dari kelas yang terdiri dari metode virtual hanya dalam C ++ sebagai Sejauh yang saya tahu sintaksnya).

Tentu saja, mulai dari Jawa 8 hal-hal sedikit berubah, tetapi idenya masih sama.

Saya kira ini cukup untuk wawancara Java biasa, jika Anda tidak diwawancarai ke tim kompiler.

Gleb Stromov
sumber
1

Dari apa yang saya pahami, sebuah Antarmuka, yang terdiri dari variabel akhir dan metode tanpa implementasi, diimplementasikan oleh kelas untuk memperoleh sekelompok metode atau metode yang terkait satu sama lain. Di sisi lain, kelas abstrak, yang dapat berisi variabel dan metode non-final dengan implementasi, biasanya digunakan sebagai panduan atau sebagai superclass dari mana semua kelas terkait atau sejenis mewarisi. Dengan kata lain, kelas abstrak berisi semua metode / variabel yang dibagikan oleh semua subkelasnya.

Marz
sumber
1

Di kelas abstrak, Anda dapat menulis implementasi metode default! Tetapi dalam Interface Anda tidak bisa. Pada dasarnya, dalam antarmuka terdapat metode virtual murni yang harus diimplementasikan oleh kelas yang mengimplementasikan antarmuka.

dg_no_9
sumber
1

Ya, respons Anda secara teknis benar tetapi di mana Anda salah tidak menunjukkannya, Anda memahami sisi positif dan buruk dari memilih satu di antara yang lain. Selain itu, mereka mungkin khawatir / panik tentang kompatibilitas basis kode mereka dengan peningkatan di masa depan. Jenis respons ini mungkin telah membantu (selain apa yang Anda katakan):

"Memilih Kelas Abstrak daripada Kelas Antarmuka tergantung pada apa yang kami proyeksikan di masa depan kode.

Kelas abstrak memungkinkan kompatibilitas maju yang lebih baik karena Anda dapat terus menambahkan perilaku ke Kelas Abstrak ke masa depan tanpa melanggar kode Anda yang ada -> ini tidak mungkin dengan Kelas Antarmuka.

Di sisi lain, Kelas Antarmuka lebih fleksibel daripada Kelas Abstrak. Ini karena mereka dapat mengimplementasikan banyak antarmuka . Masalahnya adalah Java tidak memiliki banyak pewarisan sehingga menggunakan kelas abstrak tidak akan membiarkan Anda menggunakan struktur hierarki kelas lainnya ...

Jadi, pada akhirnya aturan umum yang baik adalah: Lebih suka menggunakan Kelas Antarmuka ketika tidak ada implementasi / default di basis kode Anda. Dan, gunakan Kelas Abstrak untuk menjaga kompatibilitas jika Anda tahu Anda akan memperbarui kelas Anda di masa depan. "

Semoga sukses di wawancara Anda berikutnya!

Jaxian
sumber
1

Saya akan mencoba menjawab dengan menggunakan skenario praktis untuk menunjukkan perbedaan antara keduanya.

Antarmuka datang dengan nol payload yaitu tidak ada negara yang harus dipertahankan dan dengan demikian merupakan pilihan yang lebih baik untuk hanya mengasosiasikan kontrak (kemampuan) dengan kelas.

Misalnya, saya memiliki kelas Tugas yang melakukan beberapa tindakan, sekarang untuk menjalankan tugas di utas terpisah, saya tidak benar-benar perlu memperluas kelas Utas, bukan pilihan yang lebih baik adalah membuat Tugas mengimplementasikan antarmuka Runnable (mis. Mengimplementasikan metode run () -nya ) dan kemudian meneruskan objek kelas Tugas ini ke instance Thread dan memanggil metode start ().

Sekarang Anda dapat bertanya bagaimana jika Runnable adalah kelas abstrak?

Yah secara teknis itu mungkin tetapi desain bijaksana yang akan menjadi alasan pilihan yang buruk adalah:

  • Runnable tidak memiliki status yang terkait dengannya dan juga tidak 'menawarkan' implementasi default apa pun untuk metode run ()
  • Tugas harus diperluas sehingga tidak bisa memperpanjang kelas lain
  • Tugas tidak memiliki apa pun yang ditawarkan sebagai spesialisasi ke kelas Runnable, yang diperlukan hanyalah mengganti metode run ()

Dengan kata lain, kelas tugas membutuhkan kemampuan untuk dijalankan di utas yang dicapai dengan menerapkan ayat antarmuka Runnable memperluas kelas Utas yang akan menjadikannya utas.

Sederhananya kita antarmuka untuk mendefinisikan kemampuan (kontrak), sementara menggunakan kelas abstrak untuk mendefinisikan implementasi kerangka (umum / parsial) itu.

Penafian: contoh konyol berikut, cobalah untuk tidak menilai:

interface Forgiver {
    void forgive();
}

abstract class GodLike implements Forgiver {
    abstract void forget();
    final void forgive() {
        forget();
    }
}

Sekarang Anda telah diberi pilihan untuk menjadi GodLike tetapi Anda dapat memilih untuk menjadi Forgiver saja (yaitu bukan GodLike) dan lakukan:

class HumanLike implements Forgiver {
    void forgive() {
       // forgive but remember    
    }
}

Atau Anda dapat memilih untuk menjadi seperti GodLike dan melakukan:

class AngelLike extends GodLike {
    void forget() {
       // forget to forgive     
    }
}

PS dengan antarmuka java 8 juga dapat memiliki metode statis juga default (implementasi yang dapat dikesampingkan) dan perbedaan antarmuka b / w dan kelas abstrak bahkan lebih dipersempit.

sactiw
sumber
1

Hampir semuanya sepertinya sudah dibahas di sini .. Menambahkan hanya satu poin lagi tentang implementasi praktis abstractkelas:

abstractkata kunci juga digunakan hanya untuk mencegah kelas tidak dipakai. Jika Anda memiliki kelas konkret yang tidak ingin Anda instantiasi - Buatlah abstract.

Pedang
sumber
1

hmm sekarang orang-orang adalah pendekatan praktis lapar, Anda benar, tetapi sebagian besar pewawancara terlihat sesuai dengan kebutuhan mereka saat ini dan menginginkan pendekatan praktis.

setelah menyelesaikan jawaban Anda, Anda harus melompat pada contoh:

Abstrak:

misalnya kita memiliki fungsi gaji yang memiliki beberapa parametar yang sama untuk semua karyawan. maka kita dapat memiliki kelas abstrak yang disebut CTC dengan tubuh metode yang didefinisikan secara parsial dan akan diperluas oleh semua jenis karyawan dan mendapatkan redeined sesuai daging sapi ekstra mereka. Untuk fungsi umum.

public abstract class CTC {

    public int salary(int hra, int da, int extra)
    {
        int total;
        total = hra+da+extra;
        //incentive for specific performing employee
        //total = hra+da+extra+incentive;
        return total;
    }
}

class Manger extends CTC
{
}


class CEO extends CTC
{
}

class Developer extends CTC
{   
}

Antarmuka

antarmuka di java memungkinkan untuk memiliki fungsi interfcae tanpa memperluas yang itu dan Anda harus jelas dengan penerapan tanda tangan fungsionalitas yang ingin Anda perkenalkan di aplikasi Anda. itu akan memaksa Anda untuk memiliki definisi. Untuk fungsi yang berbeda.

public interface EmployeType {

    public String typeOfEmployee();
}

class ContarctOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "contract";
    }

}

class PermanentOne implements EmployeType
{

    @Override
    public String typeOfEmployee() {
        return "permanent";
    }

}

Anda dapat memiliki aktivitas paksa seperti itu dengan kelas abstrak juga dengan mendefinisikan methgos sebagai yang abstrak, sekarang sebuah kelas yang meluas kelas abstrak dan abstrak sampai ia menimpa fungsi abstrak itu.

RTA
sumber
1

Dari apa yang saya mengerti dan bagaimana saya mendekati,

Antarmuka seperti spesifikasi / kontrak, kelas apa pun yang mengimplementasikan kelas antarmuka harus mengimplementasikan semua metode yang didefinisikan dalam kelas abstrak (kecuali metode default (diperkenalkan di Java 8))

Sedangkan saya mendefinisikan abstrak kelas ketika saya tahu implementasi yang diperlukan untuk beberapa metode kelas dan beberapa metode saya masih tidak tahu apa yang akan menjadi implementasi (kita mungkin tahu fungsi tanda tangan tetapi bukan implementasi). Saya melakukan ini sehingga nanti di bagian pengembangan ketika saya tahu bagaimana metode ini harus diimplementasikan, saya hanya bisa memperluas kelas abstrak ini dan mengimplementasikan metode ini.

Catatan: Anda tidak dapat memiliki tubuh fungsi dalam metode antarmuka kecuali metode tersebut statis atau default.

Akash Lodha
sumber
0

Saya percaya apa yang pewawancara coba lakukan mungkin adalah perbedaan antara antarmuka dan implementasi.

Antarmuka - bukan antarmuka Java, tetapi "antarmuka" dalam istilah yang lebih umum - untuk modul kode, pada dasarnya, kontrak yang dibuat dengan kode klien yang menggunakan antarmuka.

Implementasi modul kode adalah kode internal yang membuat modul berfungsi. Seringkali Anda dapat mengimplementasikan antarmuka tertentu dalam lebih dari satu cara yang berbeda, dan bahkan mengubah implementasinya tanpa kode klien bahkan menyadari perubahan tersebut.

Antarmuka Java seharusnya hanya digunakan sebagai antarmuka dalam pengertian generik di atas, untuk menentukan bagaimana kelas berperilaku untuk kepentingan kode klien menggunakan kelas, tanpa menentukan implementasi apa pun. Jadi, sebuah antarmuka menyertakan tanda tangan metode - nama, tipe pengembalian, dan daftar argumen - untuk metode yang diharapkan dipanggil oleh kode klien, dan pada prinsipnya harus memiliki banyak Javadoc untuk setiap metode yang menggambarkan apa yang dilakukan metode itu. Alasan yang paling menarik untuk menggunakan antarmuka adalah jika Anda berencana untuk memiliki beberapa implementasi antarmuka yang berbeda, mungkin memilih implementasi tergantung pada konfigurasi penempatan.

Kelas abstrak Java, sebaliknya, menyediakan implementasi parsial kelas, daripada memiliki tujuan utama menentukan antarmuka. Ini harus digunakan ketika beberapa kelas berbagi kode, tetapi ketika subclass juga diharapkan untuk memberikan bagian dari implementasi. Ini memungkinkan kode bersama muncul hanya di satu tempat - kelas abstrak - sambil memperjelas bahwa bagian-bagian implementasi tidak ada dalam kelas abstrak dan diharapkan disediakan oleh subkelas.

Warren Dew
sumber
0

jawaban Anda benar tetapi pewawancara mengharuskan Anda untuk membedakan menurut perspektif rekayasa perangkat lunak tidak sesuai dengan rincian Jawa.

Kata-kata sederhana:

Antarmuka adalah seperti antarmuka toko apa pun yang ditampilkan di sana harus ada di toko, jadi metode apa pun di Antarmuka harus ada diimplementasikan di kelas beton. Sekarang bagaimana jika beberapa kelas berbagi beberapa metode yang tepat dan bervariasi dalam yang lain. Misalkan Antarmuka adalah tentang toko yang berisi dua hal dan misalkan kita memiliki dua toko yang keduanya berisi peralatan olahraga tetapi satu memiliki pakaian ekstra dan yang lainnya memiliki sepatu ekstra. Jadi yang Anda lakukan adalah membuat kelas abstrak untuk Olahraga yang mengimplementasikan metode Olahraga dan membiarkan metode lainnya tidak diterapkan. Kelas abstrak di sini berarti bahwa toko ini tidak ada sendiri tetapi merupakan dasar untuk kelas / toko lain. Dengan cara ini Anda mengatur kode, menghindari kesalahan mereplikasi kode, menyatukan kode, dan memastikan penggunaan kembali oleh beberapa kelas lain.

Mosab Shaheen
sumber