V Jave je Overriding funkcia, ktorá umožňuje podtriede alebo podradenej triede poskytovať špecifickú implementáciu metódy, ktorá je už poskytovaná jednou z jej nadtried alebo rodičovských tried. Keď má metóda v podtriede rovnaký názov, rovnaké parametre alebo podpis a rovnaký návratový typ (alebo podtyp) ako metóda v jej nadtriede, potom sa o metóde v podtriede hovorí, že prepísať metóda v nadtriede.
Prepísanie metódy je jedným zo spôsobov, ktorými Java dosahuje Polymorfizmus doby behu . Verzia metódy, ktorá sa vykoná, bude určená objektom, ktorý sa použije na jej vyvolanie. Ak sa na vyvolanie metódy použije objekt nadradenej triedy, vykoná sa verzia v nadradenej triede, ale ak sa na vyvolanie metódy použije objekt podtriedy, vykoná sa verzia v podradenej triede. Inými slovami, je to typ objektu, na ktorý sa odkazuje (nie typ referenčnej premennej), ktorá určuje, ktorá verzia prepísanej metódy sa vykoná.
Príklad prepisovania metódy v jazyku Java
Nižšie je uvedená implementácia prepísania metódy Java:
Java
// Java program to demonstrate> // method overriding in java> // Base Class> class> Parent {> >void> show() { System.out.println(>'Parent's show()'>); }> }> // Inherited class> class> Child>extends> Parent {> >// This method overrides show() of Parent> >@Override> void> show()> >{> >System.out.println(>'Child's show()'>);> >}> }> // Driver class> class> Main {> >public> static> void> main(String[] args)> >{> >// If a Parent type reference refers> >// to a Parent object, then Parent's> >// show is called> >Parent obj1 =>new> Parent();> >obj1.show();> >// If a Parent type reference refers> >// to a Child object Child's show()> >// is called. This is called RUN TIME> >// POLYMORPHISM.> >Parent obj2 =>new> Child();> >obj2.show();> >}> }> |
>
>Výkon
previesť celé číslo na reťazec java
Parent's show() Child's show()>
Pravidlá pre prepisovanie metódy Java
1. Modifikátory prepisovania a prístupu
The modifikátor prístupu pretože prepísaná metóda môže umožniť väčší, ale nie menší prístup ako prepísaná metóda. Napríklad metóda chránenej inštancie v nadtriede môže byť zverejnená, ale nie súkromná v podtriede. Ak tak urobíte, vygeneruje sa chyba pri kompilácii.
Java
// A Simple Java program to demonstrate> // Overriding and Access-Modifiers> class> Parent {> >// private methods are not overridden> >private> void> m1()> >{> >System.out.println(>'From parent m1()'>);> >}> >protected> void> m2()> >{> >System.out.println(>'From parent m2()'>);> >}> }> class> Child>extends> Parent {> >// new m1() method> >// unique to Child class> >private> void> m1()> >{> >System.out.println(>'From child m1()'>);> >}> >// overriding method> >// with more accessibility> >@Override> public> void> m2()> >{> >System.out.println(>'From child m2()'>);> >}> }> // Driver class> class> Main {> >public> static> void> main(String[] args)> >{> >Parent obj1 =>new> Parent();> >obj1.m2();> >Parent obj2 =>new> Child();> >obj2.m2();> >}> }> |
>
>Výkon
From parent m2() From child m2()>
2. Konečné metódy nemožno prepísať
Ak nechceme, aby bola metóda prepísaná, vyhlásime ju ako Konečný . Prosím pozri Použitie Final s dedičstvom .
Java
indická rekha
// A Java program to demonstrate that> // final methods cannot be overridden> class> Parent {> >// Can't be overridden> >final> void> show() {}> }> class> Child>extends> Parent {> >// This would produce error> >void> show() {}> }> |
>
>
Výkon
13: error: show() in Child cannot override show() in Parent void show() { } ^ overridden method is final> 3. Statické metódy nemožno prepísať (prepísanie metódy vs skrytie metódy):
Keď definujete statickú metódu s rovnakým podpisom ako statická metóda v základnej triede, je známa ako metóda skrývanie . Nasledujúca tabuľka sumarizuje, čo sa stane, keď definujete metódu s rovnakým podpisom ako metóda v nadtriede.
| Metóda inštancie supertriedy | Statická metóda supertriedy | |
|---|---|---|
| Metóda inštancie podtriedy | Prepíše | Generuje chybu v čase kompilácie |
| Podtrieda Statická metóda | Generuje chybu pri kompilácii | Skryje sa |
Java
// Java program to show that> // if the static method is redefined by> // a derived class, then it is not> // overriding, it is hiding> class> Parent {> >// Static method in base class> >// which will be hidden in subclass> >static> void> m1()> >{> >System.out.println(>'From parent '> >+>'static m1()'>);> >}> >// Non-static method which will> >// be overridden in derived class> >void> m2()> >{> >System.out.println(> >'From parent '> >+>'non - static(instance) m2() '>);> >}> }> class> Child>extends> Parent {> >// This method hides m1() in Parent> >static> void> m1()> >{> >System.out.println(>'From child static m1()'>);> >}> >// This method overrides m2() in Parent> >@Override> public> void> m2()> >{> >System.out.println(> >'From child '> >+>'non - static(instance) m2() '>);> >}> }> // Driver class> class> Main {> >public> static> void> main(String[] args)> >{> >Parent obj1 =>new> Child();> >// As per overriding rules this> >// should call to class Child static> >// overridden method. Since static> >// method can not be overridden, it> >// calls Parent's m1()> >obj1.m1();> >// Here overriding works> >// and Child's m2() is called> >obj1.m2();> >}> }> |
>
>Výkon
From parent static m1() From child non - static(instance) m2()>
4. Súkromné metódy nemožno prepísať
Súkromné metódy nemožno prepísať, pretože sú spojené počas kompilácie. Preto nemôžeme ani prepísať súkromné metódy v podtriede. (Pozri toto pre podrobnosti).
Java
class> SuperClass {> >private> void> privateMethod()> >{> >System.out.println(> >'This is a private method in SuperClass'>);> >}> >public> void> publicMethod()> >{> >System.out.println(> >'This is a public method in SuperClass'>);> >privateMethod();> >}> }> class> SubClass>extends> SuperClass {> >// This is a new method with the same name as the> >// private method in SuperClass> >private> void> privateMethod()> >{> >System.out.println(> >'This is a private method in SubClass'>);> >}> >// This method overrides the public method in SuperClass> >public> void> publicMethod()> >{> >System.out.println(> >'This is a public method in SubClass'>);> >privateMethod();>// calls the private method in> >// SubClass, not SuperClass> >}> }> public> class> Test {> >public> static> void> main(String[] args)> >{> >SuperClass obj1 =>new> SuperClass();> >obj1.publicMethod();>// calls the public method in> >// SuperClass> >SubClass obj2 =>new> SubClass();> >obj2.publicMethod();>// calls the overridden public> >// method in SubClass> >}> }> |
typy testovania softvéru
>
>Výkon
This is a public method in SuperClass This is a private method in SuperClass This is a public method in SubClass This is a private method in SubClass>
5. Prevažujúca metóda musí mať rovnaký návratový typ (alebo podtyp)
Od Java 5.0 vyššie je možné mať rôzne návratové typy pre prepisujúcu metódu v podradenej triede, ale návratový typ potomka by mal byť podtypom rodičovského návratového typu. Tento jav je známy ako kovariantný návratový typ .
Java
class> SuperClass {> >public> Object method()> >{> >System.out.println(> >'This is the method in SuperClass'>);> >return> new> Object();> >}> }> class> SubClass>extends> SuperClass {> >public> String method()> >{> >System.out.println(> >'This is the method in SubClass'>);> >return> 'Hello, World!'>;> >}> }> public> class> Test {> >public> static> void> main(String[] args)> >{> >SuperClass obj1 =>new> SuperClass();> >obj1.method();> >SubClass obj2 =>new> SubClass();> >obj2.method();> >}> }> |
>
>Výkon
This is the method in SuperClass This is the method in SubClass>
6. Vyvolanie prepísanej metódy z podtriedy
Môžeme zavolať metódu rodičovskej triedy v prepisovacej metóde pomocou super kľúčové slovo .
Java
// A Java program to demonstrate that overridden> // method can be called from sub-class> // Base Class> class> Parent {> >void> show() { System.out.println(>'Parent's show()'>); }> }> // Inherited class> class> Child>extends> Parent {> >// This method overrides show() of Parent> >@Override> void> show()> >{> >super>.show();> >System.out.println(>'Child's show()'>);> >}> }> // Driver class> class> Main {> >public> static> void> main(String[] args)> >{> >Parent obj =>new> Child();> >obj.show();> >}> }> |
>
>Výkon
Parent's show() Child's show()>
Overriding a Constructor
Konštruktor nemôžeme prepísať, pretože trieda rodičov a potomkov nikdy nemôže mať konštruktor s rovnakým názvom (názov konštruktora musí byť vždy rovnaký ako názov triedy).
Prepisovanie a spracovanie výnimiek
Nižšie sú uvedené dve pravidlá, ktoré je potrebné vziať do úvahy pri prepisovaní metód súvisiacich so spracovaním výnimiek.
Pravidlo č.1
Ak metóda prepísania nadtriedy nevyvolá výnimku, metóda prepísania podtriedy môže vyvolať iba výnimku nezaškrtnutá výnimka , vyvolanie skontrolovanej výnimky povedie k chybe pri kompilácii.
Java
// Java program to demonstrate overriding when> // superclass method does not declare an exception> class> Parent {> >void> m1() { System.out.println(>'From parent m1()'>); }> >void> m2() { System.out.println(>'From parent m2()'>); }> }> class> Child>extends> Parent {> >@Override> >// no issue while throwing unchecked exception> >void> m1()>throws> ArithmeticException> >{> >System.out.println(>'From child m1()'>);> >}> >@Override> >// compile-time error> >// issue while throwing checked exception> >void> m2()>throws> Exception> >{> >System.out.println(>'From child m2'>);> >}> }> |
>
>
Výkon
error: m2() in Child cannot override m2() in Parent void m2() throws Exception{ System.out.println('From child m2');} ^ overridden method does not throw Exception> Pravidlo č. 2
Ak metóda prepísania nadtriedy vyvolá výnimku, metóda prepísania podtriedy môže vyvolať iba rovnakú výnimku podtriedy. Vhadzovanie rodičovských výnimiek v Hierarchia výnimiek povedie k chybe času kompilácie. Tiež nie je problém, ak metóda prepísania podtriedy nevyvoláva žiadnu výnimku.
Java
// Java program to demonstrate overriding when> // superclass method does declare an exception> class> Parent {> >void> m1()>throws> RuntimeException> >{> >System.out.println(>'From parent m1()'>);> >}> }> class> Child1>extends> Parent {> >@Override> >// no issue while throwing same exception> >void> m1()>throws> RuntimeException> >{> >System.out.println(>'From child1 m1()'>);> >}> }> class> Child2>extends> Parent {> >@Override> >// no issue while throwing subclass exception> >void> m1()>throws> ArithmeticException> >{> >System.out.println(>'From child2 m1()'>);> >}> }> class> Child3>extends> Parent {> >@Override> >// no issue while not throwing any exception> >void> m1()> >{> >System.out.println(>'From child3 m1()'>);> >}> }> class> Child4>extends> Parent {> >@Override> >// compile-time error> >// issue while throwing parent exception> >void> m1()>throws> Exception> >{> >System.out.println(>'From child4 m1()'>);> >}> }> |
obsahuje java metódu
>
>
Výkon
error: m1() in Child4 cannot override m1() in Parent void m1() throws Exception ^ overridden method does not throw Exception>
Nadradená a abstraktná metóda
Abstraktné metódy v rozhraní alebo abstraktnej triede majú byť prepísané v odvodených konkrétnych triedach, inak dôjde k chybe pri kompilácii.
Prepisovacia a synchronizovaná/strictfp metóda
Prítomnosť modifikátora synchronizovaného/strictfp s metódou nemá žiadny vplyv na pravidlá prepisovania, t. j. je možné, že metóda synchronizovaná/strictfp môže prepísať nesynchronizovanú/strictfp a naopak.
Poznámka:
- V C++ potrebujeme virtuálne kľúčové slovo dosiahnuť prvoradé resp Polymorfizmus doby behu . V jazyku Java sú metódy štandardne virtuálne.
- Môžeme mať viacúrovňové prepísanie metódy.
Java
100 km/h na mph
// A Java program to demonstrate> // multi-level overriding> // Base Class> class> Parent {> >void> show() { System.out.println(>'Parent's show()'>); }> }> // Inherited class> class> Child>extends> Parent {> >// This method overrides show() of Parent> >void> show() { System.out.println(>'Child's show()'>); }> }> // Inherited class> class> GrandChild>extends> Child {> >// This method overrides show() of Parent> >void> show()> >{> >System.out.println(>'GrandChild's show()'>);> >}> }> // Driver class> class> Main {> >public> static> void> main(String[] args)> >{> >Parent obj1 =>new> GrandChild();> >obj1.show();> >}> }> |
>
>Výkon
GrandChild's show()>
Preťaženie metódy verzus preťaženie metódy
1. Preťaženie je približne rovnaká metóda s rôznymi podpismi. Prepísanie je približne rovnaká metóda a rovnaký podpis, ale rôzne triedy spojené prostredníctvom dedenia.
2. Preťaženie je príkladom polymorfizmu v čase kompilátora a prepisovanie je príkladom behu polymorfizmus .
Časté otázky o prepisovaní metódy Java
Q1. Čo je prepísanie metódy?
Ako už bolo uvedené, prepísané metódy umožňujú podporu Jave run-time polymorfizmus . Polymorfizmus je nevyhnutný pre objektovo orientované programovanie z jedného dôvodu: umožňuje všeobecnej triede špecifikovať metódy, ktoré budú spoločné pre všetky jej deriváty, pričom umožňuje podtriedam definovať špecifickú implementáciu niektorých alebo všetkých týchto metód. Prepísané metódy sú ďalším spôsobom, ako Java implementuje aspekt polymorfizmu jedného rozhrania, viacerých metód. Dynamická metóda odoslania je jedným z najvýkonnejších mechanizmov, ktoré objektovo orientovaný dizajn prináša so zreteľom na opätovné použitie kódu a robustnosť. Schopnosť existencie kódových knižníc na volanie metód na inštanciách nových tried bez rekompilácie pri zachovaní čistého abstraktného rozhrania je mimoriadne výkonný nástroj. Prepísané metódy nám umožňujú volať metódy ktorejkoľvek z odvodených tried bez toho, aby sme poznali typ objektu odvodenej triedy.
Q2. Kedy použiť prepísanie metódy? (s príkladom)
Prevažujúce a Dedičnosť : Súčasťou kľúča k úspešnému aplikovaniu polymorfizmu je pochopenie, že nadtriedy a podtriedy tvoria hierarchiu, ktorá sa posúva od menšej k väčšej špecializácii. Pri správnom použití nadtrieda poskytuje všetky prvky, ktoré môže priamo použiť podtrieda. Tiež definuje tie metódy, ktoré musí odvodená trieda implementovať sama. To umožňuje podtriede flexibilitu pri definovaní svojich metód, no stále si vyžaduje konzistentné rozhranie. Takže kombináciou dedenia s prepísanými metódami môže nadtrieda definovať všeobecnú formu metód, ktoré budú používať všetky jej podtriedy. Pozrime sa na praktickejší príklad, ktorý používa prepísanie metódy. Zvážte softvér na správu zamestnancov pre organizáciu, nechajte kód mať jednoduchú základnú triedu Zamestnanec a trieda má metódy ako raiseSalary(), transfer(), promotion(), .. atď. Rôzne typy zamestnancov ako Manager, Engineer, ..atď môžu mať svoje implementácie metód prítomné v základnej triede Zamestnanec. V našom kompletnom softvéri nám stačí odovzdať zoznam zamestnancov všade a zavolať vhodné metódy bez toho, aby sme vôbec poznali typ zamestnanca. Napríklad môžeme jednoducho zvýšiť plat všetkým zamestnancom iteráciou cez zoznam zamestnancov. Každý typ zamestnanca môže mať vo svojej triede svoju logiku, nemusíme sa obávať, pretože ak je pre konkrétny typ zamestnanca k dispozícii raiseSalary(), zavolá sa iba táto metóda.
Java
// Java program to demonstrate application>// of overriding in Java>// Base Class>class>Employee {>>public>static>int>base =>10000>;>>int>salary() {>return>base; }>}>// Inherited class>class>Manager>extends>Employee {>>// This method overrides salary() of Parent>>int>salary() {>return>base +>20000>; }>}>// Inherited class>class>Clerk>extends>Employee {>>// This method overrides salary() of Parent>>int>salary() {>return>base +>10000>; }>}>// Driver class>class>Main {>>// This method can be used to print the salary of>>// any type of employee using base class reference>>static>void>printSalary(Employee e)>>{>>System.out.println(e.salary());>>}>>public>static>void>main(String[] args)>>{>>Employee obj1 =>new>Manager();>>// We could also get type of employee using>>// one more overridden method.loke getType()>>System.out.print(>'Manager's salary : '>);>>printSalary(obj1);>>Employee obj2 =>new>Clerk();>>System.out.print(>'Clerk's salary : '>);>>printSalary(obj2);>>}>}>>>VýkonManager's salary : 30000 Clerk's salary : 20000>
Súvisiaci článok
- Dynamic Method Dispatch alebo Runtime Polymorphism v Jave
- Prepísanie metódy equals() triedy Object
- Prepísanie metódy toString() triedy Object
- Preťaženie v jave
- Výstup programu Java | Súprava 18 (hlavná)