CodeGym /Java Blog /Acak /Mengapa Kita Membutuhkan Antarmuka di Java
John Squirrels
Level 41
San Francisco

Mengapa Kita Membutuhkan Antarmuka di Java

Dipublikasikan di grup Acak
Hai! Hari ini kita akan berbicara tentang konsep penting dalam Java: antarmuka. Kata tersebut mungkin sudah tidak asing lagi bagi Anda. Misalnya, sebagian besar program dan game komputer memiliki antarmuka. Dalam arti luas, antarmuka adalah semacam 'kendali jarak jauh' yang menghubungkan dua pihak yang berinteraksi. Contoh sederhana antarmuka dalam kehidupan sehari-hari adalah remote control TV. Ini menghubungkan dua objek — seseorang dan TV — dan melakukan tugas yang berbeda: menaikkan atau menurunkan volume, mengganti saluran, dan menghidupkan atau mematikan TV. Satu pihak (orang tersebut) perlu mengakses antarmuka (tekan tombol pada remote control) agar pihak kedua melakukan tindakan tersebut. Misalnya, untuk mengubah TV ke saluran berikutnya. Terlebih lagi, pengguna tidak Anda tidak perlu tahu bagaimana TV diatur atau bagaimana proses perubahan saluran diimplementasikan secara internal. Satu-satunya hal yang dapat diakses pengguna adalah antarmuka. Tujuan utamanya adalah untuk mendapatkan hasil yang diinginkan. Apa hubungannya ini dengan pemrograman dan Java? Semuanya :) Membuat antarmuka sangat mirip dengan membuat kelas biasa, tetapi menggunakan kataclass , kami menunjukkan kata interface . Mari kita lihat antarmuka Java yang paling sederhana, lihat cara kerjanya, dan mengapa kita membutuhkannya:

public interface CanSwim {

     public void swim();
}
Kami telah membuat antarmuka CanSwim . Ini agak mirip dengan remote control kami, tetapi dengan satu 'tombol': metode swim() . Tapi bagaimana kita menggunakan pengendali jarak jauh ini? Untuk melakukan ini, kita perlu mengimplementasikan sebuah metode, yaitu tombol remote control kita. Untuk menggunakan antarmuka, beberapa kelas dalam program kita harus mengimplementasikan metodenya. Mari kita buat kelas yang objeknya 'bisa berenang'. Misalnya, kelas Bebek cocok dengan:

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 antarmuka CanSwim dengan kata kunci implements . Anda mungkin ingat bahwa kita menggunakan mekanisme serupa untuk mengasosiasikan dua kelas melalui pewarisan, tetapi dalam kasus itu kita menggunakan kata extends. Untuk kejelasan lengkap, kita dapat menerjemahkan ' Bebek kelas publik mengimplementasikan CanSwim ' secara harfiah sebagai: ' Kelas Bebek publik mengimplementasikan antarmuka CanSwim '. Ini berarti bahwa kelas yang terkait dengan antarmuka harus mengimplementasikan semua metodenya. Catatan: Duckkelas kami, sama seperti antarmuka CanSwim, memiliki swim()metode, dan mengandung beberapa logika. Ini adalah persyaratan wajib. Jika kita hanya menulispublic class Duck implements CanSwimtanpa membuat swim()metode di Duckkelas, kompiler akan memberi kita kesalahan: Duck is not abstract and not override abstract method swim() in CanSwim Why? Mengapa ini terjadi? Jika kami menjelaskan kesalahan menggunakan contoh TV, itu akan seperti menyerahkan remote control TV kepada seseorang dengan tombol 'ubah saluran' yang tidak dapat mengubah saluran. Anda dapat menekan tombol sebanyak yang Anda suka, tetapi itu tidak akan berhasil. Pengendali jarak jauh tidak mengubah saluran dengan sendirinya: ia hanya mengirimkan sinyal ke TV, yang mengimplementasikan proses rumit untuk mengubah saluran. Begitu pula dengan bebek kita: ia harus tahu cara berenang sehingga bisa dipanggil menggunakan antarmuka CanSwim. Jika tidak tahu bagaimana, theCanSwimantarmuka tidak menghubungkan kedua pihak — orang dan program. Orang tersebut tidak akan dapat menggunakan swim()metode untuk berenang Duckdi dalam program. Sekarang Anda mengerti lebih jelas untuk apa antarmuka itu. Antarmuka menggambarkan perilaku yang harus dimiliki oleh kelas yang mengimplementasikan antarmuka. 'Perilaku' adalah kumpulan metode. Jika kita ingin membuat beberapa messenger, hal termudah untuk dilakukan adalah membuat antarmuka Messenger. Apa yang dibutuhkan setiap utusan? Pada tingkat dasar, mereka harus bisa menerima dan mengirim pesan.

public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
Sekarang kita cukup membuat kelas messenger kita yang mengimplementasikan antarmuka yang sesuai. Kompiler itu sendiri akan 'memaksa' kita untuk mengimplementasikannya di kelas kita. 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!");
     }
}
Ada apa:

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!");
     }
}
Apa keuntungan yang diberikan ini? Yang paling penting dari mereka adalah kopling longgar. Bayangkan kita sedang merancang sebuah program yang akan mengumpulkan data klien. Kelas Clientpasti membutuhkan bidang untuk menunjukkan messenger spesifik mana yang digunakan klien. Tanpa antarmuka, ini akan terlihat aneh:

public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
Kami membuat tiga bidang, tetapi klien hanya dapat memiliki satu messenger. Kami hanya tidak tahu yang mana. Jadi kita harus menambahkan setiap kemungkinan ke kelas agar dapat berkomunikasi dengan klien. Ternyata satu atau dua di antaranya akan selalu null, sama sekali tidak dibutuhkan oleh program. Lebih baik menggunakan antarmuka kami sebagai gantinya:

public class Client {

    private Messenger messenger;
}
Ini adalah contoh kopling longgar! Alih-alih menentukan kelas messenger tertentu di Clientkelas, kami hanya menunjukkan bahwa klien memiliki messenger. Yang mana tepatnya akan ditentukan saat program berjalan. Tetapi mengapa kita membutuhkan antarmuka untuk ini? Mengapa mereka bahkan ditambahkan ke bahasa? Itu pertanyaan yang bagus — dan pertanyaan yang tepat! Tidak bisakah kita mencapai hasil yang sama dengan menggunakan warisan biasa? Kelas Messengersebagai orang tua, dan Viber, Telegram, dan WhatsAppsebagai anak. Memang, itu mungkin. Tapi ada satu halangan. Seperti yang sudah Anda ketahui, Java tidak memiliki pewarisan berganda. Tetapi ada dukungan untuk banyak antarmuka. Kelas dapat mengimplementasikan antarmuka sebanyak yang Anda inginkan. Bayangkan kita memiliki Smartphonekelas yang memilikinyaAppbidang, yang mewakili aplikasi yang diinstal pada ponsel cerdas.

public class Smartphone {

    private App app;
}
Tentu saja, aplikasi dan messenger serupa, tetapi keduanya tetap berbeda. Mungkin ada versi seluler dan desktop dari messenger, tetapi Aplikasi secara khusus mewakili aplikasi seluler. Inilah masalahnya — jika kita menggunakan warisan, kita tidak akan bisa menambahkan Telegramobjek ke Smartphonekelas. Lagi pula, Telegramkelas tidak dapat secara bersamaan mewarisi Appdan Messenger! Dan kami sudah membuatnya mewarisi Messengerdan menambahkannya ke Clientkelas. Tetapi Telegramkelas dapat dengan mudah mengimplementasikan kedua antarmuka! Oleh karena itu, kita bisa memberikan Clientkelas Telegramobjek sebagai a Messenger, dan kita bisa memberikannya ke Smartphonekelas sebagai App. Inilah 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 inginkan. Di beberapa tempat, ini berfungsi sebagai App. Di tempat lain, ia bertindak sebagai Messenger. Anda pasti sudah memperhatikan bahwa metode antarmuka selalu 'kosong', yaitu tidak memiliki implementasi. Alasannya sederhana: antarmuka menjelaskan perilaku, tetapi tidak mengimplementasikannya. 'Semua objek yang mengimplementasikan antarmuka CanSwimharus bisa berenang': hanya itu yang dikatakan antarmuka kepada kita. Cara spesifik ikan, bebek, dan kuda berenang adalah pertanyaan untuk Fish, Duck, danHorsekelas, bukan antarmuka. Sama seperti mengganti saluran adalah tugas TV. Remote hanya memberi Anda tombol untuk ini. Namun, tambahan yang menarik muncul di Java 8 — metode default. Misalnya, antarmuka Anda memiliki 10 metode. 9 dari mereka memiliki implementasi yang berbeda di kelas yang berbeda, tetapi satu diimplementasikan sama untuk semua. Sebelumnya, sebelum Java 8, metode antarmuka tidak memiliki implementasi apa pun: kompiler segera memberikan kesalahan. Sekarang Anda dapat 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 membuat metode antarmuka dengan implementasi default. Kita perlu menyediakan implementasi kita sendiri untuk dua metode lainnya — eat()dan run()— di semua kelas yang mengimplementasikan CanSwim. Kita tidak perlu melakukan ini dengan swim()metode: penerapannya akan sama di setiap kelas. Omong-omong, Anda telah menemukan antarmuka dalam tugas sebelumnya, bahkan jika Anda tidak menyadarinya :) Berikut adalah contoh nyata: Mengapa antarmuka diperlukan di Java - 2Anda telah bekerja dengan antarmuka Listdan Set! Lebih tepatnya, Anda telah bekerja dengan implementasinya — ArrayList, LinkedList, HashSet, dll. Diagram yang sama dengan jelas memberikan contoh di mana satu kelas mengimplementasikan beberapa antarmuka sekaligus. Misalnya, LinkedListmengimplementasikan ListdanDeque(antrean ujung ganda). Anda terbiasa dengan Mapantarmuka, atau lebih tepatnya, dengan penerapannya HashMap. Omong-omong, diagram ini mengilustrasikan sebuah fitur: antarmuka dapat mewarisi antarmuka lain. Antarmuka SortedMapmewarisi Map, sedangkan Dequemewarisi Queue. Ini diperlukan jika Anda ingin menunjukkan hubungan antar antarmuka, di mana satu antarmuka merupakan versi perluasan dari antarmuka lainnya. Mari pertimbangkan contoh dengan Queueantarmuka. Kami belum meninjauQueues, tetapi ini agak sederhana dan berfungsi seperti antrean biasa, atau antrean, di toko. Anda hanya dapat menambahkan item di akhir antrean, dan hanya dapat mengambilnya dari awal. Di beberapa titik, pengembang membutuhkan versi antrean yang disempurnakan untuk menambah dan mengambil item di kedua ujungnya. Jadi mereka membuat sebuah Dequeantarmuka, yang merupakan antrean berujung ganda. Ia memiliki semua metode antrian biasa. Bagaimanapun, ini adalah induk dari antrian ujung ganda, tetapi juga menambahkan metode baru.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION