Programmēšana

Polimorfisms un mantojums Java

Saskaņā ar leģendu Venkat Subramaniam polimorfisms ir vissvarīgākais jēdziens objektorientētajā programmēšanā. Polimorfisms- vai objekta spēja veikt specializētas darbības, pamatojoties uz tā tipu, padara Java kodu elastīgu. Dizaina modeļos, piemēram, Command, Observer, Decorator, Strategy un daudzos citos, ko izveidojusi Gang Of Four, visi tiek izmantoti kāda veida polimorfisms. Šīs koncepcijas apguve ievērojami uzlabo jūsu spēju domāt, izmantojot risinājumus programmēšanas izaicinājumiem.

Iegūstiet kodu

Jūs varat iegūt šī izaicinājuma avota kodu un veikt savus testus šeit: //github.com/rafadelnero/javaworld-challengers

Saskarnes un iedzimtība polimorfismā

Ar šo Java Challenger mēs koncentrējamies uz polimorfisma un mantojuma attiecībām. Galvenais, kas jāpatur prātā, ir tas, ka polimorfisms prasa mantojums vai saskarnes ieviešana. To var redzēt zemāk esošajā piemērā, kurā ir hercogs un Jugijs:

 publiskā abstraktā klase JavaMascot {public abstract void executeAction (); } public class Duke paplašina JavaMascot {@Override public void executeAction () {System.out.println ("Punch!"); }} public class Juggy paplašina JavaMascot {@Override public void executeAction () {System.out.println ("Fly!"); }} public class JavaMascotTest {public static void main (String ... args) {JavaMascot dukeMascot = new Duke (); JavaMascot juggyMascot = jauns Juggy (); dukeMascot.executeAction (); juggyMascot.executeAction (); }} 

Šī koda izvade būs:

 Perforators! Lido! 

To īpašās ieviešanas dēļ abi Hercogs un JuggyTiks izpildītas.

Vai metode pārslogo polimorfismu?

Daudzi programmētāji ir neizpratnē par polimorfisma saistību ar metodes ignorēšanu un metodes pārslodzi. Faktiski patiesais polimorfisms ir tikai svarīgākā metode. Pārslodzes gadījumā tiek izmantots tās pašas metodes nosaukums, taču parametri ir atšķirīgi. Polimorfisms ir plašs termins, tāpēc par šo tēmu vienmēr notiks diskusijas.

Kāds ir polimorfisma mērķis?

Polimorfisma izmantošanas lielā priekšrocība un mērķis ir atdalīt klienta klasi no ieviešanas koda. Tā vietā, lai klienta klase būtu kodēta, tā saņem ieviešanu, lai veiktu nepieciešamo darbību. Tādā veidā klientu klase zina tikai pietiekami daudz, lai izpildītu savas darbības, kas ir brīvas savienošanas piemērs.

Lai labāk izprastu polimorfisma mērķi, ieskatieties SweetCreator:

 publiskā abstraktā klase SweetProducer {public abstract void producSweet (); } public class CakeProducer paplašina SweetProducer {@Override public void producSweet () {System.out.println ("Kūka ražota"); }} sabiedrības klases ChocolateProducer paplašina SweetProducer {@Override public void producSweet () {System.out.println ("Šokolāde ražota"); }} public class CookieProducer paplašina SweetProducer {@Override public void producSweet () {System.out.println ("Sīkdatne ražota"); }} publiskā klase SweetCreator {private List sweetProducer; public SweetCreator (List sweetProducer) {this.sweetProducer = sweetProducer; } public void createSweets () {sweetProducer.forEach (sweet -> sweet.produceSweet ()); }} public class SweetCreatorTest {public static void main (String ... args) {SweetCreator sweetCreator = new SweetCreator (Arrays.asList (new CakeProducer (), new ChocolateProducer (), new CookieProducer ())); sweetCreator.createSweets (); }} 

Šajā piemērā jūs varat redzēt, ka SweetCreator klase zina tikai  SweetProducer klasē. Tā nezina katra īstenošanu Salds. Šī nošķiršana dod mums iespēju atjaunot un atkārtoti izmantot mūsu klases, un tas padara kodu daudz vieglāk uzturamu. Veidojot kodu, vienmēr meklējiet veidus, kā padarīt to pēc iespējas elastīgāku un uzturamāku. polimorfisms ir ļoti spēcīgs paņēmiens, ko izmantot šiem mērķiem.

Padoms: @ Pārvarēt anotācija uzliek programmētājam pienākumu izmantot to pašu metodes parakstu, kas ir jāpārņem. Ja metode netiek ignorēta, radīsies kompilācijas kļūda.

Kovariāna atdeves veidi metodes ignorēšanā

Ir iespējams mainīt ignorētās metodes atgriešanas veidu, ja tas ir kovariants. A kovariāna tips būtībā ir atgriešanās veida apakšklase. Apsveriet piemēru:

 publiskā abstraktā klase JavaMascot {abstraktā JavaMascot getMascot (); } public class Duke paplašina JavaMascot {@Orride Duke getMascot () {return new Duke (); }} 

Tā kā Hercogs ir JavaMascot, mēs varam mainīt atgriešanās veidu, ignorējot.

Polimorfisms ar Java pamatklasēm

Java pamatklasēs mēs visu laiku izmantojam polimorfismu. Viens ļoti vienkāršs piemērs ir tas, kad mēs veicam ArrayList klase, kas deklarēSaraksts interfeiss kā tips:

 Sarakstu saraksts = new ArrayList (); 

Lai ietu tālāk, apsveriet šo koda paraugu, izmantojot Java kolekciju API bez polimorfisms:

 public class ListActionWithoutPolymorphism {// Piemērs bez polimorfisma void executeVectorActions (Vector vector) {/ * Koda atkārtošana šeit * /} void executeArrayListActions (ArrayList arrayList) {/ * Koda atkārtošana šeit * /} void executeLinkedListActions * LinkedList {LinkedList here * /} void executeCopyOnWriteArrayListActions (CopyOnWriteArrayList copyOnWriteArrayList) {/ * Koda atkārtošana šeit * /}} public class ListActionInvokerWithoutPolymorphism {listAction.executeVectorActions (new Vector ()); listAction.executeArrayListActions (jauns ArrayList ()); listAction.executeLinkedListActions (jauns LinkedList ()); listAction.executeCopyOnWriteArrayListActions (jauns CopyOnWriteArrayList ()); } 

Neglīts kods, vai ne? Iedomājieties, kā mēģināt to uzturēt! Tagad aplūkojiet to pašu piemēru ar polimorfisms:

 public static void main (String ... polymorphism) {ListAction listAction = new ListAction (); listAction.executeListActions (); } public class ListAction {void executeListActions (List list) {// Izpildīt darbības ar dažādiem sarakstiem}} public class ListActionInvoker {public static void main (String ... masterPolymorphism) {ListAction listAction = new ListAction (); listAction.executeListActions (jauns Vector ()); listAction.executeListActions (jauns ArrayList ()); listAction.executeListActions (jauns LinkedList ()); listAction.executeListActions (jauns CopyOnWriteArrayList ()); }} 

Polimorfisma priekšrocība ir elastība un paplašināmība. Tā vietā, lai izveidotu vairākas dažādas metodes, mēs varam deklarēt tikai vienu metodi, kas saņem vispārīgo Saraksts tips.

Specifisku metožu izsaukšana polimorfās metodes izsaukumā

Polimorfā izsaukumā ir iespējams atsaukties uz noteiktām metodēm, taču tas tiek darīts par elastības cenu. Lūk, piemērs:

 publiskā abstraktā klase MetalGearCharacter {abstract void useWeapon (String ierocis); } publiskā klase BigBoss paplašina MetalGearCharacter {@Override void useWeapon (String ierocis) {System.out.println ("Big Boss izmanto ieroci +); } void giveOrderToTheArmy (String orderMessage) {System.out.println (orderMessage); }} publiskā klase SolidSnake paplašina MetalGearCharacter {void useWeapon (String ierocis) {System.out.println ("Solid Snake izmanto" ieroci +); }} public class UseSpecificMethod {public static void executeActionWith (MetalGearCharacter metalGearCharacter) {metalGearCharacter.useWeapon ("SOCOM"); // Zemāk esošā rinda nedarbosies // metalGearCharacter.giveOrderToTheArmy ("Uzbrukums!"); if (metalGearCharacter instance of BigBoss) {((BigBoss) metalGearCharacter) .giveOrderToTheArmy ("Uzbrukums!"); }} public static void main (String ... specificPolymorphismInvocation) {executeActionWith (new SolidSnake ()); executeActionWith (jauns BigBoss ()); }} 

Šeit izmantotā tehnika ir liešanavai apzināti mainot objekta tipu izpildlaikā.

Ņemiet vērā, ka ir iespējams izmantot noteiktu metodi tikai nododot vispārīgo tipu konkrētajam tipam. Laba līdzība būtu skaidri teikt sastādītājam: “Hei, es zinu, ko es šeit daru, tāpēc es nodošu objektu konkrētam tipam un izmantoju noteiktu metodi.”

Atsaucoties uz iepriekš minēto piemēru, ir svarīgs iemesls, kāpēc kompilators atsakās pieņemt noteiktu metodes izsaukumu: klasi, kas tiek nodota, var SolidSnake. Šajā gadījumā kompilatoram nav iespējas nodrošināt ikvienu MetalGearRaksturs ir giveOrderToTheArmy deklarētā metode.

The instanceof rezervēts atslēgvārds

Pievērsiet uzmanību rezervētajam vārdam instanceof. Pirms izmantot konkrēto metodi, mēs esam vaicājuši, vai MetalGearRaksturs ir “instanceofLielais boss. Ja tas nebija a Lielais boss mēs saņemtu šādu ziņojumu par izņēmumu:

 Izņēmums pavedienā "main" java.lang.ClassCastException: com.javaworld.javachallengers.polymorphism.specificinvocation.SolidSnake nevar nodot vietnei com.javaworld.javachallengers.polymorphism.specificinvocation.BigBoss 

The super rezervēts atslēgvārds

Ko darīt, ja mēs gribētu atsaukties uz atribūtu vai metodi no Java superklases? Šajā gadījumā mēs varētu izmantot super rezervēts vārds. Piemēram:

 publiskā klase JavaMascot {void executeAction () {System.out.println ("Java talismans gatavojas izpildīt darbību!"); }} public class Duke paplašina JavaMascot {@Override void executeAction () {super.executeAction (); System.out.println ("Hercogs gatavojas iesist!"); } public static void main (String ... superReservedWord) {new Duke (). executeAction (); }} 

Izmantojot rezervēto vārdu super iekšā Hercogs’S izpildītAction metode izsauc superklases metodi. Pēc tam mēs izpildām konkrēto darbību no Hercogs. Tāpēc zemāk redzamajā izvadē mēs varam redzēt abus ziņojumus:

 Java talismans gatavojas veikt darbību! Hercogs gatavojas iesist! 

Pieņem polimorfisma izaicinājumu!

Izmēģināsim to, ko esat iemācījušies par polimorfismu un mantojumu. Šajā izaicinājumā jums tiek dota nedaudz metožu no Meta Groeninga Simpsoniem, un jūsu uzdevums ir secināt, kāds būs katras klases iznākums. Lai sāktu, rūpīgi analizējiet šo kodu:

 publiskā klase Polimorfisma izaicinājums {statiskā abstraktā klase Simpsons {void talk () {System.out.println ("Simpsons!"); } aizsargāta tukša palaidnība (virknes palaidnība) {System.out.println (palaidnība); }} statiskā klase Barts pagarina Simpsonu {Stīgu palaidnība; Bārts (stīgu palaidnība) {this. palaidnība = palaidnība; } protected void talk () {System.out.println ("Ēd manus šortus!"); } aizsargāta tukša palaidnība () {super.prank (palaidnība); System.out.println ("Nokaut Homeru uz leju"); }} statiskā klase Liza pagarina Simpsonu {void talk (String toMe) {System.out.println ("I love Sax!"); }} public static void main (String ... doYourBest) {new Lisa (). talk ("Sax :)"); Simpsons simpsons = jauns Barts ("D'oh"); simpson.talk (); Lisa lisa = jauna Lisa (); lisa.talk (); ((Bart) simpson). Palaidnība (); }} 

Ko tu domā? Kāda būs galīgā produkcija? Lai to noskaidrotu, neizmantojiet IDE! Punkts ir uzlabot savas koda analīzes prasmes, tāpēc mēģiniet pats noteikt rezultātu.

Izvēlieties atbildi, un tālāk varēsiet atrast pareizo atbildi.

 A) Es mīlu Saksu! D'oh Simpson! D'oh B) Sax :) Ēd manus šortus! Es mīlu Saksu! D'oh Knock Homer down C) Sax :) D'oh Simpson! Nokauj Homeru uz leju D) Es mīlu Saksu! Ēd manus šortus! Simpson! D'oh nokauj Homēru 

Kas tikko notika? Izpratne par polimorfismu

Šādas metodes izsaukšanai:

 jaunā Liza (). saruna ("Sax :)"); 

izeja būs “Es mīlu Saksu!”Tas ir tāpēc, ka mēs ejam garām Stīga uz metodi un Liza ir metode.

Nākamajam aicinājumam:

 Simpsons simpsons = jauns Barts ("D'oh");

simpson.talk ();

Rezultāts būs "Ēd manus šortus!"Tas ir tāpēc, ka mēs veicam Simpsons ierakstiet ar Bārts.

Tagad pārbaudiet šo, kas ir nedaudz sarežģītāk:

 Lisa lisa = jauna Lisa (); lisa.talk (); 

Šeit mēs izmantojam metodes pārslodzi ar mantojumu. Mēs neko nepievienojam sarunu metodei, tāpēc Simpsons runāt metode tiek izmantota. Šajā gadījumā izeja būs:

 - Simpson! 

Šeit ir vēl viens:

 ((Bart) simpson). Palaidnība (); 

Šajā gadījumā palaidnība Stīga tika nodota, kad mēs instantiated Bārts klase ar jaunais Barts ("D'oh");. Šajā gadījumā vispirms super.prank metode, kam sekos specifiskā palaidnība metode no Bārts. Rezultāts būs:

 "D'oh" "Notrieciet Homēru" 

Video izaicinājums! Java polimorfisma un mantojuma atkļūdošana

Atkļūdošana ir viens no vienkāršākajiem veidiem, kā pilnībā absorbēt programmēšanas koncepcijas, vienlaikus uzlabojot arī kodu. Šajā video jūs varat sekot līdzi, kamēr es atkļūdoju un izskaidroju Java polimorfisma izaicinājumu:

Bieži pieļautās kļūdas ar polimorfismu

Tā ir izplatīta kļūda, domājot, ka ir iespējams atsaukties uz noteiktu metodi, neizmantojot liešanu.

Vēl viena kļūda ir neziņa, kāda metode tiks izmantota, polimorfiski klasificējot klasi. Atcerieties, ka izmantotā metode ir izveidotās instances metode.

Atcerieties arī, ka metodes ignorēšana nav metodes pārslodze.

Ja parametri atšķiras, metodi nav iespējams ignorēt. Tā ir iespējams lai mainītu ignorētās metodes atgriešanas tipu, ja atgriešanas veids ir superklases metodes apakšklase.

Kas jāatceras par polimorfismu

  • Izveidotais gadījums noteiks, kāda metode tiks izmantota, izmantojot polimorfismu.
  • The @ Pārvarēt anotācija uzliek programmētājam pienākumu izmantot ignorētu metodi; ja nē, būs sastādītāja kļūda.
  • Polimorfismu var izmantot ar parastām klasēm, abstraktām klasēm un saskarnēm.
  • Lielākā daļa dizaina modeļu ir atkarīgi no kāda polimorfisma veida.
  • Vienīgais veids, kā izmantot polimorfā apakšklasē noteiktu metodi, ir liešana.
  • Izmantojot polimorfismu, ir iespējams izveidot spēcīgu koda struktūru.
  • Palaidiet savus testus. To darot, jūs varēsiet apgūt šo spēcīgo koncepciju!

Atbildes atslēga

Atbilde šim Java izaicinātājam ir D. Rezultāts būtu:

 Es mīlu Saksu! Ēd manus šortus! Simpson! D'oh nokauj Homēru 

Šo stāstu "Polimorfisms un mantošana Java" sākotnēji publicēja JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found