CodeGym/Java Blog/Acak/Perbedaan antara kelas abstrak dan antarmuka
John Squirrels
Level 41
San Francisco

Perbedaan antara kelas abstrak dan antarmuka

Dipublikasikan di grup Acak
anggota
Hai! Dalam pelajaran ini, kita akan berbicara tentang bagaimana kelas abstrak berbeda dari antarmuka dan mempertimbangkan beberapa contoh dengan kelas abstrak umum. Perbedaan antara kelas abstrak dan antarmuka - 1Kami telah mencurahkan pelajaran terpisah untuk perbedaan antara kelas abstrak dan antarmuka, karena topik ini sangat penting. Anda akan ditanya tentang perbedaan antara konsep-konsep ini dalam 90% wawancara mendatang. Itu berarti Anda harus yakin untuk mencari tahu apa yang Anda baca. Dan jika Anda tidak sepenuhnya memahami sesuatu, bacalah sumber tambahan. Jadi, kita tahu apa itu kelas abstrak dan apa itu antarmuka. Sekarang kita akan membahas perbedaan mereka.
  1. Antarmuka hanya menjelaskan perilaku. Ia tidak memiliki keadaan. Tetapi kelas abstrak menyertakan status: ini menjelaskan keduanya.

    Misalnya, ambil Birdkelas abstrak dan CanFlyantarmuka:

    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 MockingJaykelas burung dan buat itu inherit Bird:

    public class MockingJay extends Bird {
    
       @Override
       public void fly() {
           System.out.println("Fly, bird!");
       }
    
       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 — speciesdan agevariabelnya.

    Tetapi jika kami mencoba melakukan hal yang sama dengan antarmuka, gambarnya berbeda. Kita dapat mencoba menambahkan variabel ke dalamnya:

    public interface CanFly {
    
       String species = new String();
       int age = 10;
    
       public void fly();
    }
    
    public interface CanFly {
    
       private String species = new String(); // Error
       private int age = 10; // Another error
    
       public void fly();
    }

    Kami bahkan tidak dapat mendeklarasikan variabel pribadi di dalam antarmuka. Mengapa? Karena pengubah pribadi dibuat untuk menyembunyikan implementasi dari pengguna. Dan sebuah antarmuka tidak memiliki implementasi di dalamnya: tidak ada yang disembunyikan.

    Antarmuka hanya menjelaskan perilaku. Karenanya, kami tidak dapat mengimplementasikan getter dan setter di dalam antarmuka. Ini adalah sifat antarmuka: mereka diperlukan untuk bekerja dengan perilaku, bukan keadaan.

    Java 8 memperkenalkan metode default untuk antarmuka yang memiliki implementasi. Anda sudah tahu tentang mereka, jadi kami tidak akan mengulanginya.

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

    Mari kembali ke contoh kita dengan burung.

    Kelas abstrak kita Birddiperlukan untuk membuat burung berdasarkan kelas tersebut. Hanya burung dan tidak ada yang lain! Tentu saja, akan ada berbagai jenis burung.

    Perbedaan antara kelas abstrak dan antarmuka - 2

    Dengan CanFlyantarmuka, setiap orang dapat melanjutkan dengan caranya sendiri. Itu hanya menggambarkan perilaku (terbang) yang terkait dengan namanya. Banyak hal yang tidak berhubungan 'bisa terbang'.

    Perbedaan antara kelas abstrak dan antarmuka - 3

    4 entitas ini tidak berhubungan satu sama lain. Mereka bahkan tidak semuanya hidup. Namun, mereka semua CanFly.

    Kami tidak dapat menggambarkannya menggunakan kelas abstrak. Mereka tidak berbagi negara bagian yang sama atau bidang yang identik. Untuk mendefinisikan sebuah pesawat, kita mungkin membutuhkan kolom untuk model, tahun produksi, dan jumlah maksimum penumpang. Untuk Carlson, kami membutuhkan ladang untuk semua permen yang dia makan hari ini, dan daftar permainan yang akan dia mainkan dengan adik laki-lakinya. Untuk seekor nyamuk, ...uh... Aku bahkan tidak tahu... Mungkin, 'tingkat gangguan'? :)

    Intinya adalah kita tidak bisa menggunakan kelas abstrak untuk mendeskripsikannya. Mereka terlalu berbeda. Tapi mereka memiliki perilaku yang sama: mereka bisa terbang. Antarmuka sangat cocok untuk menggambarkan segala sesuatu di dunia yang dapat terbang, berenang, melompat, atau menunjukkan perilaku lainnya.

  3. Kelas dapat mengimplementasikan antarmuka sebanyak yang Anda inginkan, tetapi mereka hanya dapat mewarisi satu kelas.

    Kami telah menyebutkan ini lebih dari sekali. Java tidak memiliki banyak pewarisan kelas, tetapi Java mendukung banyak pewarisan antarmuka. Poin ini sebagian mengikuti dari yang sebelumnya: sebuah antarmuka menghubungkan banyak kelas berbeda yang seringkali tidak memiliki kesamaan, sementara kelas abstrak dibuat untuk sekelompok kelas yang sangat dekat hubungannya. Oleh karena itu, masuk akal jika Anda hanya dapat mewarisi satu kelas tersebut. Kelas abstrak menggambarkan hubungan 'is-a'.

Antarmuka standar: InputStream dan OutputStream

Kami telah membahas berbagai kelas yang bertanggung jawab atas input dan output stream. Mari kita pertimbangkan InputStreamdan OutputStream. Secara umum, ini sama sekali bukan antarmuka, melainkan kelas abstrak yang sepenuhnya asli. Sekarang Anda tahu artinya, jadi akan lebih mudah untuk bekerja dengan mereka :) InputStreamadalah kelas abstrak yang bertanggung jawab atas input byte. Java memiliki beberapa kelas yang mewarisi InputStream. Masing-masing dirancang untuk menerima data dari sumber yang berbeda. Karena InputStreaminduknya, ia menyediakan beberapa metode yang memudahkan bekerja dengan aliran data. Setiap keturunan InputStreammemiliki metode ini:
  • int available()mengembalikan jumlah byte yang tersedia untuk dibaca;
  • close()menutup aliran input;
  • int read()mengembalikan representasi bilangan bulat dari byte berikutnya yang tersedia dalam aliran. Jika akhir aliran telah tercapai, -1 akan dikembalikan;
  • int read(byte[] buffer)mencoba membaca byte ke dalam buffer, dan mengembalikan jumlah byte yang dibaca. Saat mencapai akhir file, ia mengembalikan -1;
  • int read(byte[] buffer, int byteOffset, int byteCount)menulis bagian dari blok byte. Ini digunakan ketika array byte mungkin belum terisi seluruhnya. Saat mencapai akhir file, ia mengembalikan -1;
  • long skip(long byteCount)melompati byteCount byte dalam aliran input, dan mengembalikan jumlah byte yang diabaikan.
Saya sarankan Anda mempelajari daftar lengkap metode . Sebenarnya ada lebih dari sepuluh kelas anak. Sebagai contoh, berikut adalah beberapa:
  1. FileInputStream: jenis yang paling umum dari InputStream. Ini digunakan untuk membaca informasi dari file;
  2. StringBufferInputStream: Jenis InputStream. Itu mengubah string menjadi InputStream;
  3. BufferedInputStream: Aliran input yang di-buffer. Ini paling sering digunakan untuk meningkatkan kinerja.
Ingat ketika kami pergi BufferedReaderdan mengatakan bahwa Anda tidak harus menggunakannya? Ketika kita menulis:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
… Anda tidak harus menggunakan BufferedReader: An InputStreamReadercan do the job. Tetapi BufferedReadermeningkatkan kinerja dan juga dapat membaca seluruh baris data daripada karakter individual. Hal yang sama berlaku untuk BufferedInputStream! Kelas mengumpulkan data input dalam buffer khusus tanpa terus-menerus mengakses perangkat input. Mari kita pertimbangkan 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 read: " + c);
           }
       } catch(Exception e) {

           e.printStackTrace();

       } finally {

           inputStream.close();
           buffer.close();
       }
   }
}
Dalam contoh ini, kami membaca data dari file yang terletak di komputer di ' D:/Users/UserName/someFile.txt '. Kami membuat 2 objek — a FileInputStreamdan a BufferedInputStreamyang 'membungkusnya'. Kemudian kami membaca byte dari file dan mengubahnya menjadi karakter. Dan kami melakukan itu sampai file berakhir. Seperti yang Anda lihat, tidak ada yang rumit di sini. Anda dapat menyalin kode ini dan menjalankannya pada file asli di komputer Anda :) Kelas OutputStreamadalah kelas abstrak yang mewakili aliran keluaran byte. Seperti yang sudah Anda ketahui, ini adalah kebalikan dari file InputStream. Itu tidak bertanggung jawab untuk membaca data dari suatu tempat, melainkan untuk mengirim data ke suatu tempat . Seperti InputStream, kelas abstrak ini memberikan semua keturunannya satu set metode mudah:
  • void close()menutup aliran keluaran;
  • void flush()membersihkan 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, mulai dari posisi offset.
Berikut adalah beberapa keturunan kelas OutputStream:
  1. DataOutputStream. Aliran output yang menyertakan metode untuk menulis tipe data Java standar.

    Kelas yang sangat sederhana untuk menulis tipe dan string data Java primitif. Anda mungkin akan memahami kode berikut bahkan 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. FileOutputStream. Kelas ini menerapkan mekanisme pengiriman data ke file di disk. Omong-omong, kami sudah menggunakannya di contoh terakhir. Apakah kamu menyadari? Kami meneruskannya ke DataOutputStream, yang bertindak sebagai 'pembungkus'.

  3. BufferedOutputStream. Aliran keluaran yang di-buffer. Juga tidak ada yang rumit di sini. Tujuannya analog dengan BufferedInputStream(atau BufferedReader). Alih-alih membaca data berurutan seperti biasa, ia menulis data menggunakan buffer 'kumulatif' khusus. Buffer memungkinkan untuk mengurangi berapa kali data sink diakses, sehingga meningkatkan kinerja.

    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'll convert this string to a byte array and write it to a file
    
               byte[] buffer = text.getBytes();
    
               bufferedStream.write(buffer, 0, buffer.length);
         }
    }

    Sekali lagi, Anda dapat bermain-main dengan kode ini sendiri dan memverifikasi bahwa itu akan berfungsi pada file asli di komputer Anda.

Kami akan memiliki pelajaran terpisah tentang FileInputStream, FileOutputStreamdan BuffreredInputStream, jadi ini adalah informasi yang cukup untuk kenalan pertama. Itu dia! Kami harap Anda memahami perbedaan antara antarmuka dan kelas abstrak dan siap menjawab pertanyaan apa pun, bahkan pertanyaan jebakan :)
Komentar
  • Populer
  • Baru
  • Lama
Anda harus login untuk memberikan komentar
Halaman ini belum memiliki komentar