JavaRush /Blog Java /Random-MS /Rehat kopi #140. Kelas abstrak dan antara muka dalam Java...

Rehat kopi #140. Kelas abstrak dan antara muka dalam Java

Diterbitkan dalam kumpulan
Sumber: InfoWorld Hari ini anda akan belajar dalam kes mana pembangun harus menggunakan kelas abstrak dan dalam kes mana antara muka. Kami juga akan mengenal pasti perbezaan antara unsur-unsur bahasa Java ini dan cara menggunakannya dalam program. Rehat kopi #140.  Kelas abstrak dan antara muka dalam Java - 1Kelas abstrak dan antara muka agak biasa dalam kod Java dan juga dalam Java Development Kit (JDK) itu sendiri. Setiap elemen ini mempunyai tujuan yang berbeza:
  • Antara muka ialah binaan dalam bahasa Java yang membantu melaksanakan kaedah abstrak dan pemalar statik.
  • Kelas abstrak adalah serupa dengan kelas biasa, kecuali ia boleh memasukkan kaedah abstrak, iaitu kaedah tanpa badan. Kelas abstrak tidak boleh dibuat.
Ramai pembangun berpendapat bahawa antara muka dan kelas abstrak adalah serupa, tetapi sebenarnya ini tidak sepenuhnya benar. Mari kita lihat perbezaan utama antara mereka.

Apakah itu antara muka

Pada terasnya, antara muka ialah kontrak, jadi ia bergantung pada pelaksanaan untuk menentukan tujuan penciptaannya. Antara muka tidak boleh menggunakan pembolehubah contoh boleh ubah, ia hanya boleh menggunakan pembolehubah akhir.

Bila hendak menggunakan antara muka

Antara muka sangat berguna untuk memisahkan kod dan melaksanakan polimorfisme. Kita boleh melihat ini dalam JDK dengan antara muka Senarai :
public interface List<E> extends Collection<E> {

    int size();
    boolean isEmpty();
    boolean add(E e);
    E remove(int index);
    void clear();
}
Seperti yang mungkin anda perhatikan, kod ini, walaupun ringkas, agak deskriptif. Kita boleh dengan mudah melihat tandatangan kaedah yang akan digunakan untuk melaksanakan kaedah dalam antara muka menggunakan kelas konkrit. Antara muka Senarai mengandungi kontrak yang boleh dilaksanakan oleh ArrayList , Vector , LinkedList dan kelas lain. Untuk menggunakan polimorfisme, kami hanya boleh mengisytiharkan jenis pembolehubah kami menggunakan Senarai dan kemudian pilih mana-mana contoh yang tersedia. Berikut adalah contoh lain:
List list = new ArrayList();
System.out.println(list.getClass());

 List list = new LinkedList();
 System.out.println(list.getClass());
Outputnya ialah:
kelas java.util.ArrayList kelas java.util.LinkedList
Dalam kes ini, kaedah pelaksanaan untuk ArrayList , LinkedList dan Vector adalah berbeza, yang merupakan senario yang sangat baik untuk menggunakan antara muka. Jika anda perasan bahawa banyak kelas tergolong dalam kelas induk dengan tindakan kaedah yang sama tetapi tingkah laku yang berbeza. Dalam situasi sedemikian, adalah disyorkan untuk menggunakan antara muka. Seterusnya, mari kita lihat beberapa pilihan untuk menggunakan antara muka.

Mengatasi Kaedah Antara Muka

Seperti yang kita sedia maklum, antara muka adalah sejenis kontrak yang mesti dilaksanakan oleh kelas konkrit. Kaedah antara muka secara tersirat abstrak dan memerlukan pelaksanaan konkrit kelas. Berikut ialah contoh:
public class OverridingDemo {
  public static void main(String[] args) {
    Challenger challenger = new JavaChallenger();
    challenger.doChallenge();
  }
}

interface Challenger {
  void doChallenge();
}

class JavaChallenger implements Challenger {
  @Override
  public void doChallenge() {
    System.out.println("Challenge done!");
  }
}
Kesimpulan:
Cabaran selesai!
Ambil perhatian bahawa kaedah antara muka adalah abstrak secara tersirat . Ini bermakna kita tidak perlu mengisytiharkannya sebagai abstrak secara eksplisit.

Pembolehubah Malar

Peraturan lain yang perlu diingat ialah antara muka hanya boleh mengandungi pembolehubah malar. Berikut ialah contoh:
public class Challenger {

  int number = 7;
  String name = "Java Challenger";

}
Di sini kedua-dua pembolehubah adalah muktamad dan statik tersirat . Ini bermakna bahawa ia adalah tetap, bebas daripada contoh, dan tidak boleh diubah. Sekarang kita akan cuba menukar pembolehubah dalam antara muka Challenger , katakan seperti ini:
Challenger.number = 8;
Challenger.name = "Another Challenger";
Ini akan menyebabkan ralat penyusunan:
Tidak boleh memberikan nilai kepada 'nombor' pembolehubah akhir Tidak boleh memberikan nilai kepada 'nama' pembolehubah akhir

Kaedah Lalai

Apabila kaedah lalai diperkenalkan dalam Java 8, sesetengah pembangun berpendapat ia akan sama dengan kelas abstrak. Walau bagaimanapun, ini tidak benar kerana antara muka tidak boleh mempunyai keadaan. Kaedah lalai mungkin mempunyai pelaksanaan, tetapi kaedah abstrak tidak. Kaedah lalai adalah hasil daripada inovasi dengan ekspresi dan aliran lambda, tetapi kita mesti menggunakannya dengan berhati-hati. Kaedah dalam JDK yang menggunakan kaedah lalai ialah forEach() , yang merupakan sebahagian daripada antara muka Iterable . Daripada menyalin kod ke dalam setiap pelaksanaan Iterable , kita hanya boleh menggunakan semula kaedah forEach :
default void forEach(Consumer<? super T> action) {
  // Code implementation here...
Sebarang pelaksanaan Iterable boleh menggunakan kaedah forEach() tanpa memerlukan pelaksanaan kaedah baharu. Kami kemudiannya boleh menggunakan semula kod dengan kaedah lalai. Mari buat kaedah lalai kita sendiri:
public class DefaultMethodExample {

  public static void main(String[] args) {
    Challenger challenger = new JavaChallenger();
    challenger.doChallenge();
  }

}

class JavaChallenger implements Challenger { }

interface Challenger {

  default void doChallenge() {
    System.out.println("Challenger doing a challenge!");
  }
}
Keputusan:
Pencabar melakukan cabaran!
Berkenaan dengan kaedah lalai, adalah penting untuk diperhatikan bahawa setiap kaedah tersebut perlu dilaksanakan. Kaedah lalai tidak boleh statik. Sekarang mari kita beralih ke kelas abstrak.

Intipati kelas abstrak

Kelas abstrak boleh mempunyai keadaan dengan pembolehubah contoh. Ini bermakna pembolehubah contoh boleh digunakan dan diubah suai. Berikut ialah contoh:
public abstract class AbstractClassMutation {

  private String name = "challenger";

  public static void main(String[] args) {
    AbstractClassMutation abstractClassMutation = new AbstractClassImpl();
    abstractClassMutation.name = "mutated challenger";
    System.out.println(abstractClassMutation.name);
  }

}

class AbstractClassImpl extends AbstractClassMutation { }
Kesimpulan:
pencabar bermutasi

Kaedah abstrak dalam kelas abstrak

Seperti antara muka, kelas abstrak boleh mempunyai kaedah abstrak. Kaedah abstrak ialah kaedah tanpa badan. Tidak seperti antara muka, kaedah abstrak dalam kelas abstrak mesti diisytiharkan abstrak secara eksplisit. Berikut adalah contoh:
public abstract class AbstractMethods {

  abstract void doSomething();

}
Dan inilah percubaan untuk mengisytiharkan kaedah tanpa pelaksanaan dan tanpa kata kunci abstrak :
public abstract class AbstractMethods {
   void doSomethingElse();
}
Malangnya, ia mengakibatkan ralat penyusunan:
Badan kaedah tiada, atau isytihar abstrak

Bila hendak menggunakan kelas abstrak

Kelas abstrak disyorkan apabila anda perlu melaksanakan keadaan boleh ubah. Sebagai contoh, Rangka Kerja Koleksi Java termasuk kelas AbstractList yang menggunakan keadaan pembolehubah. Dalam kes di mana anda tidak perlu mengekalkan keadaan kelas, biasanya lebih baik menggunakan antara muka.

Perbezaan antara kelas abstrak dan antara muka

Dari perspektif pengaturcaraan berorientasikan objek, perbezaan utama antara antara muka dan kelas abstrak ialah antara muka tidak boleh mempunyai keadaan, manakala kelas abstrak boleh mempunyai keadaan dengan pembolehubah contoh. Satu lagi perbezaan utama ialah kelas boleh melaksanakan lebih daripada satu antara muka, tetapi mereka hanya boleh melanjutkan satu kelas abstrak. Penyelesaian ini berdasarkan fakta bahawa warisan berbilang (melanjutkan lebih daripada satu kelas) boleh membawa kepada kebuntuan kod. Pembangun bahasa Java memutuskan untuk mengelakkan ini. Perbezaan lain ialah antara muka boleh dilaksanakan oleh kelas atau dilanjutkan oleh antara muka, tetapi kelas hanya boleh dilanjutkan. Adalah penting untuk ambil perhatian bahawa ungkapan lambda hanya boleh digunakan dengan antara muka berfungsi (bermaksud antara muka dengan hanya satu kaedah), manakala kelas abstrak dengan hanya satu kaedah abstrak tidak boleh menggunakan ungkapan lambda. Berikut adalah beberapa lagi perbezaan antara kelas abstrak dan antara muka. Antara muka:
  • Hanya boleh mempunyai pembolehubah statik akhir. Antara muka tidak boleh mengubah keadaannya sendiri.
  • Kelas boleh melaksanakan berbilang antara muka.
  • Boleh dilaksanakan menggunakan kata kunci implements. Antara muka boleh memanjangkan antara muka lain.
  • Kaedah hanya boleh menggunakan medan akhir statik, parameter atau pembolehubah setempat.
  • Hanya antara muka berfungsi boleh menggunakan fungsi lambda dalam Java.
  • Tidak boleh mempunyai pembina.
  • Mungkin mempunyai kaedah abstrak.
  • Boleh mempunyai kaedah lalai dan statik (diperkenalkan dalam Java 8).
  • Boleh mempunyai kaedah peribadi dengan pelaksanaan (diperkenalkan dalam Java 9).
Kelas abstrak:
  • Boleh mempunyai sebarang contoh atau pembolehubah statik, boleh ubah atau tidak berubah.
  • Kelas hanya boleh memanjangkan satu kelas abstrak.
  • Mungkin mempunyai contoh medan boleh ubah, parameter atau pembolehubah setempat.
  • Kelas abstrak dengan hanya satu kaedah abstrak tidak boleh menggunakan ungkapan lambda.
  • Mungkin mempunyai pembina.
  • Boleh mempunyai apa-apa kaedah.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION