CodeGym/Blog Java/rawak/Polimorfisme Java
John Squirrels
Tahap
San Francisco

Polimorfisme Java

Diterbitkan dalam kumpulan
Soalan berkaitan OOP adalah sebahagian daripada temu bual teknikal untuk jawatan pembangun Java dalam syarikat IT. Dalam artikel ini, kita akan bercakap tentang satu prinsip OOP - polimorfisme. Kami akan memberi tumpuan kepada aspek yang sering ditanya semasa temu bual, dan juga memberikan beberapa contoh untuk kejelasan.

Apakah polimorfisme dalam Java?

Polimorfisme ialah keupayaan program untuk merawat objek dengan antara muka yang sama dengan cara yang sama, tanpa maklumat tentang jenis khusus objek. Jika anda menjawab soalan tentang apa itu polimorfisme, kemungkinan besar anda akan diminta untuk menerangkan maksud anda. Tanpa mencetuskan banyak soalan tambahan, bentangkan semuanya untuk penemuduga sekali lagi. Masa temu bual: polimorfisme dalam Java - 1Anda boleh mulakan dengan fakta bahawa pendekatan OOP melibatkan membina program Java berdasarkan interaksi antara objek, yang berdasarkan kelas. Kelas ialah cetak biru (templat) yang ditulis sebelum ini digunakan untuk mencipta objek dalam atur cara. Selain itu, kelas sentiasa mempunyai jenis tertentu, yang, dengan gaya pengaturcaraan yang baik, mempunyai nama yang mencadangkan tujuannya. Selanjutnya, boleh diperhatikan bahawa oleh kerana Java ditaip dengan kuat, kod program mesti sentiasa menentukan jenis objek apabila pembolehubah diisytiharkan. Tambah pada fakta ini bahawa penaipan yang ketat meningkatkan keselamatan dan kebolehpercayaan kod, dan memungkinkan, walaupun semasa penyusunan, untuk mengelakkan ralat disebabkan oleh jenis ketidakserasian (contohnya, cuba membahagikan rentetan dengan nombor). Sememangnya, penyusun mesti "tahu" jenis yang diisytiharkan – ia boleh menjadi kelas daripada JDK atau kelas yang kami cipta sendiri. Tunjukkan kepada penemuduga bahawa kod kami boleh menggunakan bukan sahaja objek jenis yang ditunjukkan dalam perisytiharan tetapi juga keturunannya.Ini adalah perkara penting: kita boleh bekerja dengan pelbagai jenis sebagai satu jenis (dengan syarat jenis ini berasal daripada jenis asas). Ini juga bermakna jika kita mengisytiharkan pembolehubah yang jenisnya ialah superclass, maka kita boleh menetapkan contoh salah satu keturunannya kepada pembolehubah itu. Penemuduga akan suka jika anda memberi contoh. Pilih beberapa kelas yang boleh dikongsi oleh (kelas asas untuk) beberapa kelas dan jadikan beberapa kelas mewarisinya. Kelas asas:
public class Dancer {
    private String name;
    private int age;

    public Dancer(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void dance() {
        System.out.println(toString() + " I dance like everyone else.");
    }

    @Override
    public String toString() {
        Return "I'm " + name + ". I'm " + age + " years old.";
    }
}
Dalam subkelas, ganti kaedah kelas asas:
public class ElectricBoogieDancer extends Dancer {
    public ElectricBoogieDancer(String name, int age) {
        super(name, age);
    }
// Override the method of the base class
    @Override
    public void dance() {
        System.out.println(toString () + " I dance the electric boogie!");
    }
}

public class Breakdancer extends Dancer {

    public Breakdancer(String name, int age) {
        super(name, age);
    }
// Override the method of the base class
    @Override
    public void dance() {
        System.out.println(toString() + " I breakdance!");
    }
}
Contoh polimorfisme dan cara objek ini boleh digunakan dalam atur cara:
public class Main {

    public static void main(String[] args) {
        Dancer dancer = new Dancer("Fred", 18);

        Dancer breakdancer = new Breakdancer("Jay", 19); // Widening conversion to the base type
        Dancer electricBoogieDancer = new ElectricBoogieDancer("Marcia", 20); // Widening conversion to the base type

        List<dancer> disco = Arrays.asList(dancer, breakdancer, electricBoogieDancer);
        for (Dancer d : disco) {
            d.dance(); // Call the polymorphic method
        }
    }
}
Dalam kaedah utama , tunjukkan bahawa garisan
Dancer breakdancer = new Breakdancer("Jay", 19);
Dancer electricBoogieDancer = new ElectricBoogieDancer("Marcia", 20);
mengisytiharkan pembolehubah superclass dan memberikannya objek yang merupakan contoh salah satu keturunannya. Anda berkemungkinan besar akan ditanya mengapa pengkompil tidak beralih pada ketidakkonsistenan jenis yang diisytiharkan di sebelah kiri dan kanan pengendali tugasan — lagipun, Java ditaip dengan kuat. Terangkan bahawa penukaran jenis pelebaran sedang berfungsi di sini — rujukan kepada objek dianggap seperti rujukan kepada kelas asasnya. Lebih-lebih lagi, setelah menemui binaan sedemikian dalam kod, pengkompil melakukan penukaran secara automatik dan tersirat. Kod sampel menunjukkan bahawa jenis yang diisytiharkan di sebelah kiri pengendali tugasan ( Dancer ) mempunyai berbilang bentuk (jenis), yang diisytiharkan di sebelah kanan ( Breakdancer , ElectricBoogieDancer). Setiap bentuk boleh mempunyai tingkah laku uniknya sendiri berkenaan dengan fungsi umum yang ditakrifkan dalam superclass ( kaedah tarian ). Iaitu, kaedah yang diisytiharkan dalam superclass mungkin dilaksanakan secara berbeza dalam keturunannya. Dalam kes ini, kita sedang berurusan dengan kaedah mengatasi, iaitu apa yang mencipta pelbagai bentuk (tingkah laku). Ini boleh dilihat dengan menjalankan kod dalam kaedah utama: Output program: Saya Fred. Saya berumur 18 tahun. Saya menari seperti orang lain. Saya Jay. Saya berumur 19 tahun. Saya breakdance! Saya Marcia. Saya berumur 20 tahun. Saya menari boogie elektrik! Jika kita tidak mengatasi kaedah dalam subkelas, maka kita tidak akan mendapat tingkah laku yang berbeza. Sebagai contoh,ElectricBoogieDancer kelas, maka output program adalah ini: Saya Fred. Saya berumur 18 tahun. Saya menari seperti orang lain. Saya Jay. Saya berumur 19 tahun. Saya menari seperti orang lain. Saya Marcia. Saya berumur 20 tahun. Saya menari seperti orang lain. Dan ini bermakna bahawa tidak masuk akal untuk mencipta kelas Breakdancer dan ElectricBoogieDancer . Di manakah secara khusus prinsip polimorfisme nyata? Di manakah objek digunakan dalam program tanpa pengetahuan tentang jenis khususnya? Dalam contoh kami, ia berlaku apabila kaedah dance() dipanggil pada objek Dancer d . Di Jawa, polimorfisme bermakna program tidak perlu mengetahui sama ada objek itu ialah aBreakdancer atau ElectricBoogieDancer . Yang penting ia adalah keturunan kelas Penari . Dan jika anda menyebut keturunan, anda harus ambil perhatian bahawa warisan di Jawa bukan hanya extends , tetapi juga melaksanakan. Sekarang adalah masa untuk menyebut bahawa Java tidak menyokong berbilang warisan — setiap jenis boleh mempunyai satu induk (superclass) dan bilangan keturunan yang tidak terhad (subclass). Sehubungan itu, antara muka digunakan untuk menambah beberapa set fungsi pada kelas. Berbanding dengan subkelas (warisan), antara muka kurang digabungkan dengan kelas induk. Mereka digunakan secara meluas. Dalam Java, antara muka ialah jenis rujukan, jadi program boleh mengisytiharkan pembolehubah jenis antara muka. Kini tiba masanya untuk memberi contoh. Buat antara muka:
public interface CanSwim {
    void swim();
}
Untuk kejelasan, kami akan mengambil pelbagai kelas yang tidak berkaitan dan menjadikannya melaksanakan antara muka:
public class Human implements CanSwim {
    private String name;
    private int age;

    public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public void swim() {
        System.out.println(toString()+" I swim with an inflated tube.");
    }

    @Override
    public String toString() {
        return "I'm " + name + ". I'm " + age + " years old.";
    }

}

public class Fish implements CanSwim {
    private String name;

    public Fish(String name) {
        this.name = name;
    }

    @Override
    public void swim() {
        System.out.println("I'm a fish. My name is " + name + ". I swim by moving my fins.");

    }

public class UBoat implements CanSwim {

    private int speed;

    public UBoat(int speed) {
        this.speed = speed;
    }

    @Override
    public void swim() {
        System.out.println("I'm a submarine that swims through the water by rotating screw propellers. My speed is " + speed + " knots.");
    }
}
kaedah utama :
public class Main {

    public static void main(String[] args) {
        CanSwim human = new Human("John", 6);
        CanSwim fish = new Fish("Whale");
        CanSwim boat = new UBoat(25);

        List<swim> swimmers = Arrays.asList(human, fish, boat);
        for (Swim s : swimmers) {
            s.swim();
        }
    }
}
Keputusan memanggil kaedah polimorfik yang ditakrifkan dalam antara muka menunjukkan kepada kita perbezaan dalam tingkah laku jenis yang melaksanakan antara muka ini. Dalam kes kami, ini adalah rentetan berbeza yang dipaparkan oleh kaedah berenang . Selepas mengkaji contoh kami, penemuduga mungkin bertanya mengapa menjalankan kod ini dalam kaedah utama
for (Swim s : swimmers) {
            s.swim();
}
menyebabkan kaedah utama yang ditakrifkan dalam subkelas kami dipanggil? Bagaimanakah pelaksanaan kaedah yang dikehendaki dipilih semasa program sedang dijalankan? Untuk menjawab soalan ini, anda perlu menerangkan pengikatan lewat (dinamik). Mengikat bermaksud mewujudkan pemetaan antara panggilan kaedah dan pelaksanaan kelas khususnya. Pada dasarnya, kod menentukan yang mana antara tiga kaedah yang ditakrifkan dalam kelas akan dilaksanakan. Java menggunakan pengikatan lewat secara lalai, iaitu pengikatan berlaku pada masa jalan dan bukan pada masa penyusunan seperti yang berlaku dengan pengikatan awal. Ini bermakna apabila pengkompil menyusun kod ini
for (Swim s : swimmers) {
            s.swim();
}
ia tidak tahu kelas mana ( Manusia , Ikan atau Uboat ) mempunyai kod yang akan dilaksanakan apabila berenangkaedah dipanggil. Ini ditentukan hanya apabila program dilaksanakan, terima kasih kepada mekanisme pengikatan dinamik (menyemak jenis objek semasa runtime dan memilih pelaksanaan yang betul untuk jenis ini). Jika anda ditanya bagaimana ini dilaksanakan, anda boleh menjawab bahawa apabila memuatkan dan memulakan objek, JVM membina jadual dalam memori dan memautkan pembolehubah dengan nilai dan objeknya dengan kaedahnya. Dengan berbuat demikian, jika kelas diwarisi atau melaksanakan antara muka, perintah pertama perniagaan adalah untuk menyemak kehadiran kaedah yang diganti. Jika ada, mereka terikat dengan jenis ini. Jika tidak, carian untuk kaedah padanan bergerak ke kelas yang satu langkah lebih tinggi (induk) dan seterusnya sehingga ke akar dalam hierarki berbilang peringkat. Apabila ia datang kepada polimorfisme dalam OOP dan pelaksanaannya dalam kod, kami ambil perhatian bahawa adalah amalan yang baik untuk menggunakan kelas abstrak dan antara muka untuk memberikan definisi abstrak kelas asas. Amalan ini mengikut prinsip pengabstrakan — mengenal pasti gelagat dan sifat biasa dan meletakkannya dalam kelas abstrak, atau mengenal pasti gelagat biasa sahaja dan meletakkannya dalam antara muka. Mereka bentuk dan mencipta hierarki objek berdasarkan antara muka dan warisan kelas diperlukan untuk melaksanakan polimorfisme. Mengenai polimorfisme dan inovasi dalam Java, kami perhatikan bahawa bermula dengan Java 8, apabila membuat kelas dan antara muka abstrak adalah mungkin untuk menggunakan atau mengenal pasti tingkah laku biasa sahaja dan meletakkannya dalam antara muka. Mereka bentuk dan mencipta hierarki objek berdasarkan antara muka dan warisan kelas diperlukan untuk melaksanakan polimorfisme. Mengenai polimorfisme dan inovasi dalam Java, kami perhatikan bahawa bermula dengan Java 8, apabila membuat kelas dan antara muka abstrak adalah mungkin untuk menggunakan atau mengenal pasti tingkah laku biasa sahaja dan meletakkannya dalam antara muka. Mereka bentuk dan mencipta hierarki objek berdasarkan antara muka dan warisan kelas diperlukan untuk melaksanakan polimorfisme. Mengenai polimorfisme dan inovasi dalam Java, kami perhatikan bahawa bermula dengan Java 8, apabila membuat kelas dan antara muka abstrak adalah mungkin untuk menggunakankata kunci lalai untuk menulis pelaksanaan lalai untuk kaedah abstrak dalam kelas asas. Sebagai contoh:
public interface CanSwim {
    default void swim() {
        System.out.println("I just swim");
    }
}
Kadangkala penemuduga bertanya tentang bagaimana kaedah dalam kelas asas mesti diisytiharkan supaya prinsip polimorfisme tidak dilanggar. Jawapannya mudah: kaedah ini tidak boleh statik , peribadi atau muktamad . Peribadi menjadikan kaedah tersedia hanya dalam kelas, jadi anda tidak akan dapat mengatasinya dalam subkelas. Statik mengaitkan kaedah dengan kelas dan bukannya sebarang objek, jadi kaedah superclass akan sentiasa dipanggil. Dan akhir membuat kaedah tidak berubah dan tersembunyi daripada subkelas.

Apakah yang diberikan oleh polimorfisme kepada kita?

Anda juga berkemungkinan besar akan ditanya tentang cara polimorfisme memberi manfaat kepada kami. Anda boleh menjawab ini secara ringkas tanpa terperangkap dalam butiran berbulu:
  1. Ia memungkinkan untuk menggantikan pelaksanaan kelas. Ujian dibina di atasnya.
  2. Ia memudahkan pemanjangan, menjadikannya lebih mudah untuk mencipta asas yang boleh dibina pada masa hadapan. Menambah jenis baharu berdasarkan yang sedia ada ialah cara paling biasa untuk mengembangkan kefungsian program OOP.
  3. Ia membolehkan anda menggabungkan objek yang berkongsi jenis atau tingkah laku biasa ke dalam satu koleksi atau tatasusunan dan mengendalikannya secara seragam (seperti dalam contoh kami, di mana kami memaksa semua orang menari() atau berenang () :)
  4. Fleksibiliti dalam mencipta jenis baharu: anda boleh memilih pelaksanaan kaedah induk atau mengatasinya dalam subkelas.

Beberapa kata perpisahan

Polimorfisme adalah topik yang sangat penting dan meluas. Ia adalah subjek hampir separuh daripada artikel ini tentang OOP di Jawa dan membentuk sebahagian besar asas bahasa. Anda tidak akan dapat mengelak daripada mentakrifkan prinsip ini dalam temu bual. Jika anda tidak tahu atau tidak memahaminya, temuduga mungkin akan berakhir. Oleh itu, jangan menjadi pemalas — nilai pengetahuan anda sebelum temu duga dan muat semula jika perlu.
Komen
  • Popular
  • Baru
  • Tua
Anda mesti log masuk untuk meninggalkan ulasan
Halaman ini tidak mempunyai sebarang ulasan lagi