JavaRush /Java blogi /Random-UZ /Abstrakt sinflar va interfeyslar o'rtasidagi farq

Abstrakt sinflar va interfeyslar o'rtasidagi farq

Guruhda nashr etilgan
Salom! Ushbu ma'ruzada biz mavhum sinflarning interfeyslardan qanday farq qilishlari haqida gapiramiz va umumiy abstrakt sinflarga ega misollarni ko'rib chiqamiz. Mavhum sinflar va interfeyslar o'rtasidagi farq - 1Biz alohida ma'ruzani mavhum sinf va interfeys o'rtasidagi farqlarga bag'ishladik, chunki mavzu juda muhim. Kelgusi intervyularning 90 foizida sizdan ushbu tushunchalar orasidagi farq haqida so'raladi. Shuning uchun, o'qiganingizni tushunib oling, agar biror narsani to'liq tushunmasangiz, qo'shimcha manbalarni o'qing. Shunday qilib, biz mavhum sinf nima ekanligini va interfeys nima ekanligini bilamiz. Endi ularning farqlarini ko'rib chiqaylik.
  1. Interfeys faqat xatti-harakatni tavsiflaydi. Uning boyligi yo'q. Ammo mavhum sinfning holati bor: u ikkalasini ham tasvirlaydi.

    BirdMisol sifatida mavhum sinf va interfeysni olaylik 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;
       }
    }

    MockingjayKeling, qushlar sinfini (mockingjay) yaratamiz va dan meros olamiz 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());
       }
    }

    Ko'rib turganingizdek, biz mavhum sinfning holatiga - uning o'zgaruvchilari species(turi) va age(yoshi) bilan osongina kirishimiz mumkin.

    Ammo interfeys bilan xuddi shunday qilishga harakat qilsak, rasm boshqacha bo'ladi. Biz unga o'zgaruvchilarni qo'shishga harakat qilishimiz mumkin:

    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 hatto interfeys ichida shaxsiy o'zgaruvchilarni yarata olmaymiz . Nega? Chunki xususiy modifikator dasturni foydalanuvchidan yashirish uchun yaratilgan. Ammo interfeys ichida hech qanday dastur mavjud emas: u erda yashiradigan hech narsa yo'q.

    Interfeys faqat xatti-harakatni tasvirlaydi. Shunga ko'ra, biz interfeys ichida oluvchilar va sozlashlarni amalga oshira olmaymiz. Bu interfeysning tabiati: u holat emas, balki xatti-harakatlar bilan shug'ullanish uchun mo'ljallangan.

    Java8 ilovaga ega standart interfeys usullarini taqdim etdi. Siz ular haqida allaqachon bilasiz, shuning uchun biz ularni takrorlamaymiz.

  2. Mavhum sinf juda yaqin munosabatga ega bo'lgan sinflarni bog'laydi va birlashtiradi. Shu bilan birga, bir xil interfeys umuman umumiyligi bo'lmagan sinflar tomonidan amalga oshirilishi mumkin.

    Keling, qushlar misolimizga qaytaylik.

    Bizning abstrakt sinfimiz Birduning asosida qushlarni yaratish uchun kerak. Faqat qushlar va boshqa hech kim! Albatta, ular boshqacha bo'ladi.

    Abstrakt sinflar va interfeyslar o'rtasidagi farq - 2

    Interfeys bilan Flyablehamma narsa boshqacha. U faqat o'z nomiga mos keladigan xatti-harakatni tasvirlaydi - "uchish". "Uchish", "uchishga qodir" ta'rifi bir-biriga bog'liq bo'lmagan ko'plab narsalarni o'z ichiga oladi.

    Abstrakt sinflar va interfeyslar orasidagi farq - 3

    Bu 4 ta sub'ekt bir-biriga hech qanday aloqador emas. Nima deyishim mumkin, ularning hammasi ham jonli emas. Biroq, ularning barchasi Flyableparvozga qodir.

    Biz ularni mavhum sinf yordamida tasvirlay olmaymiz. Ularda umumiy holat yoki bir xil maydonlar mavjud emas. Samolyotni tavsiflash uchun bizga "model", "ishlab chiqarilgan yili" va "maksimal yo'lovchilar soni" maydonlari kerak bo'ladi. Karlson uchun bugun u yegan barcha shirinliklar uchun maydonlar va u Kid bilan o'ynaydigan o'yinlar ro'yxati mavjud. Chivin uchun ... uh-uh ... biz hatto bilmaymiz ... Balki "bezovtalik darajasi"? :)

    Asosiysi, biz ularni mavhum sinf yordamida tasvirlay olmaymiz. Ular juda boshqacha. Ammo umumiy xatti-harakatlar mavjud: ular ucha oladi. Interfeys dunyoda ucha oladigan, suzishi, sakrashi yoki boshqa xatti-harakatlarini tasvirlash uchun ideal.

  3. Sinflar xohlagancha ko'p interfeyslarni amalga oshirishi mumkin, lekin ular faqat bitta sinfdan meros bo'lishi mumkin.

    Biz bu haqda bir necha bor gapirganmiz. Java-da bir nechta meros yo'q, lekin bir nechta dastur mavjud. Bu nuqta qisman avvalgisidan kelib chiqadi: interfeys ko'pincha umumiy hech narsaga ega bo'lmagan ko'plab turli sinflarni bog'laydi va bir-biriga juda yaqin bo'lgan sinflar guruhi uchun mavhum sinf yaratiladi. Shuning uchun, siz faqat bitta sinfdan meros bo'lishingiz mantiqan to'g'ri. Mavhum sinf "a" munosabatini tavsiflaydi.

Standart InputStream va OutputStream interfeyslari

Biz allaqachon kirish va chiqish oqimi uchun mas'ul bo'lgan turli sinflardan o'tdik. InputStreamKeling, va ni ko'rib chiqaylik OutputStream. Umuman olganda, bu interfeyslar emas, balki haqiqiy mavhum sinflardir. Endi siz ular nima ekanligini bilasiz, shuning uchun ular bilan ishlash ancha oson bo'ladi :) InputStream- bu bayt kiritish uchun mas'ul bo'lgan mavhum sinf. Java dan meros bo'lgan bir qator sinflarga ega InputStream. Ularning har biri turli manbalardan ma'lumotlarni qabul qilish uchun tuzilgan. U ota-ona bo'lganligi sababli InputStream, u ma'lumotlar oqimlari bilan qulay ishlashning bir necha usullarini taqdim etadi. Har bir bolada quyidagi usullar mavjud InputStream:
  • int available()o'qish uchun mavjud baytlar sonini qaytaradi;
  • close()kirish manbasini yopadi;
  • int read()oqimdagi keyingi mavjud baytning butun sonli tasvirini qaytaradi. Agar oqim oxiriga yetsa, -1 raqami qaytariladi;
  • int read(byte[] buffer)baytlarni buferga o'qishga harakat qiladi, o'qilgan baytlar sonini qaytaradi. Fayl oxiriga yetganda -1 ni qaytaradi;
  • int read(byte[] buffer, int byteOffset, int byteCount)bayt blokining bir qismini o'qiydi. Ma'lumotlar bloki to'liq to'ldirilmaganligi ehtimoli mavjud bo'lganda foydalaniladi. Fayl oxiriga yetganda -1 ni qaytaradi;
  • long skip(long byteCount)skips byteCount, kirish bayti, e'tibor berilmagan baytlar sonini qaytaradi.
Men sizga usullarning to'liq ro'yxatini o'rganishni maslahat beraman . Haqiqatan ham o'ndan ortiq davomiy sinflar mavjud. Mana bir nechta misollar:
  1. FileInputStream: eng keng tarqalgan turi InputStream. Fayldan ma'lumotlarni o'qish uchun ishlatiladi;
  2. StringBufferInputStream: boshqa foydali tur InputStream. U satrni kirish ma'lumotlar oqimiga aylantiradi InputStream;
  3. BufferedInputStream: buferlangan kirish oqimi. Ko'pincha samaradorlikni oshirish uchun ishlatiladi.
BufferedReaderBiz o'tib ketib , undan foydalanishimiz shart emasligini aytganimizni eslaysizmi ? Biz yozganimizda:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))
... BufferedReaderuni ishlatishning hojati yo'q: InputStreamReaderu ishni bajaradi. Ammo BufferedReaderu buni samaraliroq qiladi va bundan tashqari, ma'lumotlarni alohida belgilar emas, balki butun satrlarda o'qiy oladi. Hammasi BufferedInputStreambir xil! Sinf kirish ma'lumotlarini doimiy ravishda kiritish qurilmasiga kirmasdan maxsus buferda to'playdi. Keling, bir misolni ko'rib chiqaylik:
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();
       }
   }
}
Ushbu misolda biz "D:/Users/UserName/someFile.txt" manzilida kompyuterda joylashgan fayldan ma'lumotlarni o'qiymiz . Biz ikkita ob'ektni yaratamiz - FileInputStreamva BufferedInputStreamuning "o'rashi" sifatida. Shundan so'ng biz fayldan baytlarni o'qiymiz va ularni belgilarga aylantiramiz. Va shunga o'xshash fayl tugaguncha. Ko'rib turganingizdek, bu erda murakkab narsa yo'q. Siz ushbu kodni nusxalashingiz va uni kompyuteringizda saqlanadigan ba'zi bir haqiqiy faylda ishga tushirishingiz mumkin :) Sinf OutputStreambayt oqimi chiqishini belgilaydigan mavhum sinfdir. Siz allaqachon tushunganingizdek, bu "a" ning antipodi InputStream. U ma'lumotlarni qayerdan o'qish uchun emas, balki uni qayerga yuborish uchun javobgardir . Shunga o'xshab InputStream, ushbu mavhum sinf barcha avlodlarga qulay ishlash uchun bir qator usullarni taqdim etadi:
  • int close()chiqish oqimini yopadi;
  • void flush()barcha chiqish buferlarini tozalaydi;
  • abstract void write (int oneByte)chiqish oqimiga 1 bayt yozadi;
  • void write (byte[] buffer)chiqish oqimiga baytlar massivini yozadi;
  • void write (byte[] buffer, int offset, int count)pozitsiya ofsetidan boshlab massivdan bir qator baytlarni yozadi.
Mana, sinfning ba'zi avlodlari OutputStream:
  1. DataOutputStream. Standart Java ma'lumotlar turlarini yozish usullarini o'z ichiga olgan chiqish oqimi.

    Ibtidoiy Java turlari va satrlarini yozish uchun juda oddiy sinf. Albatta, siz yozma kodni tushuntirishsiz ham tushunasiz:

    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);
    
       }
    }

    Unda har bir tur uchun alohida usullar mavjud - writeDouble(), writeLong(), writeShort()va hokazo.

  2. Sinf FileOutputStream . Diskdagi faylga ma'lumotlarni jo'natish mexanizmini amalga oshiradi. Aytgancha, biz buni oldingi misolda ishlatganmiz, sezdingizmi? Biz uni "o'rash" vazifasini bajaruvchi DataOutputStream ichiga o'tkazdik.

  3. BufferedOutputStream. Buferlangan chiqish oqimi. BufferedInputStreamHech qanday murakkab narsa yo'q, mohiyat (yoki 'a) bilan bir xil BufferedReader. Odatiy ketma-ket ma'lumotlarni yozib olish o'rniga maxsus "saqlash" buferi orqali yozib olish qo'llaniladi. Buferdan foydalanib, siz ma'lumot olish joyiga aylanma sayohatlar sonini kamaytirishingiz va shu bilan samaradorlikni oshirishingiz mumkin.

    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();
       }
    }

    Shunga qaramay, siz ushbu kod bilan o'zingiz "o'ynashingiz" va kompyuteringizdagi haqiqiy fayllarda qanday ishlashini tekshirishingiz mumkin.

Shuningdek, merosxo'rlar haqida " InputStreamKirish / chiqish tizimiOutputStream " materialida o'qishingiz mumkin . Oh , va bizda alohida ma'ruza ham bo'ladi, shuning uchun ular haqida birinchi tanishish uchun etarli ma'lumotlar mavjud. Ana xolos! Umid qilamizki, siz interfeyslar va mavhum sinflar o'rtasidagi farqlarni yaxshi tushunasiz va har qanday savolga, hatto qiyin bo'lsa ham javob berishga tayyormiz :) FileInputStreamFileOutputStreamBufferedInputStream
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION