1. Memperkenalkan antarmuka

Hari ini adalah harimu untuk pengetahuan. Topik baru dan menarik lainnya adalah antarmuka.

Konsep antarmuka adalah anak dari prinsip abstraksi dan polimorfisme. Antarmuka sangat mirip dengan kelas abstrak, di mana semua metodenya abstrak. Itu dideklarasikan dengan cara yang sama seperti kelas, tetapi kami menggunakan kata interfacekunci.

interface Feline
{
   void purr();
   void meow();
   void growl();
}

Berikut adalah beberapa fakta berguna tentang antarmuka:

1. Mendeklarasikan antarmuka

interface Drawable
{
   void draw();
}

interface HasValue
{
   int getValue();
}
  1. Alih-alih classkata kunci, kami menulis interface.
  2. Ini hanya berisi metode abstrak (jangan tulis abstractkata kunci)
  3. Faktanya, antarmuka memiliki semuapublic metode
2. Warisan antarmuka

Antarmuka hanya dapat mewarisi antarmuka. Tetapi sebuah antarmuka dapat memiliki banyak orang tua. Cara lain untuk mengatakan ini adalah dengan mengatakan bahwa Java memiliki banyak pewarisan antarmuka. Contoh:

interface Piece extends Drawable, HasValue
{
   int getX();
   int getY();
}

3. Mewarisi kelas dari antarmuka

Kelas dapat mewarisi banyak antarmuka (hanya dari satu kelas). Ini dilakukan dengan menggunakan implementskata kunci. Contoh:

abstract class ChessItem implements Drawable, HasValue
{
   private int x, y, value;
   public int getValue()
   {
      return value;
   }

   public int getX()
   {
      return x;
   }

   public  int getY()
   {
      return y;
   }
}

Kelas ChessItem dinyatakan abstrak: ia mengimplementasikan semua metode yang diwariskan kecuali draw. Dengan kata lain, ChessItemkelas berisi satu metode abstrak — draw().

Arti teknis dari extendsdan implementskata kunci adalah sama: keduanya adalah warisan. Perbedaan itu dibuat untuk meningkatkan keterbacaan kode. Kami juga mengatakan bahwa kelas diwariskan (melalui extends) dan antarmuka diimplementasikan (melalui implements)

4. Variabel

Inilah hal yang paling penting: variabel biasa tidak dapat dideklarasikan di antarmuka (walaupun yang statis bisa).

Tetapi mengapa kita membutuhkan antarmuka? Kapan mereka digunakan? Antarmuka memiliki dua keunggulan kuat dibandingkan kelas:



2. Memisahkan "deskripsi metode" dari implementasinya.

Sebelumnya, kami mengatakan bahwa jika Anda ingin mengizinkan metode kelas Anda dipanggil dari kelas lain, maka metode Anda harus ditandai dengan kata kunci public. Jika Anda ingin beberapa metode tersebut dipanggil hanya dari dalam kelas Anda, Anda perlu menandainya dengan kata privatekunci. Dengan kata lain, kami membagi metode kelas menjadi dua kategori: "untuk digunakan semua orang" dan "hanya untuk digunakan sendiri".

Antarmuka membantu memperkuat divisi ini lebih jauh. Kami akan membuat "kelas khusus untuk digunakan semua orang" serta kelas kedua "hanya untuk penggunaan kami sendiri", yang akan mewarisi kelas pertama. Begini kira-kira tampilannya:

Sebelum Setelah
class Student
{
   private String name;
   public Student(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return this.name;
   }

   private void setName(String name)
   {
      this.name = name;
   }
interface Student
{
   public String getName();
}

class StudentImpl implements Student
{
   private String name;
   public StudentImpl(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return this.name;
   }

   private void setName(String name)
   {
      this.name = name;
   }
}
public static void main(String[] args)
{
   Student student = new Student("Alibaba");
   System.out.println(student.getName());
}
public static void main(String[] args)
{
   Student student = new StudentImpl("Ali")
   System.out.println(student.getName());
}

Kami membagi kelas kami menjadi dua: antarmuka dan kelas yang mewarisi antarmuka . Dan apa keuntungannya di sini?

Banyak kelas yang berbeda dapat mengimplementasikan (mewarisi) antarmuka yang sama. Dan masing-masing dapat memiliki perilakunya sendiri. Misalnya, ArrayList LinkedListdua implementasi antarmuka yang berbeda List.

Jadi, kami tidak hanya menyembunyikan berbagai implementasi, tetapi juga kelas implementasi itu sendiri (karena kami hanya memerlukan antarmuka dalam kode). Ini memungkinkan kita menjadi sangat fleksibel: tepat saat program berjalan, kita dapat mengganti satu objek dengan objek lainnya, mengubah perilaku objek tanpa memengaruhi semua kelas yang menggunakannya.

Ini adalah teknik yang sangat kuat bila dikombinasikan dengan polimorfisme. Untuk saat ini, masih jauh dari jelas mengapa Anda harus melakukan ini. Pertama-tama Anda perlu menemukan program dengan lusinan atau ratusan kelas untuk memahami bahwa antarmuka dapat membuat hidup Anda jauh lebih mudah daripada tanpanya.


3. Warisan berganda

Di Java, semua kelas hanya dapat memiliki satu kelas induk. Dalam bahasa pemrograman lain, kelas seringkali dapat memiliki beberapa kelas induk. Ini sangat nyaman, tetapi juga membawa banyak masalah.

Pencipta Java sampai pada kompromi: mereka melarang banyak pewarisan kelas, tetapi mengizinkan banyak pewarisan antarmuka. Antarmuka dapat memiliki beberapa antarmuka induk. Kelas dapat memiliki beberapa antarmuka induk tetapi hanya satu kelas induk.

Mengapa mereka melarang banyak pewarisan kelas tetapi mengizinkan banyak pewarisan antarmuka? Karena apa yang disebut masalah warisan intan:

Warisan berganda

Ketika kelas B mewarisi kelas A, ia tidak tahu apa-apa tentang kelas C dan D. Jadi ia menggunakan variabel kelas A sesuai keinginannya. Kelas C melakukan hal yang sama: menggunakan variabel kelas A, tetapi dengan cara yang berbeda. Dan semua ini menghasilkan konflik di kelas D.

Mari kita lihat contoh sederhana berikut ini. Katakanlah kita memiliki 3 kelas:

class Data
{
   protected int value;
}
class XCoordinate extends Data
{
   public void setX (int x) { value = x;}
   public int getX () { return value;}
}
class YCoordinate extends Data
{
   public void setY (int y) { value = y;}
   public int getY () { return value; }
}

Kelas Data menyimpan valuevariabel. Kelas keturunan XCoordinate menggunakan variabel itu untuk menyimpan xnilai, dan YCoordinatekelas keturunan menggunakannya untuk menyimpan ynilai.

Dan itu berhasil. Terpisah. Tetapi jika kita ingin kelas XYCoordinates mewarisi kelas XCoordinatedan YCoordinate, maka kita mendapatkan kode yang rusak. Kelas ini akan memiliki metode dari kelas leluhurnya, tetapi tidak akan bekerja dengan benar, karena memiliki kesamaan value variable.

Tetapi karena antarmuka tidak dapat memiliki variabel, mereka tidak dapat memiliki konflik semacam ini. Dengan demikian, beberapa warisan antarmuka diperbolehkan.