-
İnterfeys yalnız davranışı təsvir edir. Onun taleyi yoxdur. Lakin mücərrəd sinfin bir vəziyyəti var: o, hər ikisini təsvir edir.
Bird
Nümunə olaraq abstrakt sinif və interfeysi götürəkFlyable
: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; } }
Gəlin bir quş sinfi
Mockingjay
(mockingjay) yaradaq və ondan miras alaqBird
: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()); } }
Gördüyünüz kimi, biz mücərrəd sinfin vəziyyətinə - onun dəyişənlərinə
species
(növ) vəage
(yaş) asanlıqla daxil ola bilərik.Ancaq interfeyslə eyni şeyi etməyə çalışsaq, şəkil fərqli olacaq. Biz ona dəyişənlər əlavə etməyə cəhd edə bilərik:
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(); }
Biz hətta interfeys daxilində şəxsi dəyişənlər yarada bilməyəcəyik . Niyə? Çünki özəl modifikator tətbiqi istifadəçidən gizlətmək üçün yaradılmışdır. Ancaq interfeys daxilində heç bir tətbiq yoxdur: orada gizlənə biləcək heç bir şey yoxdur.
İnterfeys yalnız davranışı təsvir edir. Müvafiq olaraq, biz interfeys daxilində alıcıları və tənzimləyiciləri həyata keçirə bilməyəcəyik. Bu, interfeysin xarakteridir: o, vəziyyətlə deyil, davranışla məşğul olmaq üçün nəzərdə tutulub.
Java8 tətbiqi olan standart interfeys üsullarını təqdim etdi. Siz artıq onlar haqqında bilirsiniz, ona görə də onları təkrar etməyəcəyik.
-
Mücərrəd sinif çox sıx əlaqədə olan sinifləri əlaqələndirir və birləşdirir. Eyni zamanda, eyni interfeys ümumiyyətlə heç bir ortaqlığı olmayan siniflər tərəfindən həyata keçirilə bilər.
Quşlarla bağlı nümunəmizə qayıdaq.
Bird
Onun əsasında quşlar yaratmaq üçün abstrakt sinifimiz lazımdır. Yalnız quşlar və başqa heç kim! Təbii ki, fərqli olacaqlar.İnterfeys ilə
Flyable
hər şey fərqlidir. O, yalnız adına uyğun davranışı təsvir edir - "uçmaq". “Uçan”, “uça bilən” anlayışına bir-biri ilə əlaqəsi olmayan çoxlu obyektlər daxildir.Bu 4 varlıq heç bir şəkildə bir-biri ilə əlaqəli deyil. Nə deyim, heç də hamısı canlı deyil. Bununla belə, onların hamısı
Flyable
uçuş qabiliyyətinə malikdir.Mücərrəd sinifdən istifadə edərək onları təsvir edə bilməyəcəyik. Onların ümumi dövləti və ya eyni sahələri yoxdur. Təyyarəni xarakterizə etmək üçün yəqin ki, “model”, “istehsal ili” və “maksimum sərnişin sayı” sahələrinə ehtiyacımız olacaq. Carlson üçün bu gün yediyi bütün şirniyyatlar üçün sahələr və Uşaqla oynayacağı oyunların siyahısı var. Bir ağcaqanad üçün ... uh-uh ... biz hətta bilmirik ... Bəlkə "qıcıqlanma səviyyəsi"? :)
Əsas odur ki, biz onları abstrakt sinifdən istifadə edərək təsvir edə bilmərik. Onlar çox fərqlidirlər. Ancaq ümumi bir davranış var: uça bilərlər. İnterfeys dünyada uça, üzə, tullanmaya və ya başqa davranışlara malik olan hər şeyi təsvir etmək üçün idealdır.
-
Siniflər istədikləri qədər interfeys həyata keçirə bilər, lakin onlar yalnız bir sinifdən miras ala bilərlər.
Bu barədə artıq bir dəfədən çox danışmışıq. Java-da çoxsaylı miras yoxdur, lakin çoxlu tətbiqetmə var. Bu məqam qismən əvvəlkindən irəli gəlir: interfeys çox vaxt ortaq heç nəyi olmayan çoxlu müxtəlif sinifləri birləşdirir və bir-birinə çox yaxın olan siniflər qrupu üçün mücərrəd sinif yaradılır. Buna görə də, yalnız bir belə sinifdən miras ala biləcəyiniz məntiqlidir. Mücərrəd sinif "bir" əlaqəsini təsvir edir.
Standart InputStream & OutputStream İnterfeysləri
Biz artıq axın girişi və çıxışı üçün məsul olan müxtəlif siniflərdən keçmişik. Gəlin baxaqInputStream
və OutputStream
. Ümumiyyətlə, bunlar interfeys deyil, real abstrakt siniflərdir. İndi onların nə olduğunu bilirsiniz, ona görə də onlarla işləmək çox asan olacaq :) InputStream
- bu bayt daxilinə cavabdeh olan mücərrəd sinifdir. Java-dan miras qalan bir sıra siniflərə malikdir InputStream
. Onların hər biri müxtəlif mənbələrdən məlumat almaq üçün konfiqurasiya edilmişdir. InputStream
O, valideyn olduğu üçün məlumat axınları ilə rahat işləmək üçün bir neçə üsul təqdim edir. Hər bir uşağın bu üsulları var InputStream
:
int available()
oxumaq üçün mövcud baytların sayını qaytarır;close()
giriş mənbəyini bağlayır;int read()
axındakı növbəti mövcud baytın tam təsvirini qaytarır. Əgər axın sonuna çatarsa, -1 rəqəmi qaytarılacaq;int read(byte[] buffer)
baytları buferə oxumağa çalışır, oxunan baytların sayını qaytarır. Faylın sonuna çatdıqda -1 qaytarır;int read(byte[] buffer, int byteOffset, int byteCount)
bayt blokunun bir hissəsini oxuyur. Məlumat blokunun tam doldurulmaması ehtimalı olduqda istifadə olunur. Faylın sonuna çatdıqda -1 qaytarır;long skip(long byteCount)
skipsbyteCount
, bir bayt giriş, nəzərə alınmayan baytların sayını qaytarır.
FileInputStream
: ən ümumi növüInputStream
. Fayldan məlumatı oxumaq üçün istifadə olunur;StringBufferInputStream
: başqa faydalı növInputStream
. O, sətri giriş məlumat axınına çevirirInputStream
;BufferedInputStream
: buferli giriş axını. Ən çox səmərəliliyi artırmaq üçün istifadə olunur.
BufferedReader
Yanımızdan keçib istifadə etməli olduğumuzu dediyimizi xatırlayırsınızmı ? Yazdığımız zaman:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReader
istifadə etməyə ehtiyac yoxdur: InputStreamReader
işi görəcək. Lakin BufferedReader
o, bunu daha səmərəli edir və üstəlik, məlumatları ayrı-ayrı simvollarla deyil, bütün sətirlərdə oxuya bilir. Hər şey BufferedInputStream
eynidir! Sinif giriş məlumatlarını daim daxiletmə qurğusuna daxil olmadan xüsusi buferdə toplayır. Bir misala baxaq:
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();
}
}
}
Bu nümunədə biz kompüterdə "D:/Users/UserName/someFile.txt" ünvanında yerləşən fayldan məlumatları oxuyuruq . Biz 2 obyekt yaradırıq - FileInputStream
və BufferedInputStream
onun "sarğı" kimi. Bundan sonra fayldan baytları oxuyuruq və onları simvollara çeviririk. Və fayl bitənə qədər. Gördüyünüz kimi, burada mürəkkəb bir şey yoxdur. Siz bu kodu kopyalayıb kompüterinizdə saxlanılan bəzi real faylda işlədə bilərsiniz :) OutputStream
Sinif bayt axını çıxışını təyin edən mücərrəd sinifdir. Artıq başa düşdüyünüz kimi, bu, 'a'nın antipodudur InputStream
. O, məlumatların haradan oxunacağına deyil, hara göndəriləcəyinə görə məsuliyyət daşıyır . Məsələn InputStream
, bu mücərrəd sinif bütün nəsillərə rahat iş üçün bir qrup üsul təqdim edir:
int close()
çıxış axını bağlayır;void flush()
bütün çıxış tamponlarını təmizləyir;abstract void write (int oneByte)
çıxış axınına 1 bayt yazır;void write (byte[] buffer)
çıxış axınına bayt massivi yazır;void write (byte[] buffer, int offset, int count)
mövqe ofsetindən başlayaraq massivdən bir sıra bayt sayı yazır.
OutputStream
:
-
DataOutputStream
. Standart Java məlumat növlərinin yazılması üsullarını ehtiva edən çıxış axını.Primitiv Java növləri və sətirlərinin yazılması üçün çox sadə sinif. Şübhəsiz ki, yazılı kodu izah etmədən də başa düşəcəksiniz:
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); } }
Onun hər bir növ üçün ayrıca üsulları var -
writeDouble()
,writeLong()
,writeShort()
və s. -
Sinif
FileOutputStream
. Diskdəki fayla verilənlərin göndərilməsi mexanizmini həyata keçirir. Yeri gəlmişkən, biz bundan əvvəlki nümunədə artıq istifadə etmişik, fikir vermisiniz? Biz onu “sarğı” kimi çıxış edən DataOutputStream-in içərisinə keçirdik. -
BufferedOutputStream
. Buferli çıxış axını.BufferedInputStream
Mürəkkəb bir şey də yoxdur, mahiyyət (və ya 'a) ilə eynidirBufferedReader
. Adi ardıcıl məlumat qeydinin əvəzinə xüsusi "saxlama" buferi vasitəsilə qeyd istifadə olunur. Buferdən istifadə etməklə siz məlumat təyinatına gediş-gəlişlərin sayını azalda və bununla da səmərəliliyi artıra bilərsiniz.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(); } }
Yenə də bu kodla özünüz "oynaya" və onun kompüterinizdəki real fayllarda necə işləyəcəyini yoxlaya bilərsiniz.
InputStream
Giriş /Çıxış SistemiOutputStream
” materialında varislər haqqında oxuya bilərsiniz . Oh , bizim də ayrıca mühazirəmiz olacaq, ona görə də ilk tanışlıq üçün onlar haqqında kifayət qədər məlumat var. Hamısı budur! Ümid edirik ki, siz interfeyslər və abstrakt siniflər arasındakı fərqləri yaxşı başa düşürsünüz və istənilən suala, hətta çətin suala belə cavab verməyə hazırsınız :) FileInputStream
FileOutputStream
BufferedInputStream
GO TO FULL VERSION