V Javě je Overriding funkce, která umožňuje podtřídě nebo podřízené třídě poskytovat specifickou implementaci metody, která je již poskytována jednou z jejích nadtříd nebo nadřazených tříd. Když má metoda v podtřídě stejný název, stejné parametry nebo signaturu a stejný návratový typ (nebo podtyp) jako metoda ve své nadtřídě, pak se o metodě v podtřídě říká, že přepsat metoda v nadtřídě.
Přepsání metody je jedním ze způsobů, jak toho Java dosahuje Polymorfismus doby běhu . Verze metody, která se spustí, bude určena objektem, který se použije k jejímu vyvolání. Pokud se k vyvolání metody použije objekt nadřazené třídy, provede se verze v nadřazené třídě, ale pokud se k vyvolání metody použije objekt podtřídy, provede se verze v podřízené třídě. Jinými slovy, je to typ objektu, na který se odkazuje (nikoli typ referenční proměnné), která určuje, která verze přepsané metody bude provedena.
Příklad přepisování metody v Javě
Níže je uvedena implementace přepisování metody Java:
Jáva
rychlé třídění
// 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ýstup
Parent's show() Child's show()>
Pravidla pro přepisování metod Java
1. Přepisovací a přístupové modifikátory
The modifikátor přístupu protože přepisující metoda může umožnit více, ale ne méně, přístup než přepsaná metoda. Například metoda chráněné instance v nadtřídě může být v podtřídě zveřejněna, ale ne soukromá. Pokud tak učiníte, vygeneruje se chyba při kompilaci.
Jáva
// 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ýstup
From parent m2() From child m2()>
2. Konečné metody nelze přepsat
Pokud nechceme, aby byla metoda přepsána, deklarujeme ji jako finále . Prosím podívej se Použití Final s dědičností .
Jáva
// 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ýstup
13: error: show() in Child cannot override show() in Parent void show() { } ^ overridden method is final> 3. Statické metody nelze přepsat (přepsání metody vs skrytí metody):
Když definujete statickou metodu se stejnou signaturou jako statická metoda v základní třídě, je známá jako metoda skrývání . Následující tabulka shrnuje, co se stane, když definujete metodu se stejnou signaturou jako metoda v nadtřídě.
| Metoda instance nadtřídy | Statická metoda nadtřídy | |
|---|---|---|
| Metoda instance podtřídy | Přepíše | Generuje chybu při kompilaci |
| Podtřída Statická metoda | Generuje chybu při kompilaci | Skryje se |
Jáva
// 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ýstup
From parent static m1() From child non - static(instance) m2()>
4. Soukromé metody nelze přepsat
Soukromé metody nelze přepsat, protože jsou spojeny během kompilace. Proto nemůžeme ani přepsat soukromé metody v podtřídě. (Viz tento pro detaily).
Jáva
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> >}> }> |
seznam java do pole
>
>Výstup
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. Přepisovací metoda musí mít stejný návratový typ (nebo podtyp)
Od Java 5.0 výše je možné mít různé návratové typy pro přepisující metodu v podřízené třídě, ale návratový typ potomka by měl být podtypem návratového typu rodiče. Tento jev je známý jako kovariantní návratový typ .
Jáva
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ýstup
This is the method in SuperClass This is the method in SubClass>
6. Vyvolání přepsané metody z podtřídy
Můžeme volat metodu rodičovské třídy v přepisovací metodě pomocí super klíčové slovo .
Jáva
// 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ýstup
Parent's show() Child's show()>
Přepisování a konstruktor
Nemůžeme přepsat konstruktor, protože nadřazená a podřízená třída nikdy nemohou mít konstruktor se stejným názvem (název konstruktoru musí být vždy stejný jako název třídy).
Přepisování a zpracování výjimek
Níže jsou uvedena dvě pravidla, která je třeba vzít v úvahu při přepisování metod souvisejících se zpracováním výjimek.
Pravidlo č. 1
Pokud metoda přepsání nadtřídou nevyvolá výjimku, metoda přepsání podtřídy může vyvolat pouze výjimku nezaškrtnutá výjimka , vyvolání zaškrtnuté výjimky povede k chybě při kompilaci.
Jáva
// 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ýstup
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
Pokud metoda přepsání nadtřídou vyvolá výjimku, metoda přepsání podtřídy může vyvolat pouze stejnou výjimku podtřídy. Vyhození nadřazených výjimek v Hierarchie výjimek povede k chybě času kompilace. Také neexistuje žádný problém, pokud metoda přepsání podtřídou nevyvolá žádnou výjimku.
Jáva
// 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()'>);> >}> }> |
>
>
Výstup
error: m1() in Child4 cannot override m1() in Parent void m1() throws Exception ^ overridden method does not throw Exception>
Nadřazená a abstraktní metoda
Abstraktní metody v rozhraní nebo abstraktní třídě mají být v odvozených konkrétních třídách přepsány, jinak dojde k chybě při kompilaci.
Přepisovací a synchronizovaná/strictfp metoda
Přítomnost modifikátoru synchronized/strictfp u metody nemá žádný vliv na pravidla přepisování, tj. je možné, že metoda synchronizovaná/strictfp může přepsat nesynchronizovanou/strictfp a naopak.
Poznámka:
- V C++ potřebujeme virtuální klíčové slovo k dosažení prvořadého popř Polymorfismus doby běhu . V Javě jsou metody ve výchozím nastavení virtuální.
- Můžeme mít víceúrovňové přepisování metod.
Jáva
// 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();> >}> }> |
>
>
python převádí bajty na řetězecVýstup
GrandChild's show()>
Přepisování metod vs přetěžování metod
1. Přetížení je přibližně stejná metoda s různými podpisy. Přepsání je přibližně stejná metoda a stejný podpis, ale různé třídy spojené prostřednictvím dědičnosti.
2. Přetížení je příkladem polymorfismu v době kompilátoru a přepisování je příkladem běhu polymorfismus .
Nejčastější dotazy o přepisování metody Java
Q1. Co je to přepisování metody?
Jak bylo uvedeno dříve, přepsané metody umožňují podporu Javě run-time polymorfismus . Polymorfismus je nezbytný pro objektově orientované programování z jednoho důvodu: umožňuje obecné třídě specifikovat metody, které budou společné všem jejím derivátům, a zároveň umožňuje podtřídám definovat konkrétní implementaci některých nebo všech těchto metod. Přepsané metody jsou dalším způsobem, jak Java implementuje aspekt polymorfismu jednoho rozhraní, více metod. Dynamická metoda odeslání je jedním z nejvýkonnějších mechanismů, které objektově orientovaný design přináší do opětovného použití kódu a robustnosti. Schopnost existovat knihovny kódu pro volání metod na instancích nových tříd bez rekompilace při zachování čistého abstraktního rozhraní je hluboce mocný nástroj. Přepsané metody nám umožňují volat metody kterékoli z odvozených tříd, aniž bychom znali typ objektu odvozené třídy.
Q2. Kdy použít metodu Overriding? (s příkladem)
Převažující a Dědictví : Součástí klíče k úspěšné aplikaci polymorfismu je pochopení, že supertřídy a podtřídy tvoří hierarchii, která se pohybuje od menší k větší specializaci. Při správném použití poskytuje nadtřída všechny prvky, které může podtřída přímo používat. Definuje také ty metody, které musí odvozená třída implementovat sama. To umožňuje podtřídě flexibilitu při definování svých metod, ale stále vynucuje konzistentní rozhraní. Kombinací dědičnosti s přepsanými metodami tedy může nadtřída definovat obecnou formu metod, kterou budou používat všechny její podtřídy. Podívejme se na praktičtější příklad, který používá přepisování metody. Zvažte software pro správu zaměstnanců pro organizaci, nechejte kód mít jednoduchou základní třídu Employee a třída má metody jako raiseSalary(), transfer(), promotion(), .. atd. Různé typy zaměstnanců jako Manager, Engineer, ..atd mohou mít své implementace metod přítomné v základní třídě Employee. V našem kompletním softwaru stačí všude předat seznam zaměstnanců a zavolat vhodné metody, aniž bychom vůbec znali typ zaměstnance. Můžeme například snadno zvýšit plat všem zaměstnancům iterací seznamu zaměstnanců. Každý typ zaměstnance může mít ve své třídě svou logiku, nemusíme si dělat starosti, protože pokud je pro konkrétní typ zaměstnance přítomna metoda raiseSalary(), bude volána pouze tato metoda.
Jáva
// 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ýstupManager's salary : 30000 Clerk's salary : 20000>
Související článek
- Dynamic Method Dispatch nebo Runtime Polymorphism v Javě
- Přepsání metody equals() třídy Object
- Přepsání metody toString() třídy Object
- Přetížení v Javě
- Výstup programu Java | Sada 18 (hlavní)