Hai! Mari kita bercakap tentang kelas abstrak di Jawa.Contoh konkrit kelas abstrak dalam Java - 1

Mengapakah kelas dipanggil "abstrak"?

Anda mungkin masih ingat apa itu abstraksi — kami telah membincangkannya lebih awal :) Jika anda terlupa, jangan risau. Ingat, ini adalah prinsip OOP yang mengatakan, apabila mereka bentuk kelas dan mencipta objek, anda harus mewakili hanya sifat utama entiti dan buang yang kedua. Sebagai contoh, jika kita mereka bentuk SchoolTeacherkelas, ketinggian mungkin tidak akan menjadi harta yang diperlukan seorang guru. Sememangnya ciri ini tidak penting bagi seorang guru. Tetapi jika kita mencipta BasketballPlayerkelas, maka ketinggian akan menjadi salah satu ciri yang paling penting. Nah, kelas abstrakialah "bahan kerja kasar" yang paling abstrak untuk sekumpulan kelas masa hadapan. Bahan kerja tidak boleh digunakan secara langsung — ia terlalu "kasar". Tetapi ia mentakrifkan keadaan ciri dan tingkah laku tertentu yang akan dimiliki oleh kelas masa depan - keturunan kelas abstrak.

Contoh kelas abstrak dalam Java

Pertimbangkan contoh mudah dengan kereta:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
Inilah rupa kelas abstrak yang paling mudah. Seperti yang anda lihat, tiada yang istimewa :) Mengapakah kita memerlukan ini? Pertama, ia memberikan penerangan paling abstrak tentang entiti yang kami perlukan — sebuah kereta. Kata kunci abstrak bermaksud sesuatu di sini. Di dunia nyata, tiada perkara seperti "sekadar kereta". Terdapat trak, kereta lumba, sedan, coupe dan SUV. Kelas abstrak kami hanyalah "cetak biru" yang akan kami gunakan kemudian untuk membuat kelas kereta tertentu.

public class Sedan extends Car {
  
   @Override
   public void gas() {
       System.out.println("The sedan is accelerating!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }
  
}
Dalam banyak cara, ini serupa dengan apa yang kita bincangkan dalam pelajaran tentang warisan. Hanya dalam kes itu kami mempunyai Carkelas yang kaedahnya tidak abstrak. Tetapi penyelesaian sedemikian mempunyai beberapa kelemahan yang ditetapkan dalam kelas abstrak. Pertama sekali, contoh kelas abstrak tidak boleh dibuat:

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Pencipta Java sengaja membuat "ciri" ini. Sekali lagi, ingat: kelas abstrak hanyalah rangka tindakan untuk kelas "biasa" masa hadapan . Anda tidak memerlukan salinan pelan tindakan, bukan? Begitu juga, tidak perlu mencipta contoh kelas abstrak :) Dan jika Carkelas itu bukan abstrak, maka kita boleh mencipta contoh kelas itu dengan mudah:

public class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public void go() {
       // ...some logic
   }

   public  void brake() {
       // ...some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // This is okay. The car is created.
   }
}
Pada masa ini, program kami mempunyai beberapa jenis kereta yang tidak dapat difahami. Ia bukan trak, bukan kereta lumba, dan bukan sedan, tetapi ia tidak begitu jelas apa itu. Ia adalah "hanya kereta" yang tidak wujud dalam realiti. Contoh yang sama boleh diberikan dengan haiwan. Bayangkan jika program anda mempunyai Animalobjek (" hanya haiwan "). Tidak jelas jenisnya, keluarga apa, atau ciri-cirinya. Ia akan menjadi pelik untuk melihat satu dalam program. Tiada "hanya haiwan" dalam alam semula jadi. Hanya anjing, kucing, musang, tahi lalat, dsb. Kelas abstrak menyelamatkan kita daripada " objek sahaja ". Mereka memberi kita keadaan dan tingkah laku garis dasar. Sebagai contoh, semua kereta mesti mempunyai model , warna dan kelajuan tertinggi, dan mereka juga mesti boleh menggunakan gas dan brek . Itu sahaja. Ia adalah pelan tindakan abstrak umum yang akan anda gunakan kemudian untuk mereka bentuk kelas yang anda perlukan. Nota: kedua-dua kaedah dalam kelas abstrak juga abstract , yang bermaksud ia tidak mempunyai pelaksanaan sama sekali. Sebabnya adalah sama: kelas abstrak tidak mencipta "tingkah laku lalai" untuk "hanya kereta". Mereka hanya menunjukkan apa yang setiap kereta mesti boleh lakukan. Yang berkata, jika anda memerlukan tingkah laku lalai, anda boleh melaksanakan kaedah dalam kelas abstrak. Java tidak melarang ini:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Accelerating!");
   }

   public abstract void brake();
  
   // Getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan is slowing down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Output konsol:
Accelerating!
Seperti yang anda lihat, kami melaksanakan satu kaedah dalam kelas abstrak, tetapi bukan yang lain. Akibatnya, tingkah laku Sedankelas kami dibahagikan kepada dua bahagian: jika kami memanggil kaedahnya gas(), tingkah laku itu "ditarik" daripada Carkelas induk abstrak, dan kami melaksanakan brake()kaedah itu dalam Sedankelas. Itu sangat mudah dan fleksibel. Tetapi kelas kita tidak begitu abstrak sekarang, bukan ? Lagipun, ia sebenarnya melaksanakan separuh daripada kaedah. Hakikatnya - dan ini adalah ciri yang sangat penting - kelas adalah abstrak jika walaupun salah satu kaedahnya adalah abstrak. Satu kaedah dua, atau satu daripada seribu — tidak mengapa. Kami juga boleh melaksanakan semua kaedah, tidak meninggalkan satu pun abstrak. Hasilnya akan menjadi kelas abstrak tanpa sebarang kaedah abstrak. Ini mungkin pada dasarnya — pengkompil tidak akan menghasilkan sebarang ralat — tetapi lebih baik jangan lakukan ini, kerana ia menafikan perkataan abstrak daripada maknanya. Rakan pengaturcara anda juga akan sangat terkejut melihat ini :/ Yang berkata, jika kaedah ditandakan sebagai abstrak, setiap kelas keturunan mesti melaksanakannya atau diisytiharkan sebagai abstrak. Jika tidak, pengkompil akan membuang ralat. Sudah tentu, setiap kelas hanya boleh mewarisi satu kelas abstrak, jadi tidak ada perbezaan antara kelas abstrak dan biasa dari segi pewarisan. Tidak kira sama ada kita mewarisi kelas abstrak atau kelas biasa — hanya boleh ada satu kelas induk.

Mengapa Java tidak mempunyai warisan kelas berbilang

Kami telah mengatakan bahawa tidak ada warisan berbilang di Jawa, tetapi kami tidak benar-benar menyelidiki mengapa. Mari cuba lakukannya sekarang. Hakikatnya ialah jika Java mempunyai banyak warisan, maka kelas kanak-kanak tidak akan dapat menentukan tingkah laku yang hendak dipilih. Katakan kita mempunyai dua kelas: Toasterdan NuclearBomb:

public class Toaster {
  
  
 public void on() {

       System.out.println("The toaster is on. We're toasting!");
   }
  
   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Boom!");
   }
}
Seperti yang anda lihat, kedua-dua kelas mempunyai on()kaedah. Untuk pembakar roti, kaedah mula membuat roti bakar, tetapi dalam kes bom nuklear, ia mencetuskan letupan. Uh-oh :/ Sekarang bayangkan anda telah memutuskan (jangan tanya saya mengapa!) untuk mencipta sesuatu di antaranya. Inilah kelas anda: MysteriousDevice! Kod ini tidak akan berfungsi, sudah tentu. Kami membentangkannya secara ringkas sebagai contoh "apa yang mungkin berlaku":

public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {
      
       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get toast or a nuclear apocalypse?
   }
}
Mari lihat apa yang kita ada. Peranti misteri itu berasal daripada Pembakar Roti dan Bom Nuklear pada masa yang sama. Kedua-duanya mempunyai on()kaedah. Akibatnya, tidak jelas pelaksanaan mana yang harus dilaksanakan jika kita memanggil on()objek MysteriousDevice. Objek tidak akan faham. Dan untuk mengatasi semuanya, NuclearBomb tidak mempunyai off()kaedah, jadi jika kita tidak meneka dengan betul, maka mustahil untuk mematikan peranti. Contoh konkrit kelas abstrak dalam Java - 2"Salah faham" ini, apabila tidak jelas tingkah laku yang harus dilaksanakan, sebenarnya adalah sebab mengapa pencipta Java menolak warisan berbilang. Yang berkata, anda akan mengetahui bahawa kelas Java boleh melaksanakan banyak antara muka.