CodeGym /Blog Java /rawak /Mengapa Kami Memerlukan Antara Muka di Java
John Squirrels
Tahap
San Francisco

Mengapa Kami Memerlukan Antara Muka di Java

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan bercakap tentang konsep penting dalam Java: antara muka. Perkataan itu mungkin biasa kepada anda. Sebagai contoh, kebanyakan program komputer dan permainan mempunyai antara muka. Dalam erti kata yang luas, antara muka ialah sejenis 'kawalan jauh' yang menghubungkan dua pihak yang berinteraksi. Contoh mudah antara muka dalam kehidupan seharian ialah alat kawalan jauh TV. Ia menghubungkan dua objek — seseorang dan TV — dan melaksanakan tugas yang berbeza: naikkan atau kecilkan kelantangan, tukar saluran dan hidupkan atau matikan TV. Satu pihak (orang itu) perlu mengakses antara muka (tekan butang pada alat kawalan jauh) untuk menyebabkan pihak kedua melakukan tindakan tersebut. Contohnya, untuk membuat TV bertukar ke saluran seterusnya. Apatah lagi, pengguna tidak t perlu tahu bagaimana TV disusun atau bagaimana proses penukaran saluran dilaksanakan secara dalaman. Satu-satunya perkara yang boleh diakses oleh pengguna ialah antara muka. Objektif utama adalah untuk mendapatkan hasil yang diinginkan. Apakah kaitan ini dengan pengaturcaraan dan Java? Semuanya :) Mencipta antara muka adalah sangat serupa dengan mencipta kelas biasa, tetapi sebaliknya menggunakan perkataankelas , kami menunjukkan antara muka perkataan . Mari lihat antara muka Java yang paling mudah, lihat cara ia berfungsi, dan sebab kami memerlukannya:

public interface CanSwim {

     public void swim();
}
Kami telah mencipta antara muka CanSwim . Ia agak seperti alat kawalan jauh kami, tetapi dengan satu 'butang': kaedah swim() . Tetapi bagaimana kita menggunakan alat kawalan jauh ini? Untuk melakukan ini, kita perlu melaksanakan kaedah, iaitu butang kawalan jauh kita. Untuk menggunakan antara muka, beberapa kelas dalam program kami mesti melaksanakan kaedahnya. Mari cipta kelas yang objeknya 'boleh berenang'. Sebagai contoh, kelas Itik sesuai:

public class Duck implements CanSwim {

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

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
"Apa yang kita lihat di sini? Kelas Duck 'dikaitkan' dengan antara muka CanSwim oleh kata kunci implements . Anda mungkin ingat bahawa kami menggunakan mekanisme yang sama untuk mengaitkan dua kelas melalui warisan, tetapi dalam kes itu kami menggunakan perkataan extends. Untuk dengan kejelasan lengkap, kita boleh menterjemah ' kelas awam Duck melaksanakan CanSwim ' secara literal sebagai: ' Kelas Duck awam melaksanakan antara muka CanSwim '. Ini bermakna kelas yang dikaitkan dengan antara muka mesti melaksanakan semua kaedahnya. Nota: Duckkelas kami, sama seperti antara CanSwimmuka, mempunyai swim()kaedah, dan ia mengandungi beberapa logik. Ini adalah keperluan wajib. Jika kita hanya menulispublic class Duck implements CanSwimtanpa mencipta swim()kaedah dalam Duckkelas, pengkompil akan memberi kami ralat: Duck bukan abstrak dan tidak mengatasi kaedah abstrak swim() dalam CanSwim Why? Mengapa ini berlaku? Jika kami menerangkan ralat menggunakan contoh TV, ia adalah seperti menyerahkan seseorang alat kawalan jauh TV dengan butang 'tukar saluran' yang tidak boleh menukar saluran. Anda boleh menekan butang seberapa banyak yang anda suka, tetapi ia tidak akan berfungsi. Alat kawalan jauh tidak menukar saluran dengan sendirinya: ia hanya menghantar isyarat kepada TV, yang melaksanakan proses penukaran saluran yang kompleks. Begitu juga dengan itik kita: ia mesti tahu cara berenang supaya ia boleh dipanggil menggunakan CanSwimantara muka. Jika ia tidak tahu bagaimana, yangCanSwimantara muka tidak menghubungkan dua pihak — orang dan program. Orang itu tidak akan dapat menggunakan swim()kaedah untuk berenang Duckdi dalam program. Kini anda memahami dengan lebih jelas untuk kegunaan antara muka. Antara muka menerangkan tingkah laku yang kelas yang melaksanakan antara muka mesti ada. 'Kelakuan' ialah himpunan kaedah. Jika kita ingin mencipta beberapa messenger, perkara paling mudah untuk dilakukan ialah mencipta antara Messengermuka. Apakah yang diperlukan oleh setiap utusan? Pada peringkat asas, mereka mesti boleh menerima dan menghantar mesej.

public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
Kini kita hanya boleh membuat kelas messenger kita yang melaksanakan antara muka yang sepadan. Pengkompil itu sendiri akan 'memaksa' kami untuk melaksanakannya dalam kelas kami. Telegram:

public class Telegram implements Messenger {

    public void sendMessage() {

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

     public void getMessage() {
         System.out.println("Receiving a Telegram message!");
     }
}
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 Viber message!");
    }

     public void getMessage() {
         System.out.println("Receiving a Viber message!");
     }
}
Apakah kelebihan yang diberikan ini? Yang paling penting ialah gandingan longgar. Bayangkan bahawa kami sedang mereka bentuk program yang akan mengumpul data pelanggan. Kelas Clientpasti memerlukan medan untuk menunjukkan messenger tertentu yang digunakan oleh pelanggan. Tanpa antara muka, ini akan kelihatan pelik:

public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
Kami mencipta tiga medan, tetapi pelanggan hanya boleh mempunyai satu messenger. Cuma kita tak tahu yang mana satu. Oleh itu, kami perlu menambah setiap kemungkinan kepada kelas untuk dapat berkomunikasi dengan pelanggan. Ternyata satu atau dua daripadanya akan sentiasa null, sama sekali tidak diperlukan oleh program ini. Lebih baik menggunakan antara muka kami sebaliknya:

public class Client {

    private Messenger messenger;
}
Ini adalah contoh gandingan longgar! Daripada menentukan kelas messenger tertentu dalam Clientkelas, kami hanya menunjukkan bahawa klien mempunyai messenger. Yang mana satu tepat akan ditentukan semasa program berjalan. Tetapi mengapa kita memerlukan antara muka untuk ini? Mengapa mereka ditambah kepada bahasa itu? Itu soalan yang bagus — dan soalan yang betul! Tidak bolehkah kita mencapai hasil yang sama menggunakan warisan biasa? Kelas Messengersebagai ibu bapa, dan Viber, Telegram, dan WhatsAppsebagai kanak-kanak. Memang, itu mungkin. Tetapi ada satu halangan. Seperti yang anda sedia maklum, Java tidak mempunyai pelbagai warisan. Tetapi terdapat sokongan untuk pelbagai antara muka. Kelas boleh melaksanakan seberapa banyak antara muka yang anda mahu. Bayangkan kita mempunyai Smartphonekelas yang mempunyai satuAppmedan, yang mewakili aplikasi yang dipasang pada telefon pintar.

public class Smartphone {

    private App app;
}
Sudah tentu, aplikasi dan messenger adalah serupa, tetapi mereka masih perkara yang berbeza. Mungkin terdapat versi mudah alih dan desktop utusan, tetapi Apl secara khusus mewakili apl mudah alih. Inilah tawarannya — jika kami menggunakan warisan, kami tidak akan dapat menambahkan Telegramobjek pada Smartphonekelas. Lagipun, Telegramkelas tidak boleh mewarisi Appdan Messenger! Dan kami telah menjadikannya mewarisi Messengerdan menambahkannya pada Clientkelas. Tetapi Telegramkelas boleh dengan mudah melaksanakan kedua-dua antara muka! Oleh itu, kita boleh memberikan Clientkelas Telegramobjek sebagai Messenger, dan kita boleh memberikannya kepada Smartphonekelas sebagai App. Begini cara anda melakukannya:

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();
    }
}
Sekarang kita menggunakan Telegramkelas seperti yang kita mahu. Di sesetengah tempat, ia bertindak sebagai App. Di tempat lain, ia bertindak sebagai Messenger. Anda pastinya telah perasan bahawa kaedah antara muka sentiasa 'kosong', iaitu ia tidak mempunyai pelaksanaan. Sebabnya adalah mudah: antara muka menerangkan tingkah laku, tetapi ia tidak melaksanakannya. 'Semua objek yang melaksanakan CanSwimantara muka mesti boleh berenang': itu sahaja yang antara muka memberitahu kami. Cara khusus ikan, itik dan kuda berenang ialah soalan untuk Fish, Duck, danHorsekelas, bukan antara muka. Sama seperti menukar saluran adalah tugas untuk TV. Alat kawalan jauh hanya memberi anda butang untuk ini. Walau bagaimanapun, penambahan menarik muncul dalam Java 8 — kaedah lalai. Sebagai contoh, antara muka anda mempunyai 10 kaedah. 9 daripadanya mempunyai pelaksanaan yang berbeza dalam kelas yang berbeza, tetapi satu dilaksanakan sama untuk semua. Sebelum ini, sebelum Java 8, kaedah antara muka tidak mempunyai pelaksanaan apa-apa: pengkompil segera memberikan ralat. Sekarang anda boleh melakukan sesuatu seperti ini:

public interface CanSwim {

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

   public void eat();

   public void run();
}
Menggunakan defaultkata kunci, kami telah mencipta kaedah antara muka dengan pelaksanaan lalai. Kami perlu menyediakan pelaksanaan kami sendiri untuk dua kaedah lain — eat()dan run()— dalam semua kelas yang melaksanakan CanSwim. Kami tidak perlu melakukan ini dengan swim()kaedah: pelaksanaan akan sama dalam setiap kelas. Ngomong-ngomong, anda telah menemui antara muka dalam tugasan lepas, walaupun anda tidak perasan :) Berikut ialah contoh yang jelas: Mengapa antara muka diperlukan dalam Java - 2Anda telah bekerja dengan antara muka Listdan Set! Lebih tepat lagi, anda telah bekerja dengan pelaksanaannya — ArrayList, LinkedList, HashSet, dsb. Gambar rajah yang sama jelas memberikan contoh di mana satu kelas melaksanakan berbilang antara muka pada masa yang sama. Sebagai contoh, LinkedListmelaksanakan ListdanDeque(baris gilir dua hujung) antara muka. Anda sudah biasa dengan Mapantara muka, atau sebaliknya, dengan pelaksanaannya HashMap. Dengan cara ini, rajah ini menggambarkan ciri: antara muka boleh mewarisi antara muka lain. Antara SortedMapmuka mewarisi Map, manakala Dequemewarisi Queue. Ini perlu jika anda ingin menunjukkan hubungan antara antara muka, di mana satu antara muka adalah versi lanjutan bagi yang lain. Mari kita pertimbangkan contoh dengan Queueantara muka. Kami belum menyemak lagiQueues, tetapi ia agak mudah dan berfungsi seperti baris gilir biasa, atau barisan, di kedai. Anda hanya boleh menambah item pada penghujung baris gilir dan hanya boleh membawanya dari awal. Pada satu ketika, pembangun memerlukan versi baris gilir yang dipertingkatkan untuk menambah dan mengambil item di kedua-dua hujungnya. Jadi mereka mencipta Dequeantara muka, iaitu baris gilir dua hujung. Ia mempunyai semua kaedah baris gilir biasa. Lagipun, ia adalah induk kepada baris gilir dua hujung, tetapi ia juga menambah kaedah baharu.
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION