JavaRush /Java Blog /Random-ID /Perbedaan antara kelas abstrak dan antarmuka

Perbedaan antara kelas abstrak dan antarmuka

Dipublikasikan di grup Random-ID
Halo! Dalam kuliah ini, kita akan membahas tentang perbedaan kelas abstrak dari antarmuka dan melihat contoh kelas abstrak umum. Perbedaan antara kelas abstrak dan antarmuka - 1Kami memberikan kuliah terpisah tentang perbedaan antara kelas abstrak dan antarmuka, karena topiknya sangat penting. Anda akan ditanya tentang perbedaan antara konsep-konsep ini dalam 90% wawancara selanjutnya. Oleh karena itu, pastikan untuk memahami apa yang Anda baca, dan jika Anda belum sepenuhnya memahami sesuatu, bacalah sumber tambahan. Jadi, kita tahu apa itu kelas abstrak dan apa itu antarmuka. Sekarang mari kita bahas perbedaannya.
  1. Antarmuka hanya menjelaskan perilaku. Dia tidak punya kekayaan. Tapi kelas abstrak memiliki keadaan: ia menjelaskan keduanya.

    Mari kita ambil kelas abstrak Birddan antarmuka 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 kita buat kelas burung Mockingjay(mockingjay) dan mewarisi dari 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 dapat dengan mudah mengakses status kelas abstrak - variabelnya species(tipe) dan age(usia).

    Namun jika kita mencoba melakukan hal yang sama dengan antarmuka, gambarannya akan berbeda. Kita dapat mencoba menambahkan variabel ke dalamnya:

    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 bahkan tidak dapat membuat variabel pribadi di dalam antarmuka. Mengapa? Karena pengubah privat dibuat untuk menyembunyikan implementasi dari pengguna. Namun tidak ada implementasi di dalam antarmuka: tidak ada yang disembunyikan di sana.

    Antarmuka hanya menjelaskan perilakunya. Oleh karena itu, kami tidak akan dapat mengimplementasikan getter dan setter di dalam antarmuka. Itulah sifat antarmuka: dimaksudkan untuk menangani perilaku, bukan keadaan.

    Java8 memperkenalkan metode antarmuka default yang memiliki implementasi. Anda sudah mengetahuinya, jadi kami tidak akan mengulanginya.

  2. Kelas abstrak menghubungkan dan menyatukan kelas-kelas yang mempunyai hubungan yang sangat erat. Pada saat yang sama, antarmuka yang sama dapat diimplementasikan oleh kelas-kelas yang tidak memiliki kesamaan sama sekali.

    Mari kembali ke contoh kita dengan burung.

    Kelas abstrak kita Birddiperlukan untuk membuat burung berdasarkan itu. Hanya burung dan tidak ada orang lain! Tentu saja keduanya akan berbeda.

    Perbedaan antara kelas abstrak dan antarmuka - 2

    Dengan antarmuka Flyablesemuanya berbeda. Itu hanya menggambarkan perilaku yang sesuai dengan namanya - "terbang". Yang dimaksud dengan “terbang”, “mampu terbang” mencakup banyak benda yang tidak berhubungan satu sama lain.

    Perbedaan antara kelas abstrak dan antarmuka - 3

    Keempat entitas ini tidak terkait satu sama lain dengan cara apa pun. Apa yang bisa saya katakan, tidak semuanya bernyawa. Namun, mereka semua Flyablemampu terbang.

    Kami tidak akan dapat mendeskripsikannya menggunakan kelas abstrak. Mereka tidak memiliki negara bagian yang sama atau bidang yang identik. Untuk mengkarakterisasi sebuah pesawat, kita mungkin memerlukan kolom “model”, “tahun pembuatan”, dan “jumlah penumpang maksimum”. Bagi Carlson, ada kolom untuk semua manisan yang dia makan hari ini, dan daftar permainan yang akan dia mainkan bersama Kid. Untuk seekor nyamuk...uh-uh...kita bahkan tidak tahu... Mungkin “tingkat gangguannya”? :)

    Hal utama adalah kita tidak dapat mendeskripsikannya menggunakan kelas abstrak. Mereka terlalu berbeda. Tapi ada perilaku umum: mereka bisa terbang. Antarmukanya ideal untuk mendeskripsikan segala sesuatu di dunia yang bisa terbang, berenang, melompat, atau berperilaku lainnya.

  3. Kelas dapat mengimplementasikan antarmuka sebanyak yang mereka inginkan, namun mereka hanya dapat mewarisi dari satu kelas.

    Kami telah membicarakan hal ini lebih dari sekali. Tidak ada pewarisan berganda di Java, tetapi ada implementasi berganda. Poin ini sebagian mengikuti poin sebelumnya: sebuah antarmuka menghubungkan banyak kelas berbeda yang seringkali tidak memiliki kesamaan, dan kelas abstrak dibuat untuk sekelompok kelas yang sangat dekat satu sama lain. Oleh karena itu, logis jika Anda hanya dapat mewarisi dari satu kelas tersebut. Kelas abstrak menggambarkan hubungan “adalah”.

Antarmuka InputStream & OutputStream Standar

Kita telah mempelajari berbagai kelas yang bertanggung jawab atas input dan output streaming. Mari kita lihat InputStreamdan OutputStream. Secara umum, ini bukan antarmuka, tetapi kelas abstrak nyata. Sekarang Anda tahu apa itu, jadi bekerja dengannya akan lebih mudah :) InputStream- ini adalah kelas abstrak yang bertanggung jawab atas input byte. Java memiliki serangkaian kelas yang diwarisi dari InputStream. Masing-masing dikonfigurasi untuk menerima data dari sumber berbeda. Karena InputStreammerupakan induk, ia menyediakan beberapa metode untuk bekerja dengan aliran data dengan nyaman. Setiap anak mempunyai metode berikut InputStream:
  • int available()mengembalikan jumlah byte yang tersedia untuk dibaca;
  • close()menutup sumber masukan;
  • int read()mengembalikan representasi integer dari byte berikutnya yang tersedia di aliran. Jika akhir aliran tercapai, angka -1 akan dikembalikan;
  • int read(byte[] buffer)mencoba membaca byte ke dalam buffer, mengembalikan jumlah byte yang dibaca. Ketika mencapai akhir file, ia mengembalikan -1;
  • int read(byte[] buffer, int byteOffset, int byteCount)membaca bagian dari satu blok byte. Digunakan bila ada kemungkinan blok data tidak terisi penuh. Ketika mencapai akhir file, kembalikan -1;
  • long skip(long byteCount)skips byteCount, satu byte masukan, mengembalikan jumlah byte yang diabaikan.
Saya menyarankan Anda untuk mempelajari daftar lengkap metode . Sebenarnya ada lebih dari selusin kelas penerus. Berikut beberapa contohnya:
  1. FileInputStream: tipe yang paling umum InputStream. Digunakan untuk membaca informasi dari suatu file;
  2. StringBufferInputStream: tipe lain yang berguna InputStream. Ini mengubah string menjadi aliran data masukan InputStream;
  3. BufferedInputStream: aliran input yang di-buffer. Ini paling sering digunakan untuk meningkatkan efisiensi.
Apakah Anda ingat ketika kami lewat BufferedReaderdan berkata bahwa kami tidak perlu menggunakannya? Saat kita menulis:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReadertidak perlu menggunakannya: InputStreamReaderitu akan berhasil. Namun BufferedReaderia melakukannya dengan lebih efisien dan, terlebih lagi, dapat membaca data di seluruh baris, daripada karakter individual. Semua BufferedInputStreamsama! Kelas mengumpulkan data masukan dalam buffer khusus tanpa terus-menerus mengakses perangkat masukan. Mari kita lihat sebuah 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, kita membaca data dari file yang terletak di komputer dengan alamat "D:/Users/UserName/someFile.txt" . Kami membuat 2 objek - FileInputStreamdan BufferedInputStreamsebagai "pembungkusnya". Setelah itu, kita membaca byte dari file dan mengubahnya menjadi karakter. Begitu seterusnya hingga file berakhir. Seperti yang Anda lihat, tidak ada yang rumit di sini. Anda dapat menyalin kode ini dan menjalankannya pada beberapa file nyata yang disimpan di komputer Anda :) Kelas OutputStreamadalah kelas abstrak yang mendefinisikan keluaran aliran byte. Seperti yang sudah Anda pahami, ini adalah antipode dari InputStream'a. Ia bertanggung jawab bukan atas dari mana membaca data, tetapi ke mana mengirimkannya . Seperti InputStream, kelas abstrak ini memberi semua keturunan sekelompok metode untuk pekerjaan yang nyaman:
  • int close()menutup aliran keluaran;
  • void flush()menghapus semua buffer keluaran;
  • abstract void write (int oneByte)menulis 1 byte ke aliran keluaran;
  • void write (byte[] buffer)menulis array byte ke aliran keluaran;
  • void write (byte[] buffer, int offset, int count)menulis rentang hitungan byte dari array, dimulai dari posisi offset.
Berikut adalah beberapa keturunan kelas tersebut OutputStream:
  1. DataOutputStream. Aliran keluaran yang mencakup metode untuk menulis tipe data Java standar.

    Kelas yang sangat sederhana untuk menulis tipe dan string Java primitif. Pastinya Anda akan memahami kode tertulis meski 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);
    
       }
    }

    Ini memiliki metode terpisah untuk setiap jenis - writeDouble(), writeLong(), writeShort()dan seterusnya.

  2. Kelas FileOutputStream . Mengimplementasikan mekanisme pengiriman data ke file di disk. Ngomong-ngomong, kita sudah menggunakannya pada contoh sebelumnya, apakah Anda memperhatikan? Kami meneruskannya ke dalam DataOutputStream, yang bertindak sebagai "pembungkus".

  3. BufferedOutputStream. Aliran keluaran yang disangga. Tidak ada yang ribet juga, intinya sama seperti di BufferedInputStream(atau BufferedReader'a). Alih-alih merekam data berurutan seperti biasa, digunakan rekaman melalui buffer "penyimpanan" khusus. Dengan menggunakan buffer, Anda dapat mengurangi jumlah perjalanan bolak-balik ke tujuan data dan dengan demikian meningkatkan efisiensi.

    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 dapat "bermain" sendiri dengan kode ini dan memeriksa cara kerjanya pada file nyata di komputer Anda.

Anda juga dapat membaca tentang ahli waris pada materi “ Sistem InputStreamInput /Output ”. Oh , dan kami juga akan mengadakan kuliah terpisah, jadi informasi tentang mereka cukup untuk kenalan pertama. Itu saja! Kami harap Anda memiliki pemahaman yang baik tentang perbedaan antara antarmuka dan kelas abstrak dan siap menjawab pertanyaan apa pun, bahkan pertanyaan rumit :) OutputStreamFileInputStreamFileOutputStreamBufferedInputStream
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION