JavaRush /Java blogi /Random-UZ /Java tilidagi interfeyslar

Java tilidagi interfeyslar

Guruhda nashr etilgan
Salom! Bugun biz Java-da muhim tushuncha - interfeyslar haqida gaplashamiz. Bu so'z sizga tanish bo'lsa kerak. Masalan, ko'pgina kompyuter dasturlari va o'yinlari interfeyslarga ega. Keng ma'noda interfeys - bu bir-biri bilan o'zaro aloqada bo'lgan ikki tomonni bog'laydigan "masofadan boshqarish" turi. Kundalik hayotdagi interfeysning oddiy misoli televizorning masofadan boshqarish pultidir. U ikkita ob'ektni, odamni va televizorni bog'laydi va turli vazifalarni bajaradi: ovoz balandligini oshirish yoki kamaytirish, kanallarni o'zgartirish, televizorni yoqish yoki o'chirish. Harakatni amalga oshirish uchun bir tomon (odam) interfeysga kirishi kerak (masofadan boshqarish tugmachasini bosing). Masalan, televizor uchun kanalni keyingisiga o'tkazish. Bunday holda, foydalanuvchi televizorning qurilmasini va uning ichida kanalni o'zgartirish jarayoni qanday amalga oshirilishini bilishi shart emas. Java-da interfeyslar nima uchun kerak - 1Foydalanuvchining kirish huquqiga ega bo'lgan barcha narsa interfeysdir . Asosiy vazifa - kerakli natijaga erishish. Buning dasturlash va Java bilan qanday aloqasi bor? To'g'ridan-to'g'ri :) Interfeys yaratish oddiy sinf yaratishga juda o'xshaydi, lekin so'z o'rniga classbiz so'zni belgilaymiz interface. Keling, eng oddiy Java interfeysini ko'rib chiqamiz va uning qanday ishlashini va nima uchun kerakligini aniqlaymiz:
public interface Swimmable  {

     public void swim();
}
Biz suzishga qodirSwimmable interfeys yaratdik . Bu bizning masofadan boshqarish pultimizga o'xshaydi, unda bitta "tugma" mavjud: usul "suzish". Ushbu “ masofadan boshqarish pultidan ” qanday foydalanishimiz mumkin ? Shu maqsadda usul, ya'ni. masofadan boshqarish pultidagi tugmani amalga oshirish kerak. Interfeysdan foydalanish uchun uning usullari dasturimizning ayrim sinflari tomonidan amalga oshirilishi kerak. Keling, ob'ektlari "suzishi mumkin" tavsifiga mos keladigan sinfni yarataylik. Masalan, o'rdak sinfi mos keladi : swim()Duck
public class Duck implements Swimmable {

    public void swim() {
        System.out.println("Duck, swim!");
    }

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
Bu erda nimani ko'ramiz? Sinf kalit so'z yordamida Duckinterfeys bilan bog'lanadi . Esingizda bo'lsa, biz merosda ikkita sinfni ulash uchun shunga o'xshash mexanizmdan foydalanganmiz, faqat " kengaytiradi " so'zi bor edi. Aniqlik uchun “ ” so‘zini so‘zma-so‘z tarjima qilish mumkin: “ommaviy sinf interfeysni amalga oshiradi .” Bu interfeys bilan bog'langan sinf uning barcha usullarini amalga oshirishi kerakligini anglatadi. Iltimos, diqqat qiling: bizning sinfimizda, xuddi interfeysdagi kabi , usul mavjud va uning ichida qandaydir mantiq bor. Bu majburiy talabdir. Agar biz shunchaki “ ” deb yozgan bo'lsak va sinfda metod yaratmagan bo'lsak , kompilyator bizga xato qiladi: Duck mavhum emas va Swimmable-da swim() mavhum usulini bekor qilmaydi Nima uchun bu sodir bo'ladi? Agar biz xatoni televizor misolida tushuntirsak, biz odamga kanallarni qanday o'zgartirishni bilmagan televizordan "kanalni o'zgartirish" tugmasi bilan masofadan boshqarish pultini berayotganimiz ma'lum bo'ladi. Bu vaqtda tugmani xohlagancha bosing, hech narsa ishlamaydi. Masofadan boshqarish pultining o'zi kanallarni o'zgartirmaydi: u faqat televizorga signal beradi, uning ichida kanalni o'zgartirishning murakkab jarayoni amalga oshiriladi. Bizning o'rdakimiz ham shunday: u suzish qobiliyatiga ega bo'lishi kerak, shunda unga interfeys yordamida kirish mumkin bo'ladi . Agar u buni qanday qilishni bilmasa, interfeys ikki tomonni - odamni va dasturni bog'lamaydi. Biror kishi dastur ichidagi ob'ektni float qilish usulidan foydalana olmaydi . Endi siz interfeyslar nima uchun ekanligini aniqroq ko'rdingiz. Interfeys ushbu interfeysni amalga oshiradigan sinflar ega bo'lishi kerak bo'lgan xatti-harakatni tavsiflaydi. "Xulq-atvor" - bu usullar to'plami. Agar biz bir nechta messenjer yaratmoqchi bo'lsak, buni qilishning eng oson yo'li interfeys yaratishdir . Har qanday messenjer nima qila olishi kerak? Soddalashtirilgan shaklda xabarlarni qabul qiling va yuboring. Swimmableimplementspublic class Duck implements SwimmableDuckSwimmableDuckSwimmableswim()public class Duck implements Swimmableswim()DuckSwimmableSwimmableswim()DuckMessenger
public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
Va endi biz ushbu interfeysni amalga oshirish orqali oddiygina messenjer sinflarimizni yaratishimiz mumkin. Kompilyatorning o'zi bizni ularni sinflar ichida amalga oshirishga "majbur qiladi". Telegram:
public class Telegram implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a message to Telegram!");
    }

     public void getMessage() {
         System.out.println("Reading the message in Telegram!");
     }
}
WhatsApp:
public class WhatsApp implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a WhatsApp message!");
    }

     public void getMessage() {
         System.out.println("Reading a WhatsApp message!");
     }
}
Viber:
public class Viber implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a message to Viber!");
    }

     public void getMessage() {
         System.out.println("Reading a message in Viber!");
     }
}
Bu qanday imtiyozlar beradi? Ulardan eng muhimi bo'shashmasdan ulanishdir. Tasavvur qiling-a, biz mijozlar ma'lumotlarini to'playdigan dasturni ishlab chiqmoqdamiz. Sinfda Clientmijoz qaysi messenjerdan foydalanishini ko'rsatadigan maydon bo'lishi kerak. Interfeyslarsiz u g'alati ko'rinadi:
public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
Biz uchta maydon yaratdik, ammo mijoz osongina faqat bitta messenjerga ega bo'lishi mumkin. Biz faqat qaysi birini bilmaymiz. Va mijoz bilan aloqasiz qolmaslik uchun barcha mumkin bo'lgan variantlarni sinfga "itarish" kerak. Ma'lum bo'lishicha, ulardan bir yoki ikkitasi doimo u erda bo'ladi nullva dastur ishlashi uchun ular umuman kerak emas. Buning o'rniga bizning interfeysimizdan foydalanish yaxshidir:
public class Client {

    private Messenger messenger;
}
Bu "bo'shashmasdan ulanish" ning misolidir! Sinfda ma'lum bir messenjer sinfini ko'rsatish o'rniga Client, mijozda messenjer borligini eslatib o'tamiz. Qaysi biri dastur davomida aniqlanadi. Lekin nima uchun bizga interfeyslar kerak? Nima uchun ular umuman tilga qo'shilgan? Savol yaxshi va to'g'ri! Xuddi shu natijaga oddiy meros orqali erishish mumkin, shunday emasmi? Sinf Messengerota-ona sinfidir, va Viber, Telegramva WhatsAppmerosxo'rlardir. Darhaqiqat, buni qilish mumkin. Lekin bitta jihat bor. Siz allaqachon bilganingizdek, Java-da bir nechta meros yo'q. Ammo interfeyslarning bir nechta ilovalari mavjud. Sinf o'zi xohlagancha ko'p interfeyslarni amalga oshirishi mumkin. SmartphoneTasavvur qiling-a, bizda maydonga ega bo'lgan sinf bor Application- smartfonda o'rnatilgan dastur.
public class Smartphone {

    private Application application;
}
Ilova va messenjer, albatta, o'xshash, ammo baribir ular boshqa narsalar. Messenger ham mobil, ham ish stoli bo'lishi mumkin, ilova esa mobil ilovadir. TelegramShunday qilib, agar biz merosdan foydalansak, sinfga ob'ekt qo'sha olmaymiz Smartphone. Axir, sinf dan va undan Telegrammeros bo'lolmaydi ! Va biz allaqachon uni meros qilib olishga muvaffaq bo'ldik va uni ushbu shaklda sinfga qo'shdik . Ammo sinf ikkala interfeysni ham osongina amalga oshirishi mumkin! Shuning uchun sinfda ob'ektni sifatida , sinfda esa sifatida amalga oshirishimiz mumkin . Bu qanday amalga oshiriladi: ApplicationMessengerMessengerClientTelegramClientTelegramMessengerSmartphoneApplication
public class Telegram implements Application, Messenger {

    //...methods
}

public class Client {

    private Messenger messenger;

    public Client() {
        this.messenger = new Telegram();
    }
}


public class Smartphone {

    private Application application;

    public Smartphone() {
        this.application = new Telegram();
    }
}
Endi biz sinfdan Telegramxohlagancha foydalanishimiz mumkin. Qaerdadir rolida Application, qayerdadir rolida harakat qiladi Messenger. Ehtimol, interfeyslardagi usullar har doim "bo'sh", ya'ni ularda amalga oshirilmaganligini allaqachon payqagansiz. Buning sababi oddiy: interfeys xatti-harakatni tasvirlaydi, uni amalga oshiradi. "Interfeysni amalga oshiradigan sinflarning barcha ob'ektlari Swimmablesuzish qobiliyatiga ega bo'lishi kerak": interfeys bizga shuni aytadi. Qanday qilib baliq, o'rdak yoki ot suzadi, bu savol interfeys uchun emas, balki Fishsinflar uchun Duckva . HorseXuddi kanalni o'zgartirish televizorning vazifasi bo'lgani kabi. Masofadan boshqarish pulti sizga buni amalga oshirish uchun tugmani beradi. Biroq, Java8-da qiziqarli qo'shimcha mavjud - standart usullar. Masalan, sizning interfeysingizda 10 ta usul mavjud. Ulardan 9 tasi turli sinflarda turlicha amalga oshiriladi, lekin bittasi hammasida bir xil amalga oshiriladi. Ilgari, Java8 chiqarilishidan oldin, interfeys ichidagi usullar umuman amalga oshirilmagan: kompilyator darhol xatoga yo'l qo'ydi. Endi siz buni shunday qilishingiz mumkin:
public interface Swimmable {

   public default void swim() {
       System.out.println("Swim!");
   }

   public void eat();

   public void run();
}
Kalit so'zdan foydalanib default, biz standart dastur bilan interfeysda usul yaratdik. Biz qolgan ikkita usulni eat()va , run()amalga oshiradigan barcha sinflarda o'zimiz amalga oshirishimiz kerak bo'ladi Swimmable. Buni usul bilan qilishning hojati yo'q swim(): amalga oshirish barcha sinflarda bir xil bo'ladi. Aytgancha, siz o'tgan vazifalarda interfeyslarni bir necha marta uchratgansiz, garchi buni o'zingiz sezmagan bo'lsangiz ham :) Mana yaqqol misol: Nima uchun bizga Java-da interfeyslar kerak - 2Siz interfeyslar bilan ishlagansiz Listva Set! Aniqrog'i, ularning amalga oshirilishi bilan - ArrayList, LinkedList, HashSetva boshqalar. Xuddi shu diagrammada bitta sinf bir vaqtning o'zida bir nechta interfeyslarni amalga oshirish misoli ko'rsatilgan. Masalan, LinkedListu interfeyslarni Listva Deque(ikki tomonlama navbat) amalga oshiradi. Siz shuningdek interfeys bilan Map, aniqrog'i, uning amalga oshirilishi bilan tanishsiz - HashMap. Aytgancha, ushbu diagrammada siz bitta xususiyatni ko'rishingiz mumkin: interfeyslarni bir-biridan meros qilib olish mumkin. Interfeys SortedMapdan meros bo'lib Map, navbatdan Dequemeros bo'lib o'tadi Queue. Agar siz interfeyslar orasidagi aloqani ko'rsatmoqchi bo'lsangiz, bu zarur, lekin bitta interfeys boshqasining kengaytirilgan versiyasidir. Keling, interfeysli misolni ko'rib chiqaylik Queue- navbat. Biz hali to'plamlarni ko'rib chiqmadik Queue, lekin ular juda oddiy va do'kondagi oddiy chiziq kabi tartibga solingan. Siz elementlarni faqat navbatning oxiriga qo'shishingiz va ularni faqat boshidan olib tashlashingiz mumkin. Muayyan bosqichda ishlab chiquvchilar har ikki tomondan elementlarni qo'shish va qabul qilish uchun navbatning kengaytirilgan versiyasiga muhtoj edi. Shunday qilib interfeys yaratildi Deque- ikki tomonlama navbat. U oddiy navbatning barcha usullarini o'z ichiga oladi, chunki u ikki tomonlama navbatning "otasi" dir, ammo yangi usullar qo'shilgan.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION