CodeGym/Java Blog/Random/Java Polymorphism
John Squirrels
Antas
San Francisco

Java Polymorphism

Nai-publish sa grupo
Ang mga tanong na nauugnay sa OOP ay isang mahalagang bahagi ng teknikal na panayam para sa isang posisyon ng developer ng Java sa isang kumpanya ng IT. Sa artikulong ito, pag-uusapan natin ang tungkol sa isang prinsipyo ng OOP - polymorphism. Magtutuon tayo sa mga aspeto na madalas itanong sa panahon ng mga panayam, at magbibigay din ng ilang halimbawa para sa kalinawan.

Ano ang polymorphism sa Java?

Ang polymorphism ay ang kakayahan ng isang programa na tratuhin ang mga bagay na may parehong interface sa parehong paraan, nang walang impormasyon tungkol sa partikular na uri ng bagay. Kung sasagutin mo ang isang tanong tungkol sa kung ano ang polymorphism, malamang na hihilingin sa iyo na ipaliwanag kung ano ang ibig mong sabihin. Nang hindi nagti-trigger ng isang grupo ng mga karagdagang tanong, ilagay ang lahat ng ito para sa tagapanayam muli. Oras ng panayam: polymorphism sa Java - 1Maaari kang magsimula sa katotohanan na ang diskarte sa OOP ay nagsasangkot ng pagbuo ng isang Java program batay sa pakikipag-ugnayan sa pagitan ng mga bagay, na batay sa mga klase. Ang mga klase ay dating nakasulat na mga blueprint (mga template) na ginamit upang lumikha ng mga bagay sa programa. Bukod dito, ang isang klase ay palaging may isang tiyak na uri, na, na may mahusay na istilo ng programming, ay may isang pangalan na nagmumungkahi ng layunin nito. Dagdag pa, mapapansin na dahil malakas ang pag-type ng Java, dapat palaging tukuyin ng program code ang uri ng object kapag ang mga variable ay ipinahayag. Idagdag dito ang katotohanan na ang mahigpit na pag-type ay nagpapabuti sa seguridad at pagiging maaasahan ng code, at ginagawang posible, kahit na sa compilation, upang maiwasan ang mga error dahil sa mga uri ng hindi pagkakatugma (halimbawa, sinusubukang hatiin ang isang string sa isang numero). Natural, ang compiler ay dapat "alam" ang ipinahayag na uri – maaari itong maging isang klase mula sa JDK o isa na ginawa namin mismo. Ituro sa tagapanayam na maaaring gamitin ng ating code hindi lamang ang mga bagay ng uri na ipinahiwatig sa deklarasyon kundi pati na rin ang mga inapo nito.Ito ay isang mahalagang punto: maaari tayong magtrabaho sa maraming iba't ibang uri bilang isang uri (sa kondisyon na ang mga uri na ito ay nagmula sa isang baseng uri). Nangangahulugan din ito na kung magdedeklara tayo ng variable na ang uri ay isang superclass, maaari tayong magtalaga ng isang instance ng isa sa mga inapo nito sa variable na iyon. Magugustuhan ito ng tagapanayam kung magbibigay ka ng halimbawa. Pumili ng ilang klase na maaaring ibahagi ng (isang batayang klase para sa) ilang klase at gawin itong magmana ng dalawa sa kanila. Batayang klase:
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.";
    }
}
Sa mga subclass, i-override ang paraan ng base class:
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!");
    }
}
Isang halimbawa ng polymorphism at kung paano maaaring gamitin ang mga bagay na ito sa isang programa:
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
        }
    }
}
Sa pangunahing pamamaraan, ipakita na ang mga linya
Dancer breakdancer = new Breakdancer("Jay", 19);
Dancer electricBoogieDancer = new ElectricBoogieDancer("Marcia", 20);
magdeklara ng variable ng isang superclass at magtalaga dito ng object na isang instance ng isa sa mga inapo nito. Malamang na tatanungin ka kung bakit hindi nag-flip out ang compiler sa hindi pagkakapare-pareho ng mga uri na idineklara sa kaliwa at kanang bahagi ng operator ng pagtatalaga - pagkatapos ng lahat, ang Java ay malakas na na-type. Ipaliwanag na ang pagpapalawak ng uri ng conversion ay gumagana dito — ang isang reference sa isang bagay ay itinuturing na isang reference sa base class nito. Higit pa rito, na nakatagpo ng ganoong construct sa code, ang compiler ay nagsasagawa ng conversion nang awtomatiko at hindi malinaw. Ipinapakita ng sample code na ang uri na idineklara sa kaliwang bahagi ng assignment operator ( Dancer ) ay may maraming mga form (uri), na idineklara sa kanang bahagi ( Breakdancer , ElectricBoogieDancer). Ang bawat form ay maaaring magkaroon ng sarili nitong natatanging pag-uugali na may paggalang sa pangkalahatang pag-andar na tinukoy sa superclass (ang paraan ng sayaw ). Iyon ay, ang isang paraan na idineklara sa isang superclass ay maaaring ipatupad nang iba sa mga inapo nito. Sa kasong ito, nakikitungo kami sa overriding ng pamamaraan, na kung ano mismo ang lumilikha ng maraming anyo (pag-uugali). Ito ay makikita sa pamamagitan ng pagpapatakbo ng code sa pangunahing pamamaraan: Output ng programa: Ako si Fred. Ako ay 18 taong gulang. Sumasayaw ako tulad ng iba. Ako si Jay. Ako ay 19 taong gulang. Breakdance ko! Ako si Marcia. Ako ay 20 taong gulang. Sumasayaw ako ng electric boogie! Kung hindi namin i-override ang pamamaraan sa mga subclass, hindi kami makakakuha ng ibang pag-uugali. Halimbawa,ElectricBoogieDancer classes, kung gayon ang magiging output ng programa ay ito: Ako si Fred. Ako ay 18 taong gulang. Sumasayaw ako tulad ng iba. Ako si Jay. Ako ay 19 taong gulang. Sumasayaw ako tulad ng iba. Ako si Marcia. Ako ay 20 taong gulang. Sumasayaw ako tulad ng iba. At nangangahulugan ito na walang saysay na gawin ang mga klase ng Breakdancer at ElectricBoogieDancer . Saan partikular na ipinakikita ang prinsipyo ng polymorphism? Saan ginagamit ang isang bagay sa programa nang walang kaalaman sa partikular na uri nito? Sa aming halimbawa, ito ay nangyayari kapag ang dance() method ay tinatawag sa Dancer d object. Sa Java, ang polymorphism ay nangangahulugan na ang programa ay hindi kailangang malaman kung ang bagay ay aBreakdancer o ElectricBoogieDancer . Ang importante ay descendant ito ng Dancer class. At kung babanggitin mo ang mga inapo, dapat mong tandaan na ang mana sa Java ay hindi lamang extends , ngunit nagpapatupad din. Ngayon na ang oras upang banggitin na ang Java ay hindi sumusuporta sa maramihang pamana — bawat uri ay maaaring magkaroon ng isang magulang (superclass) at walang limitasyong bilang ng mga inapo (subclass). Alinsunod dito, ang mga interface ay ginagamit upang magdagdag ng maraming hanay ng mga function sa mga klase. Kung ikukumpara sa mga subclass (mana), ang mga interface ay hindi gaanong pinagsama sa parent class. Ginagamit ang mga ito nang napakalawak. Sa Java, ang isang interface ay isang uri ng sanggunian, kaya ang programa ay maaaring magdeklara ng isang variable ng uri ng interface. Ngayon ay oras na upang magbigay ng isang halimbawa. Lumikha ng interface:
public interface CanSwim {
    void swim();
}
Para sa kalinawan, kukuha kami ng iba't ibang hindi nauugnay na mga klase at gagawin silang ipatupad ang interface:
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.");
    }
}
pangunahing pamamaraan:
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();
        }
    }
}
Ang mga resulta na tumatawag sa isang polymorphic na pamamaraan na tinukoy sa isang interface ay nagpapakita sa amin ng mga pagkakaiba sa pag-uugali ng mga uri na nagpapatupad ng interface na ito. Sa aming kaso, ito ang iba't ibang mga string na ipinapakita ng paraan ng paglangoy . Pagkatapos pag-aralan ang aming halimbawa, maaaring magtanong ang tagapanayam kung bakit pinapatakbo ang code na ito sa pangunahing pamamaraan
for (Swim s : swimmers) {
            s.swim();
}
nagiging sanhi ng pagtawag sa mga overriding na pamamaraan na tinukoy sa aming mga subclass? Paano pinipili ang nais na pagpapatupad ng pamamaraan habang tumatakbo ang programa? Para masagot ang mga tanong na ito, kailangan mong ipaliwanag ang huli (dynamic) binding. Ang ibig sabihin ng binding ay pagtatatag ng pagmamapa sa pagitan ng isang method call at sa partikular na pagpapatupad ng klase nito. Sa esensya, tinutukoy ng code kung alin sa tatlong pamamaraan na tinukoy sa mga klase ang isasagawa. Gumagamit ang Java ng late binding bilang default, ibig sabihin, nangyayari ang pagbubuklod sa runtime at hindi sa oras ng pag-compile gaya ng kaso sa maagang pagbubuklod. Nangangahulugan ito na kapag pinagsama-sama ng compiler ang code na ito
for (Swim s : swimmers) {
            s.swim();
}
hindi nito alam kung aling klase ( Tao , Isda , o Uboat ) ang may code na ipapatupad kapag lumangoytinatawag na pamamaraan. Ito ay natutukoy lamang kapag ang programa ay naisakatuparan, salamat sa dynamic na mekanismo ng pagbubuklod (pagsuri sa uri ng isang bagay sa runtime at pagpili ng tamang pagpapatupad para sa ganitong uri). Kung tatanungin ka kung paano ito ipinapatupad, masasagot mo na kapag naglo-load at nagpapasimula ng mga bagay, ang JVM ay bubuo ng mga talahanayan sa memorya at nagli-link ng mga variable sa kanilang mga halaga at mga bagay sa kanilang mga pamamaraan. Sa paggawa nito, kung ang isang klase ay minana o nagpapatupad ng isang interface, ang unang pagkakasunud-sunod ng negosyo ay upang suriin ang pagkakaroon ng mga overridden na pamamaraan. Kung mayroon man, nakatali sila sa ganitong uri. Kung hindi, ang paghahanap para sa isang paraan ng pagtutugma ay lilipat sa klase na isang hakbang na mas mataas (ang magulang) at iba pa hanggang sa ugat sa isang multilevel na hierarchy. Pagdating sa polymorphism sa OOP at ang pagpapatupad nito sa code, tandaan namin na magandang kasanayan ang gumamit ng mga abstract na klase at mga interface upang magbigay ng abstract na mga kahulugan ng mga batayang klase. Ang kasanayang ito ay sumusunod sa prinsipyo ng abstraction — pagtukoy ng karaniwang pag-uugali at pag-aari at paglalagay ng mga ito sa isang abstract na klase, o pagtukoy lamang ng karaniwang pag-uugali at paglalagay nito sa isang interface. Ang pagdidisenyo at paglikha ng isang object hierarchy batay sa mga interface at class inheritance ay kinakailangan upang maipatupad ang polymorphism. Tungkol sa polymorphism at mga inobasyon sa Java, tandaan namin na simula sa Java 8, kapag lumilikha ng mga abstract na klase at interface ay posible na gamitin ang o pagtukoy lamang ng karaniwang pag-uugali at paglalagay nito sa isang interface. Ang pagdidisenyo at paglikha ng isang object hierarchy batay sa mga interface at class inheritance ay kinakailangan upang maipatupad ang polymorphism. Tungkol sa polymorphism at mga inobasyon sa Java, tandaan namin na simula sa Java 8, kapag lumilikha ng mga abstract na klase at interface ay posible na gamitin ang o pagtukoy lamang ng karaniwang pag-uugali at paglalagay nito sa isang interface. Ang pagdidisenyo at paglikha ng isang object hierarchy batay sa mga interface at class inheritance ay kinakailangan upang maipatupad ang polymorphism. Tungkol sa polymorphism at mga inobasyon sa Java, tandaan namin na simula sa Java 8, kapag lumilikha ng mga abstract na klase at interface ay posible na gamitin angdefault na keyword upang magsulat ng default na pagpapatupad para sa mga abstract na pamamaraan sa mga batayang klase. Halimbawa:
public interface CanSwim {
    default void swim() {
        System.out.println("I just swim");
    }
}
Minsan ang mga tagapanayam ay nagtatanong tungkol sa kung paano dapat ideklara ang mga pamamaraan sa mga batayang klase upang ang prinsipyo ng polymorphism ay hindi nilabag. Ang sagot ay simple: ang mga pamamaraang ito ay hindi dapat static , pribado o final . Ginagawang available lang ng Private ang isang paraan sa loob ng isang klase, kaya hindi mo ito ma-override sa isang subclass. Iniuugnay ng static ang isang pamamaraan sa klase kaysa sa anumang bagay, kaya palaging tatawagin ang pamamaraan ng superclass. At ang pangwakas ay gumagawa ng isang paraan na hindi nababago at nakatago mula sa mga subclass.

Ano ang ibinibigay sa atin ng polymorphism?

Malamang na tatanungin ka rin tungkol sa kung paano tayo nakikinabang sa polymorphism. Maaari mong sagutin ito nang maikli nang hindi nababato sa mabuhok na mga detalye:
  1. Ginagawa nitong posible na palitan ang mga pagpapatupad ng klase. Ang pagsubok ay binuo dito.
  2. Pinapadali nito ang pagpapalawak, na ginagawang mas madaling lumikha ng pundasyon na maaaring itayo sa hinaharap. Ang pagdaragdag ng mga bagong uri batay sa mga umiiral na ay ang pinakakaraniwang paraan upang palawakin ang functionality ng mga OOP program.
  3. Hinahayaan ka nitong pagsamahin ang mga bagay na nagbabahagi ng isang karaniwang uri o gawi sa isang koleksyon o hanay at hawakan ang mga ito nang pantay-pantay (tulad ng sa aming mga halimbawa, kung saan pinilit namin ang lahat na sumayaw() o lumangoy () :)
  4. Kakayahang umangkop sa paggawa ng mga bagong uri: maaari kang mag-opt para sa pagpapatupad ng magulang ng isang pamamaraan o i-override ito sa isang subclass.

Ilang salitang pamamaalam

Ang polymorphism ay isang napakahalaga at malawak na paksa. Ito ang paksa ng halos kalahati ng artikulong ito sa OOP sa Java at bumubuo ng isang magandang bahagi ng pundasyon ng wika. Hindi mo maiiwasang tukuyin ang prinsipyong ito sa isang panayam. Kung hindi mo alam o hindi naiintindihan, malamang na matatapos ang pakikipanayam. Kaya huwag maging isang tamad — suriin ang iyong kaalaman bago ang interbyu at i-refresh ito kung kinakailangan.

Higit pang pagbabasa:

Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito