JavaRush /Java блогу /Random-KY /Java тилиндеги интерфейстер

Java тилиндеги интерфейстер

Группада жарыяланган
Салам! Бүгүн биз Javaдагы маанилүү түшүнүк - интерфейстер жөнүндө сүйлөшөбүз. Бул сөз сизге тааныш болсо керек. Мисалы, көпчүлүк компьютердик программалар менен оюндардын интерфейстери бар. Кеңири мааниде интерфейс - бул бири-бири менен өз ара аракеттенген эки тарапты бириктирген "алыстан башкаруунун" бир түрү. Күнүмдүк жашоодогу интерфейстин жөнөкөй мисалы - телевизордун пульту. Ал эки an objectти, адамды жана телевизорду бириктирип, ар кандай тапшырмаларды аткарат: үнүн жогорулатуу же азайтуу, каналдарды өзгөртүү, сыналгы күйгүзүү же өчүрүү. Бир тарап (адам) аракетти аткаруу үчүн экинчи тарап үчүн интерфейске (алыстан башкаруу баскычын басыңыз) кирүү керек. Мисалы, сыналгы үчүн каналды кийинкиге которуу. Бул учурда колдонуучуга телевизордун түзүлүшүн жана анын ичинде каналды өзгөртүү процесси кантип ишке ашырылып жатканын билүүгө муктаж эмес. Эмне үчүн Java-да интерфейстер керек - 1Колдонуучунун бардык мүмкүнчүлүгү бар интерфейс . Негизги милдет - каалаган натыйжаны алуу. Мунун программалоо жана Java менен кандай байланышы бар? Түздөн-түз :) Интерфейс түзүү кадимки классты түзүүгө абдан окшош, бирок сөздүн ордуна classсөздү көрсөтөбүз interface. Келгиле, эң жөнөкөй Java интерфейсин карап көрөлү жана анын кантип иштээрин жана ал эмне үчүн керек экенин түшүнөлү:
public interface Swimmable  {

     public void swim();
}
Биз сүзө алганSwimmable интерфейсти түздүк . Бул биздин алыстан башкаруу сыяктуу бир нерсе, анын бир "баскычы" бар: ыкмасы "сүзүү". Бул " алыстан башкарууну " кантип колдонсок болот ? Бул үчүн ыкма, б.а. биздин пульттун кнопкасын ишке ашыруу керек. Интерфейсти колдонуу үчүн анын ыкмалары биздин программанын кээ бир класстары тарабынан ишке ашырылышы керек. Келгиле, an objectтери "сүзө алат" деген сыпаттамага туура келген классты ойлоп табалы. Мисалы, өрдөк классы ылайыктуу : 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();
    }
}
Бул жерде биз эмнени көрүп жатабыз? Класс ачкыч сөздү колдонуу менен Duckинтерфейс менен байланышкан . Эсиңизде болсо, биз мурастоодо эки классты туташтыруу үчүн ушундай механизмди колдонгонбуз, бир гана " узарат " деген сөз бар болчу. Түшүнүктүү болуу үчүн “ ” сөзмө-сөз которууга болот: “коомдук класс интерфейсти ишке ашырат .” Бул интерфейс менен байланышкан класс анын бардык ыкмаларын ишке ашырышы керек дегенди билдирет. Көңүл буруңуз: биздин класста интерфейстегидей эле метод бар жана анын ичинде кандайдыр бир логика бар. Бул милдеттүү талап болуп саналат. Эгерде биз жөн эле “ ” деп жазып , класста метод түзбөсөк , компилятор бизге ката берет: Duck абстракттуу эмес жана Swimmable ичиндеги swim() абстракттуу ыкмасын жокко чыгарbyte Эмне үчүн мындай болот? Эгер катаны телевизордун мисалы менен түшүндүрсөк, каналды кантип алмаштырууну билбеген телевизордун “каналды өзгөртүү” баскычы бар пультту адамга берип жатабыз. Бул учурда баскычты каалаганча басыңыз, эч нерсе иштебейт. Пульттун өзү каналдарды алмаштырbyte: ал сыналгыга гана сигнал берет, анын ичинде каналды алмаштыруунун татаал процесси ишке ашырылат. Биздин өрдөк да ушундай: ал сүзө алышы керек, ошондуктан ага интерфейс аркылуу кирүүгө болот . Эгер ал муну кантип кылууну билбесе, интерфейс эки тарапты - адам менен программаны байланыштырbyte. Адам программанын ичиндеги an objectти сүзүү ыкмасын колдоно алbyte . Эми сиз интерфейстер эмне үчүн экенин айкыныраак көрдүңүз. Интерфейс ошол интерфейсти ишке ашырган класстар ээ болушу керек болгон жүрүм-турумду сүрөттөйт. "Жүрүм-турум" - бул ыкмалардын жыйындысы. Эгерде биз бир нече мессенджерлерди түзгүбүз келсе, муну жасоонун эң оңой жолу - интерфейс түзүү . Ар бир мессенжер эмне кыла алышы керек? Жөнөкөйлөштүрүлгөн формада билдирүүлөрдү кабыл алуу жана жөнөтүү. Swimmableimplementspublic class Duck implements SwimmableDuckSwimmableDuckSwimmableswim()public class Duck implements Swimmableswim()DuckSwimmableSwimmableswim()DuckMessenger
public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
Эми бул интерфейсти ишке ашыруу менен биз жөн гана мессенжер класстарыбызды түзө алабыз. Компилятордун өзү бизди аларды класстардын ичинде ишке ашырууга "мажбур кылат". 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!");
     }
}
Бул кандай пайдаларды берет? Алардын эң негизгиси – бош байланыш. Элестеткиле, биз кардарлардын маалыматтарын чогулта турган программаны иштеп жатабыз. Класста Clientкардар кайсы мессенджерди колдонгонун көрсөтүүчү талаа болушу керек. Интерфейстерсиз ал кызыктай көрүнөт:
public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
Биз үч талаа түздүк, бирок кардар оңой эле бир эле мессенджерге ээ болот. Биз кайсынысын билбейбиз. Ал эми кардар менен байланышсыз калбаш үчүн, бардык мүмкүн болгон варианттарды класска "түртүшүңүз" керек. Көрсө, алардын бир же экиси дайыма ошол жерде болот nullжана программа иштеши үчүн алар таптакыр керек эмес. Анын ордуна, биздин интерфейсти колдонуу жакшы:
public class Client {

    private Messenger messenger;
}
Бул "бошоң байланыштын" мисалы! Класста белгилүү бир мессенджер классын көрсөтүүнүн ордуна Client, биз кардардын мессенджери бар экенин жөн гана айтабыз. Кайсысы программанын жүрүшүндө аныкталат. Бирок бул үчүн интерфейстер эмне үчүн керек? Эмне үчүн алар тилге таптакыр кошулган? Суроо жакшы жана туура! Ошол эле натыйжага кадимки мурас аркылуу жетишсе болот, туурабы? Класс Messengerата-эне класс, жана Viber, Telegramжана WhatsAppмураскорлор. Чынында эле, мындай кылууга болот. Бирок бир нерсе бар. Белгилүү болгондой, Javaда бир нече мурас жок. Бирок интерфейстердин бир нече ишке ашырылышы бар. Класс каалагандай интерфейсти ишке ашыра алат. SmartphoneЭлестеткиле, бизде талаа бар класс бар Application- смартфонго орнотулган тиркеме.
public class Smartphone {

    private Application application;
}
Тиркеме жана мессенджер, албетте, окшош, бирок баары бир алар башка нерселер. Messenger мобилдик жана рабочий болушу мүмкүн, ал эми Колдонмо мобилдик тиркеме. TelegramДемек, эгерде биз мурасты колдонсок, класска an objectти кошо албайбыз Smartphone. Анткени, класс тен жана андан Telegramмурас ала алbyte ! Жана биз буга чейин аны мурастап , класска ушул формада кошууга жетиштик . Бирок класс эки интерфейсти оңой ишке ашыра алат! Демек, класста биз an objectти , ал эми класста катары ишке ашыра алабыз . Бул кандайча жасалат: 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();
    }
}
Эми классты Telegramкаалагандай колдоно алабыз. Бир жерде ал ролдо Application, бир жерде роль ойнойт Messenger. Интерфейстеги методдор ар дайым “бош”, башкача айтканда, алардын ишке ашырылышы жок экенин байкаган чыгарсыз. Мунун себеби жөнөкөй: интерфейс аны ишке ашырbyte, жүрүм-турумду сүрөттөйт. "Интерфейсти ишке ашырган класстардын бардык an objectтери Swimmableкалкып кете алгыдай болушу керек": интерфейстин баары ушуну айтат. Балык, өрдөк же ат кандайча сүзөт деген суроо интерфейс үчүн эмес Fish, класстар үчүн Duckжана . HorseКаналды алмаштыруу телевизордун милдети сыяктуу. Пульт жөн гана сизге бул үчүн баскычты берет. Бирок, Java8 кызыктуу кошумча бар - демейки ыкмалары. Мисалы, интерфейсиңизде 10 ыкма бар. Алардын 9у ар кандай класстарда ар кандай ишке ашырылат, бирок бирөө бардыгы үчүн бирдей ишке ашырылат. Буга чейин, Java8 чыкканга чейин, интерфейстердин ичиндеги методдор такыр ишке ашырылчу эмес: компилятор дароо ката кетирди. Эми сиз муну мындай кылсаңыз болот:
public interface Swimmable {

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

   public void eat();

   public void run();
}
Ачкыч сөздү колдонуу менен default, интерфейсте демейки ишке ашыруу менен ыкманы түздүк. Биз башка эки ыкманы ишке ашырышыбыз керек, eat()жана run()өзүбүз ишке ашыра турган бардык класстарда Swimmable. Муну метод менен жасоонун кереги жок swim(): ишке ашыруу бардык класстарда бирдей болот. Айтмакчы, сиз интерфейстерди мурунку тапшырмаларда бир нече жолу кезиктирдиңиз, бирок аны өзүңүз байкаган жоксуз :) Бул жерде ачык мисал: Эмне үчүн бизге Java интерфейси керек - 2Сиз интерфейстер менен иштегенсиз Listжана Set! Тагыраак айтканда, алардын ишке ашырылышы менен - ArrayList​​, LinkedList, HashSetжана башкалар. Ошол эле диаграммада бир класс бир эле учурда бир нече интерфейсти ишке ашыруунун мисалы көрсөтүлгөн. Мисалы, LinkedListал интерфейстерди Listжана Deque(эки тараптуу кезек) ишке ашырат. Сиз ошондой эле интерфейс менен Map, тагыраак айтканда, анын ишке ашырылышы менен таанышсыз - HashMap. Айтмакчы, бул диаграммада сиз бир өзгөчөлүктү көрө аласыз: интерфейстер бири-биринен мураска алынышы мүмкүн. Интерфейс SortedMapкезектен мураска алынган Mapжана Dequeкезектен мураска алынган Queue. Бул интерфейстердин ортосундагы байланышты көрсөтүүнү кааласаңыз, бирок бир интерфейс башкасынын кеңейтилген versionсы болсо керек. Келгиле, интерфейси бар мисалды карап көрөлү Queue- кезек. Биз коллекцияларды карап чыга элекпиз Queue, бирок алар абдан жөнөкөй жана дүкөндөгү кадимки линиядай тизилген. Сиз элементтерди кезектин аягына гана кошуп, аларды башынан гана алып салсаңыз болот. Белгилүү бир этапта иштеп чыгуучуларга эки тараптан тең элементтер кошулуп жана кабыл алынышы үчүн кезектин кеңейтилген versionсы керек болгон. Мына ушундайча интерфейс түзүлгөн Deque- эки тараптуу кезек. Ал кадимки кезектин бардык ыкмаларын камтыйт, анткени ал эки тараптуу кезектин “ата-энеси”, бирок жаңы ыкмалар кошулган.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION