JavaRush /Blog Java /Random-MS /Perbezaan antara kelas abstrak dan antara muka

Perbezaan antara kelas abstrak dan antara muka

Diterbitkan dalam kumpulan
hello! Dalam kuliah ini, kita akan bercakap tentang cara kelas abstrak berbeza daripada antara muka dan melihat contoh dengan kelas abstrak biasa. Perbezaan antara kelas abstrak dan antara muka - 1Kami menumpukan syarahan berasingan kepada perbezaan antara kelas abstrak dan antara muka, kerana topik itu sangat penting. Anda akan ditanya tentang perbezaan antara konsep ini dalam 90% temu bual akan datang. Oleh itu, pastikan anda memahami apa yang anda baca, dan jika anda tidak memahami sepenuhnya sesuatu, baca sumber tambahan. Jadi, kita tahu apa itu kelas abstrak dan apa itu antara muka. Sekarang mari kita lalui perbezaan mereka.
  1. Antara muka hanya menerangkan tingkah laku. Dia tiada rezeki. Tetapi kelas abstrak mempunyai keadaan: ia menerangkan kedua-duanya.

    Mari kita ambil kelas abstrak Birddan antara muka sebagai contoh Flyable:

    public abstract class Bird {
       private String species;
       private int age;
    
       public abstract void fly();
    
       public String getSpecies() {
           return species;
       }
    
       public void setSpecies(String species) {
           this.species = species;
       }
    
       public int getAge() {
           return age;
       }
    
       public void setAge(int age) {
           this.age = age;
       }
    }

    Mari buat kelas burung Mockingjay(mockingjay) dan warisi daripada Bird:

    public class Mockingjay extends Bird {
    
       @Override
       public void fly() {
           System.out.println("Fly, birdie!");
       }
    
       public static void main(String[] args) {
    
           Mockingjay someBird = new Mockingjay();
           someBird.setAge(19);
           System.out.println(someBird.getAge());
       }
    }

    Seperti yang anda lihat, kita boleh mengakses keadaan kelas abstrak dengan mudah - pembolehubahnya species(jenis) dan age(umur).

    Tetapi jika kita cuba melakukan perkara yang sama dengan antara muka, gambar akan berbeza. Kita boleh cuba menambah pembolehubah kepadanya:

    public interface Flyable {
    
       String species = new String();
       int age = 10;
    
       public void fly();
    }
    
    public interface Flyable {
    
       private String species = new String(); // error
       private int age = 10; // also an error
    
       public void fly();
    }

    Kami tidak akan dapat mencipta pembolehubah peribadi di dalam antara muka. kenapa? Kerana pengubah suai peribadi dicipta untuk menyembunyikan pelaksanaan daripada pengguna. Tetapi tiada pelaksanaan di dalam antara muka: tiada apa yang perlu disembunyikan di sana.

    Antara muka hanya menerangkan tingkah laku. Sehubungan itu, kami tidak akan dapat melaksanakan getter dan setter di dalam antara muka. Itulah sifat antara muka: ia bertujuan untuk menangani tingkah laku, bukan menyatakan.

    Java8 memperkenalkan kaedah antara muka lalai yang mempunyai pelaksanaan. Anda sudah tahu tentang mereka, jadi kami tidak akan mengulanginya.

  2. Kelas abstrak memaut dan menggabungkan kelas yang mempunyai hubungan yang sangat rapat. Pada masa yang sama, antara muka yang sama boleh dilaksanakan oleh kelas yang tidak mempunyai persamaan sama sekali.

    Mari kita kembali kepada contoh kita dengan burung.

    Kelas abstrak kami Birddiperlukan untuk mencipta burung berdasarkannya. Hanya burung dan tidak ada orang lain! Sudah tentu mereka akan berbeza.

    Perbezaan antara kelas abstrak dan antara muka - 2

    Dengan antara muka Flyablesemuanya berbeza. Ia hanya menerangkan tingkah laku yang sepadan dengan namanya - "terbang". Takrifan "terbang", "mampu terbang" merangkumi banyak objek yang tidak berkaitan antara satu sama lain.

    Perbezaan antara kelas abstrak dan antara muka - 3

    4 entiti ini tidak berkaitan antara satu sama lain dalam apa cara sekalipun. Apa yang boleh saya katakan, tidak semuanya bernyawa. Walau bagaimanapun, mereka semua Flyablemampu terbang.

    Kami tidak akan dapat menerangkannya menggunakan kelas abstrak. Mereka tidak mempunyai keadaan yang sama atau medan yang sama. Untuk mencirikan pesawat, kita mungkin memerlukan medan "model", "tahun pembuatan" dan "bilangan penumpang maksimum". Bagi Carlson, terdapat ladang untuk semua gula-gula yang dia makan hari ini, dan senarai permainan yang akan dia mainkan dengan Kid. Untuk nyamuk...uh-uh...kita pun tak tahu... Mungkin "tahap kegusaran"? :)

    Perkara utama ialah kita tidak boleh menerangkannya menggunakan kelas abstrak. Mereka terlalu berbeza. Tetapi ada tingkah laku biasa: mereka boleh terbang. Antara muka sesuai untuk menerangkan segala-galanya di dunia yang boleh terbang, berenang, melompat atau mempunyai beberapa tingkah laku lain.

  3. Kelas boleh melaksanakan seberapa banyak antara muka yang mereka mahu, tetapi mereka hanya boleh mewarisi daripada satu kelas.

    Kami telah membincangkan perkara ini lebih daripada sekali. Tiada warisan berbilang di Jawa, tetapi terdapat pelbagai pelaksanaan. Perkara ini sebahagiannya mengikuti daripada yang sebelumnya: antara muka menghubungkan banyak kelas berbeza yang selalunya tidak mempunyai persamaan, dan kelas abstrak dicipta untuk sekumpulan kelas yang sangat rapat antara satu sama lain. Oleh itu, adalah logik bahawa anda boleh mewarisi hanya satu kelas sedemikian. Kelas abstrak menerangkan hubungan "adalah".

Antara Muka InputStream & OutputStream Standard

Kami telah melalui pelbagai kelas yang bertanggungjawab untuk penstriman input dan output. Jom tengok InputStreamdan OutputStream. Secara umum, ini bukan antara muka, tetapi kelas abstrak sebenar. Sekarang anda tahu apa itu, jadi bekerja dengan mereka akan menjadi lebih mudah :) InputStream- ini adalah kelas abstrak yang bertanggungjawab untuk input bait. Java mempunyai satu siri kelas yang mewarisi daripada InputStream. Setiap daripada mereka dikonfigurasikan untuk menerima data daripada sumber yang berbeza. Kerana InputStreamia adalah ibu bapa, ia menyediakan beberapa kaedah untuk bekerja dengan mudah dengan aliran data. Setiap kanak-kanak mempunyai kaedah ini InputStream:
  • int available()mengembalikan bilangan bait yang tersedia untuk dibaca;
  • close()menutup sumber input;
  • int read()mengembalikan perwakilan integer bagi bait seterusnya yang tersedia dalam strim. Jika penghujung aliran dicapai, nombor -1 akan dikembalikan;
  • int read(byte[] buffer)cuba membaca bait ke dalam penimbal, mengembalikan bilangan bait yang dibaca. Apabila ia mencapai penghujung fail, ia mengembalikan -1;
  • int read(byte[] buffer, int byteOffset, int byteCount)membaca sebahagian daripada blok bait. Digunakan apabila terdapat kemungkinan blok data tidak diisi sepenuhnya. Apabila ia mencapai penghujung fail, mengembalikan -1;
  • long skip(long byteCount)langkau byteCount, bait input, mengembalikan bilangan bait diabaikan.
Saya menasihati anda untuk mengkaji senarai penuh kaedah . Sebenarnya terdapat lebih daripada sedozen kelas pengganti. Berikut adalah beberapa contoh:
  1. FileInputStream: jenis yang paling biasa InputStream. Digunakan untuk membaca maklumat daripada fail;
  2. StringBufferInputStream: jenis lain yang berguna InputStream. Ia menukar rentetan menjadi aliran data input InputStream;
  3. BufferedInputStream: aliran input buffer. Ia paling kerap digunakan untuk meningkatkan kecekapan.
Adakah anda masih ingat ketika kami berjalan BufferedReaderdan berkata bahawa kami tidak perlu menggunakannya? Apabila kita menulis:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReadertidak perlu menggunakannya: InputStreamReaderia akan melakukan kerja. Tetapi BufferedReaderia melakukannya dengan lebih cekap dan, lebih-lebih lagi, boleh membaca data dalam keseluruhan baris, bukannya aksara individu. Semuanya BufferedInputStreamsama! Kelas mengumpul data input dalam penimbal khas tanpa sentiasa mengakses peranti input. Mari lihat contoh:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;

public class BufferedInputExample {

   public static void main(String[] args) throws Exception {
       InputStream inputStream = null;
       BufferedInputStream buffer = null;

       try {

           inputStream = new FileInputStream("D:/Users/UserName/someFile.txt");

           buffer = new BufferedInputStream(inputStream);

           while(buffer.available()>0) {

               char c = (char)buffer.read();

               System.out.println("Character was read" + c);
           }
       } catch(Exception e) {

           e.printStackTrace();

       } finally {

           inputStream.close();
           buffer.close();
       }
   }
}
Dalam contoh ini, kami sedang membaca data daripada fail yang terletak pada komputer di alamat "D:/Users/UserName/someFile.txt" . Kami mencipta 2 objek - FileInputStreamdan BufferedInputStreamsebagai "pembungkus". Selepas itu, kami membaca bait daripada fail dan menukarnya menjadi aksara. Dan seterusnya sehingga fail tamat. Seperti yang anda lihat, tidak ada yang rumit di sini. Anda boleh menyalin kod ini dan menjalankannya pada beberapa fail sebenar yang disimpan pada komputer anda :) Kelas OutputStreamialah kelas abstrak yang mentakrifkan output aliran bait. Seperti yang anda sudah faham, ini adalah antipoda InputStream'a. Ia bertanggungjawab bukan untuk dari mana untuk membaca data, tetapi untuk ke mana untuk menghantarnya . Seperti InputStream, kelas abstrak ini menyediakan semua keturunan dengan sekumpulan kaedah untuk kerja yang mudah:
  • int close()menutup aliran keluaran;
  • void flush()mengosongkan semua penimbal keluaran;
  • abstract void write (int oneByte)menulis 1 bait ke aliran keluaran;
  • void write (byte[] buffer)menulis tatasusunan bait ke aliran keluaran;
  • void write (byte[] buffer, int offset, int count)menulis julat bait kiraan daripada tatasusunan, bermula pada posisi mengimbangi.
Berikut adalah beberapa keturunan kelas OutputStream:
  1. DataOutputStream. Strim output yang merangkumi kaedah untuk menulis jenis data Java standard.

    Kelas yang sangat mudah untuk menulis jenis dan rentetan Java primitif. Pasti anda akan memahami kod bertulis walaupun tanpa penjelasan:

    import java.io.*;
    
    public class DataOutputStreamExample {
    
       public static void main(String[] args) throws IOException {
    
           DataOutputStream dos = new DataOutputStream(new FileOutputStream("testFile.txt"));
    
           dos.writeUTF("SomeString");
           dos.writeInt(22);
           dos.writeDouble(1.21323);
           dos.writeBoolean(true);
    
       }
    }

    Ia mempunyai kaedah berasingan untuk setiap jenis - writeDouble(), writeLong(), writeShort()dan seterusnya.

  2. Kelas FileOutputStream . Melaksanakan mekanisme untuk menghantar data ke fail pada cakera. By the way, kita sudah menggunakannya dalam contoh sebelumnya, adakah anda perasan? Kami menghantarnya ke dalam DataOutputStream, yang bertindak sebagai "pembungkus".

  3. BufferedOutputStream. Aliran keluaran penimbal. Tiada yang rumit sama ada, intipatinya sama seperti dalam BufferedInputStream(atau BufferedReader'a). Daripada rakaman data berurutan yang biasa, rakaman melalui penimbal "storan" khas digunakan. Dengan menggunakan penimbal, anda boleh mengurangkan bilangan perjalanan pergi dan balik ke destinasi data dan dengan itu meningkatkan kecekapan.

    import java.io.*;
    
    public class DataOutputStreamExample {
    
       public static void main(String[] args) throws IOException {
    
           FileOutputStream outputStream = new FileOutputStream("D:/Users/Username/someFile.txt");
           BufferedOutputStream bufferedStream = new BufferedOutputStream(outputStream);
    
           String text = "I love Java!"; // we will convert this string into an array of bytes and write it to a file
    
           byte[] buffer = text.getBytes();
    
           bufferedStream.write(buffer, 0, buffer.length);
           bufferedStream.close();
       }
    }

    Sekali lagi, anda boleh "bermain" dengan kod ini sendiri dan menyemak cara ia akan berfungsi pada fail sebenar pada komputer anda.

Anda juga boleh membaca tentang waris dalam bahan " Sistem InputStreamInput / Output ". Oh , dan kami juga akan mengadakan kuliah berasingan, jadi terdapat maklumat yang mencukupi tentang mereka untuk kenalan pertama. Itu sahaja! Kami harap anda mempunyai pemahaman yang baik tentang perbezaan antara antara muka dan kelas abstrak dan bersedia untuk menjawab sebarang soalan, walaupun soalan yang rumit :) OutputStreamFileInputStreamFileOutputStreamBufferedInputStream
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION