-
Antarmuka hanya menjelaskan perilaku. Dia tidak punya kekayaan. Tapi kelas abstrak memiliki keadaan: ia menjelaskan keduanya.
Mari kita ambil kelas abstrak
Bird
dan antarmuka sebagai contohFlyable
: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 dariBird
: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) danage
(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.
-
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
Bird
diperlukan untuk membuat burung berdasarkan itu. Hanya burung dan tidak ada orang lain! Tentu saja keduanya akan berbeda.Dengan antarmuka
Flyable
semuanya 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.Keempat entitas ini tidak terkait satu sama lain dengan cara apa pun. Apa yang bisa saya katakan, tidak semuanya bernyawa. Namun, mereka semua
Flyable
mampu 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.
-
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 lihatInputStream
dan 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 InputStream
merupakan 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)
skipsbyteCount
, satu byte masukan, mengembalikan jumlah byte yang diabaikan.
FileInputStream
: tipe yang paling umumInputStream
. Digunakan untuk membaca informasi dari suatu file;StringBufferInputStream
: tipe lain yang bergunaInputStream
. Ini mengubah string menjadi aliran data masukanInputStream
;BufferedInputStream
: aliran input yang di-buffer. Ini paling sering digunakan untuk meningkatkan efisiensi.
BufferedReader
dan berkata bahwa kami tidak perlu menggunakannya? Saat kita menulis:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReader
tidak perlu menggunakannya: InputStreamReader
itu akan berhasil. Namun BufferedReader
ia melakukannya dengan lebih efisien dan, terlebih lagi, dapat membaca data di seluruh baris, daripada karakter individual. Semua BufferedInputStream
sama! 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 - FileInputStream
dan BufferedInputStream
sebagai "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 OutputStream
adalah 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.
OutputStream
:
-
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. -
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". -
BufferedOutputStream
. Aliran keluaran yang disangga. Tidak ada yang ribet juga, intinya sama seperti diBufferedInputStream
(atauBufferedReader
'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.
InputStream
Input /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 :) OutputStream
FileInputStream
FileOutputStream
BufferedInputStream
GO TO FULL VERSION