1. Kemampuan

Untuk lebih memahami manfaat antarmuka dan di mana menggunakannya, kita perlu membicarakan beberapa hal yang lebih abstrak.

Kelas biasanya memodelkan objek tertentu. Antarmuka kurang sesuai dengan objek, dan lebih sesuai dengan kemampuan atau peran mereka.

Inti dari antarmuka

Misalnya, hal-hal seperti mobil, sepeda, sepeda motor, dan roda paling baik direpresentasikan sebagai kelas dan objek. Tapi kemampuan mereka — seperti "Saya bisa ditunggangi", "Saya bisa mengangkut orang", "Saya bisa berdiri" — lebih baik ditampilkan sebagai antarmuka. Berikut beberapa contohnya:

Kode Keterangan
interface CanMove
{
   void move(String newLocation);
}
Sesuai dengan kemampuan bergerak
interface Rideable
{
   void ride(Passenger passenger);
}
Sesuai dengan kemampuan untuk dikendarai
interface CanTransport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
Sesuai dengan kemampuan untuk mengangkut barang
class Wheel implements CanMove
{
   ...
}
Kelas Wheelbisa bergerak
class Car implements CanMove, Rideable, CanTransport
{
   ...
}
Kelas Cardapat bergerak, ditunggangi, dan mengangkut barang
class Skateboard implements CanMove, Rideable
{
   ...
}
Kelas Skateboarddapat bergerak dan ditunggangi


2. Peran

Antarmuka sangat menyederhanakan kehidupan programmer. Sangat sering, sebuah program memiliki ribuan objek, ratusan kelas, tetapi hanya beberapa lusin antarmuka , yaitu peran . Ada beberapa peran, tetapi ada banyak cara untuk menggabungkannya (kelas).

Intinya adalah Anda tidak perlu menulis kode di setiap kelas untuk berinteraksi dengan setiap kelas lainnya. Anda hanya perlu berinteraksi dengan peran mereka (antarmuka).

Bayangkan Anda adalah pelatih hewan peliharaan. Setiap hewan peliharaan yang bekerja dengan Anda dapat memiliki beberapa kemampuan berbeda. Anda bertengkar dengan tetangga tentang hewan peliharaan siapa yang paling berisik. Untuk menyelesaikan masalah ini, Anda cukup membariskan semua hewan peliharaan yang dapat "berbicara", dan Anda memberi mereka perintah: Bicara!

Anda tidak peduli binatang apa mereka atau kemampuan lain apa yang mereka miliki. Bahkan jika mereka bisa melakukan jungkir balik tiga kali lipat. Pada saat khusus ini, Anda hanya tertarik pada kemampuan mereka untuk berbicara dengan lantang. Berikut tampilannya dalam kode:

Kode Keterangan
interface CanSpeak
{
   void speak();
}
Kemampuan CanSpeak. Antarmuka ini memahami perintah ke speak, artinya memiliki metode yang sesuai.
class Cat implements CanSpeak
{
   void speak()
   {
      println("MEOW");
   }
}

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

class Fish
{
   ...
}
Hewan yang memiliki fitur ini.

Untuk memudahkan pemahaman, kami memberikan nama kelas dalam bahasa Inggris. Ini diperbolehkan di Jawa, tetapi sangat tidak diinginkan.













Kami Fishtidak memiliki kemampuan untuk berbicara (tidak mengimplementasikan antarmuka CanSpeak).

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 perintah?

Ketika jumlah kelas dalam program Anda mencapai ribuan, Anda tidak akan bisa hidup tanpa antarmuka. Alih-alih mendeskripsikan interaksi ribuan kelas, cukup mendeskripsikan interaksi beberapa lusin antarmuka — ini sangat menyederhanakan hidup.

Dan bila dikombinasikan dengan polimorfisme, pendekatan ini umumnya sukses besar.



3. defaultPenerapan metode antarmuka

Kelas abstrak dapat memiliki variabel dan implementasi metode, tetapi tidak dapat memiliki banyak pewarisan. Antarmuka tidak dapat memiliki variabel atau implementasi metode, tetapi dapat memiliki banyak pewarisan.

Situasi tersebut diungkapkan dalam tabel berikut:

Kemampuan/properti Kelas abstrak Antarmuka
Variabel
Implementasi metode
Warisan berganda

Jadi, beberapa programmer sangat menginginkan antarmuka memiliki kemampuan untuk memiliki implementasi metode. Tetapi memiliki kemampuan untuk menambahkan implementasi metode tidak berarti bahwa metode tersebut akan selalu ditambahkan. Tambahkan jika Anda mau. Atau jika tidak, maka jangan.

Selain itu, masalah dengan pewarisan berganda terutama disebabkan oleh variabel. Bagaimanapun, itulah yang mereka putuskan dan lakukan. Dimulai dengan JDK 8, Java memperkenalkan kemampuan untuk menambahkan implementasi metode ke antarmuka.

Ini tabel yang diperbarui (untuk JDK 8 dan yang lebih baru):

Kemampuan/properti Kelas abstrak Antarmuka
Variabel
Implementasi metode
Warisan berganda

Sekarang untuk kelas abstrak serta antarmuka, Anda dapat mendeklarasikan metode dengan atau tanpa implementasi. Dan ini adalah berita bagus!

Dalam kelas abstrak, metode tanpa implementasi harus diawali dengan abstractkata kunci. Anda tidak perlu menambahkan apa pun sebelum metode dengan implementasi. Di antarmuka, kebalikannya benar. Jika suatu metode tidak memiliki implementasi, maka tidak ada yang harus ditambahkan. Namun jika ada implementasi, maka defaultkata kunci harus ditambahkan.

Untuk mempermudah, kami sajikan informasi ini dalam tabel kecil berikut:

Kemampuan/properti Kelas abstrak Antarmuka
Metode tanpa implementasi abstract
Metode dengan implementasi default

Masalah

Menggunakan antarmuka yang memiliki metode dapat sangat menyederhanakan hierarki kelas besar. Misalnya, abstrak InputStreamdan OutputStreamkelas dapat dideklarasikan sebagai antarmuka! Ini memungkinkan kita menggunakannya lebih sering dan lebih nyaman.

Tapi sudah ada puluhan juta (miliar?) kelas Java di dunia. Dan jika Anda mulai mengubah pustaka standar, Anda mungkin merusak sesuatu. Seperti semuanya! 😛

Agar tidak merusak program dan pustaka yang ada secara tidak sengaja, diputuskan bahwa implementasi metode dalam antarmuka akan memiliki prioritas pewarisan terendah .

Misalnya, jika satu antarmuka mewarisi antarmuka lain yang memiliki metode, dan antarmuka pertama mendeklarasikan metode yang sama tetapi tanpa implementasi, maka implementasi metode dari antarmuka yang diwariskan tidak akan mencapai antarmuka yang diwariskan. 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
{
}

Kode tidak akan dikompilasi karena Tomkelas tidak mengimplementasikan meow()metode.