1. Kebolehan

Untuk lebih memahami faedah antara muka dan tempat untuk menggunakannya, kita perlu bercakap tentang beberapa perkara yang lebih abstrak.

Kelas biasanya memodelkan objek tertentu. Antara muka kurang sepadan dengan objek, dan lebih kepada kebolehan atau peranan mereka.

Intipati antara muka

Contohnya, perkara seperti kereta, basikal, motosikal dan roda paling baik digambarkan sebagai kelas dan objek. Tetapi kebolehan mereka — seperti "Saya boleh ditunggangi", "Saya boleh mengangkut orang", "Saya boleh berdiri" — lebih baik dipersembahkan sebagai antara muka. Berikut adalah beberapa contoh:

Kod Penerangan
interface CanMove
{
   void move(String newLocation);
}
Sesuai dengan keupayaan untuk bergerak
interface Rideable
{
   void ride(Passenger passenger);
}
Sesuai dengan keupayaan untuk ditunggangi
interface CanTransport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
Sesuai dengan keupayaan untuk mengangkut barang
class Wheel implements CanMove
{
   ...
}
Kelas Wheelboleh bergerak
class Car implements CanMove, Rideable, CanTransport
{
   ...
}
Kelas Carboleh bergerak, ditunggangi, dan mengangkut barang
class Skateboard implements CanMove, Rideable
{
   ...
}
Kelas Skateboardboleh bergerak dan ditunggangi


2. Peranan

Antara muka sangat memudahkan kehidupan pengaturcara. Selalunya, program mempunyai beribu-ribu objek, beratus-ratus kelas, tetapi hanya beberapa dozen antara muka , iaitu peranan . Terdapat sedikit peranan, tetapi terdapat banyak cara untuk menggabungkannya (kelas).

Intinya ialah anda tidak perlu menulis kod untuk setiap kelas untuk berinteraksi dengan setiap kelas lain. Anda hanya perlu berinteraksi dengan peranan mereka (antara muka).

Bayangkan anda seorang jurulatih haiwan peliharaan. Setiap haiwan peliharaan yang anda bekerjasama boleh mempunyai beberapa kebolehan yang berbeza. Anda bertengkar dengan jiran anda mengenai haiwan peliharaan siapa yang paling banyak bising. Untuk menyelesaikan perkara itu, anda hanya membariskan semua haiwan peliharaan yang boleh "bercakap", dan anda memberi mereka arahan: Bercakap!

Anda tidak peduli apa jenis haiwan mereka atau apa kebolehan lain yang mereka ada. Walaupun mereka boleh melakukan jungkir balik tiga kali ganda. Pada masa ini, anda hanya berminat dengan keupayaan mereka untuk bercakap dengan kuat. Inilah yang akan kelihatan seperti dalam kod:

Kod Penerangan
interface CanSpeak
{
   void speak();
}
kebolehan CanSpeak. Antara muka ini memahami arahan kepada speak, bermakna ia mempunyai kaedah yang sepadan.
class Cat implements CanSpeak
{
   void speak()
   {
      println("MEOW");
   }
}

class Dog implements CanSpeak
{
   void speak()
   {
      println("WOOF");
   }
}

class Fish
{
   ...
}
Haiwan yang mempunyai ciri ini.

Untuk memudahkan pemahaman, kami menyediakan nama kelas dalam bahasa Inggeris. Ini dibenarkan di Jawa, tetapi ia sangat tidak diingini.













Kami Fishtidak mempunyai keupayaan untuk bercakap (tidak melaksanakan CanSpeakantara muka).

public static void main(String[] args)
{
   // Add all the animals to the list
   ArrayList pets = new ArrayList();
   pets.add(new Cat());
   pets.add(new Dog());
   pets.add(new Fish());

   // If the ability exists, then make a sound
   for(Object pet: pets)
   {
      if (pet instanceof CanSpeak)
      {
         CanSpeak loudmouth = (CanSpeak) pet;
         loudmouth.speak();
      }
   }
}
Dan bagaimana kita memberi mereka arahan?

Apabila bilangan kelas dalam program anda mencecah ribuan, anda tidak akan dapat hidup tanpa antara muka. Daripada menerangkan interaksi beribu-ribu kelas, ia sudah cukup untuk menerangkan interaksi beberapa dozen antara muka — ini sangat memudahkan kehidupan.

Dan apabila digabungkan dengan polimorfisme, pendekatan ini secara amnya merupakan satu kejayaan yang menakjubkan.



3. defaultPelaksanaan kaedah antara muka

Kelas abstrak boleh mempunyai pembolehubah dan pelaksanaan kaedah, tetapi mereka tidak boleh mempunyai banyak warisan. Antara muka tidak boleh mempunyai pembolehubah atau pelaksanaan kaedah, tetapi itu boleh mempunyai berbilang warisan.

Situasi dinyatakan dalam jadual berikut:

Keupayaan/harta benda Kelas abstrak Antara muka
Pembolehubah
Pelaksanaan kaedah
Pusaka berbilang

Jadi, sesetengah pengaturcara benar-benar mahukan antara muka mempunyai keupayaan untuk mempunyai pelaksanaan kaedah. Tetapi mempunyai keupayaan untuk menambah pelaksanaan kaedah tidak bermakna bahawa satu akan sentiasa ditambah. Tambah jika anda mahu. Atau jika anda tidak, maka jangan.

Di samping itu, masalah dengan warisan berbilang disebabkan terutamanya oleh pembolehubah. Walau apa pun, itulah yang mereka putuskan dan lakukan. Bermula dengan JDK 8, Java memperkenalkan keupayaan untuk menambah pelaksanaan kaedah pada antara muka.

Berikut ialah jadual yang dikemas kini (untuk JDK 8 dan ke atas):

Keupayaan/harta benda Kelas abstrak Antara muka
Pembolehubah
Pelaksanaan kaedah
Pusaka berbilang

Sekarang untuk kelas abstrak serta antara muka, anda boleh mengisytiharkan kaedah dengan atau tanpa pelaksanaan. Dan ini adalah berita yang sangat baik!

Dalam kelas abstrak, kaedah tanpa pelaksanaan mesti didahului oleh abstractkata kunci. Anda tidak perlu menambah apa-apa sebelum kaedah dengan pelaksanaan. Dalam antara muka, sebaliknya adalah benar. Jika kaedah tidak mempunyai pelaksanaan, maka tiada apa yang perlu ditambah. Tetapi jika terdapat pelaksanaan, maka defaultkata kunci mesti ditambah.

Untuk kesederhanaan, kami membentangkan maklumat ini dalam jadual kecil berikut:

Keupayaan/harta benda Kelas abstrak Antara muka
Kaedah tanpa pelaksanaan abstract
Kaedah dengan pelaksanaan default

Masalah

Menggunakan antara muka yang mempunyai kaedah boleh memudahkan hierarki kelas yang besar. Sebagai contoh, abstrak InputStreamdan OutputStreamkelas boleh diisytiharkan sebagai antara muka! Ini membolehkan kami menggunakannya dengan lebih kerap dan lebih mudah.

Tetapi sudah ada berpuluh juta (berbilion?) kelas Java di dunia. Dan jika anda mula menukar perpustakaan standard, maka anda mungkin memecahkan sesuatu. Suka segala-galanya! 😛

Untuk tidak memecahkan program dan pustaka sedia ada secara tidak sengaja, telah diputuskan bahawa pelaksanaan kaedah dalam antara muka akan mempunyai keutamaan warisan yang paling rendah .

Sebagai contoh, jika satu antara muka mewarisi antara muka lain yang mempunyai kaedah, dan antara muka pertama mengisytiharkan kaedah yang sama tetapi tanpa pelaksanaan, maka pelaksanaan kaedah daripada antara muka yang diwarisi tidak akan mencapai antara muka pewarisan. Contoh:

interface Pet
{
   default void meow()
   {
      System.out.println("Meow");
   }
}

interface Cat extends Pet
{
   void meow(); // Here we override the default implementation by omitting an implementation
}

class Tom implements Cat
{
}

Kod tidak akan disusun kerana Tomkelas tidak melaksanakan meow()kaedah.