1. Memperkenalkan antara muka

Hari ini adalah hari anda untuk pengetahuan. Satu lagi topik baharu dan menarik ialah antara muka.

Konsep antara muka adalah anak kepada prinsip abstraksi dan polimorfisme. Antara muka adalah sangat serupa dengan kelas abstrak, di mana semua kaedah adalah abstrak. Ia diisytiharkan dengan cara yang sama seperti kelas, tetapi kami menggunakan kata interfacekunci.

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

Berikut ialah beberapa fakta berguna tentang antara muka:

1. Mengisytiharkan antara muka

interface Drawable
{
   void draw();
}

interface HasValue
{
   int getValue();
}
  1. Daripada classkata kunci, kami menulis interface.
  2. Ia mengandungi kaedah abstrak sahaja (jangan tulis abstractkata kunci)
  3. Malah, antara muka mempunyai semuapublic kaedah
2. Warisan antara muka

Antara muka hanya boleh mewarisi antara muka. Tetapi antara muka boleh mempunyai ramai ibu bapa. Satu lagi cara untuk mengatakan ini ialah dengan mengatakan bahawa Java mempunyai pelbagai warisan antara muka. Contoh:

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

3. Mewarisi kelas daripada antara muka

Kelas boleh mewarisi berbilang antara muka (hanya daripada satu kelas). Ini dilakukan 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 diisytiharkan abstrak: ia melaksanakan semua kaedah yang diwarisi kecuali draw. Dengan kata lain, ChessItemkelas mengandungi satu kaedah abstrak — draw().

Maksud teknikal extendsdan implementskata kunci adalah sama: kedua-duanya adalah warisan. Perbezaan dibuat untuk meningkatkan kebolehbacaan kod. Kami juga mengatakan bahawa kelas diwarisi (melalui extends) dan antara muka dilaksanakan (melalui implements)

4. Pembolehubah

Inilah perkara yang paling penting: pembolehubah biasa tidak boleh diisytiharkan dalam antara muka (walaupun pembolehubah statik boleh).

Tetapi mengapa kita memerlukan antara muka? Bilakah ia digunakan? Antara muka mempunyai dua kelebihan yang kuat berbanding kelas:



2. Mengasingkan "penerangan kaedah" daripada pelaksanaannya.

Sebelum ini, kami berkata bahawa jika anda ingin membenarkan kaedah kelas anda dipanggil dari kelas lain, maka kaedah anda perlu ditandakan dengan kata publickunci. Jika anda mahu beberapa kaedah tersebut dipanggil hanya dari dalam kelas anda, anda perlu menandakannya dengan kata privatekunci. Dalam erti kata lain, kami membahagikan kaedah kelas kepada dua kategori: "untuk digunakan oleh semua orang" dan "hanya untuk kegunaan kami sendiri".

Antara muka membantu mengukuhkan lagi bahagian ini. Kami akan membuat "kelas untuk kegunaan semua orang" khas serta kelas kedua "hanya untuk kegunaan kami sendiri", yang akan mewarisi kelas pertama. Begini kira-kira bagaimana ia akan kelihatan:

Sebelum ini Selepas
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 membahagikan kelas kami kepada dua: antara muka dan kelas yang mewarisi antara muka . Dan apakah kelebihan di sini?

Banyak kelas yang berbeza boleh melaksanakan (mewarisi) antara muka yang sama. Dan setiap orang boleh mempunyai tingkah laku sendiri. Sebagai contoh, ArrayList LinkedListadalah dua pelaksanaan berbeza antara Listmuka.

Oleh itu, kami menyembunyikan bukan sahaja pelbagai pelaksanaan, tetapi juga kelas pelaksana itu sendiri (kerana kami hanya memerlukan antara muka dalam kod). Ini membolehkan kita menjadi sangat fleksibel: semasa program berjalan, kita boleh menggantikan satu objek dengan yang lain, mengubah tingkah laku objek tanpa menjejaskan semua kelas yang menggunakannya.

Ini adalah teknik yang sangat berkuasa apabila digabungkan dengan polimorfisme. Buat masa ini, adalah jauh dari jelas mengapa anda perlu melakukan ini. Mula-mula anda perlu menemui program dengan berpuluh-puluh atau beratus-ratus kelas untuk memahami bahawa antara muka boleh menjadikan hidup anda lebih mudah berbanding tanpanya.


3. Pusaka berbilang

Di Java, semua kelas hanya boleh mempunyai satu kelas induk. Dalam bahasa pengaturcaraan lain, kelas selalunya boleh mempunyai berbilang kelas induk. Ini sangat mudah, tetapi juga membawa banyak masalah.

Pencipta Java mencapai kompromi: mereka melarang pewarisan berbilang kelas, tetapi membenarkan pewarisan berbilang antara muka. Antara muka boleh mempunyai berbilang antara muka induk. Kelas boleh mempunyai berbilang antara muka induk tetapi hanya satu kelas induk.

Mengapa mereka mengharamkan berbilang warisan kelas tetapi membenarkan berbilang warisan antara muka? Kerana apa yang dipanggil masalah warisan berlian:

Pusaka berbilang

Apabila kelas B mewarisi kelas A, ia tidak tahu apa-apa tentang kelas C dan D. Jadi ia menggunakan pembolehubah kelas A seperti yang difikirkannya patut. Kelas C melakukan perkara yang sama: ia menggunakan pembolehubah kelas A, tetapi dengan cara yang berbeza. Dan semua ini mengakibatkan konflik dalam kelas D.

Mari kita lihat contoh mudah berikut. Katakan kita mempunyai 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 valuepembolehubah. Kelas keturunan XCoordinate menggunakan pembolehubah itu untuk menyimpan xnilai, dan YCoordinatekelas keturunan menggunakannya untuk menyimpan ynilai.

Dan ia berfungsi. Secara berasingan. Tetapi jika kita mahu kelas XYCoordinates mewarisi kedua-dua kelas XCoordinatedan YCoordinate, maka kita akan mendapat kod rosak. Kelas ini akan mempunyai kaedah kelas nenek moyangnya, tetapi mereka tidak akan berfungsi dengan betul, kerana mereka mempunyai value variable.

Tetapi kerana antara muka tidak boleh mempunyai pembolehubah, mereka tidak boleh mempunyai konflik seperti ini. Sehubungan itu, pewarisan berbilang antara muka dibenarkan.