-
Antara muka hanya menerangkan tingkah laku. Dia tiada rezeki. Tetapi kelas abstrak mempunyai keadaan: ia menerangkan kedua-duanya.
Mari kita ambil kelas abstrak
Bird
dan antara muka 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 buat kelas burung
Mockingjay
(mockingjay) dan warisi daripadaBird
: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) danage
(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.
-
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
Bird
diperlukan untuk mencipta burung berdasarkannya. Hanya burung dan tidak ada orang lain! Sudah tentu mereka akan berbeza.Dengan antara muka
Flyable
semuanya 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.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
Flyable
mampu 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.
-
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 tengokInputStream
dan 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 InputStream
ia 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)
langkaubyteCount
, bait input, mengembalikan bilangan bait diabaikan.
FileInputStream
: jenis yang paling biasaInputStream
. Digunakan untuk membaca maklumat daripada fail;StringBufferInputStream
: jenis lain yang bergunaInputStream
. Ia menukar rentetan menjadi aliran data inputInputStream
;BufferedInputStream
: aliran input buffer. Ia paling kerap digunakan untuk meningkatkan kecekapan.
BufferedReader
dan berkata bahawa kami tidak perlu menggunakannya? Apabila kita menulis:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReader
tidak perlu menggunakannya: InputStreamReader
ia akan melakukan kerja. Tetapi BufferedReader
ia melakukannya dengan lebih cekap dan, lebih-lebih lagi, boleh membaca data dalam keseluruhan baris, bukannya aksara individu. Semuanya BufferedInputStream
sama! 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 - FileInputStream
dan BufferedInputStream
sebagai "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 OutputStream
ialah 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.
OutputStream
:
-
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. -
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". -
BufferedOutputStream
. Aliran keluaran penimbal. Tiada yang rumit sama ada, intipatinya sama seperti dalamBufferedInputStream
(atauBufferedReader
'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.
InputStream
Input / 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 :) OutputStream
FileInputStream
FileOutputStream
BufferedInputStream
GO TO FULL VERSION