W Javie Overriding to funkcja, która pozwala podklasie lub klasie podrzędnej zapewnić specyficzną implementację metody, która jest już zapewniona przez jedną z jej nadklas lub klas nadrzędnych. Kiedy metoda w podklasie ma tę samą nazwę, te same parametry lub sygnaturę i ten sam typ (lub podtyp) zwracany co metoda w jej nadklasie, wówczas mówi się, że metoda w podklasie nadpisanie metoda w nadklasie.
Nadpisywanie metod jest jednym ze sposobów osiągnięcia Java Polimorfizm czasu wykonania . Wersja metody, która zostanie wykonana, zostanie określona przez obiekt użyty do jej wywołania. Jeśli do wywołania metody zostanie użyty obiekt klasy nadrzędnej, to zostanie wykonana wersja z klasy nadrzędnej, natomiast jeśli do wywołania metody zostanie użyty obiekt klasy nadrzędnej, to zostanie wykonana wersja z klasy potomnej. Innymi słowy, jest to typ obiektu, do którego się odnosimy (nie typ zmiennej referencyjnej), która określa, która wersja zastąpionej metody zostanie wykonana.
Przykład przesłaniania metod w Javie
Poniżej znajduje się implementacja przesłaniania metody Java:
Jawa
// 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();> >}> }> |
>
>Wyjście
Parent's show() Child's show()>
Reguły zastępowania metod Java
1. Modyfikatory przesłaniania i dostępu
The modyfikator dostępu ponieważ metoda przesłaniająca może pozwolić na większy, ale nie mniejszy dostęp niż metoda zastąpiona. Na przykład chroniona metoda instancji w nadklasie może być publiczna, ale nie prywatna, w podklasie. Spowoduje to wygenerowanie błędu w czasie kompilacji.
Jawa
// 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();> >}> }> |
>
>
ciąg Java na liczbę całkowitąWyjście
From parent m2() From child m2()>
2. Ostatecznych metod nie można zastąpić
Jeśli nie chcemy, aby metoda została nadpisana, deklarujemy ją jako finał . Proszę zobaczyć Używanie wersji finalnej z dziedziczeniem .
Jawa
// 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() {}> }> |
>
>
Wyjście
13: error: show() in Child cannot override show() in Parent void show() { } ^ overridden method is final> 3. Nie można zastąpić metod statycznych (przesłanianie metody vs ukrywanie metody):
Kiedy definiujesz metodę statyczną z tym samym podpisem, co metoda statyczna w klasie bazowej, nazywa się to metoda ukrywania . Poniższa tabela podsumowuje, co się stanie, gdy zdefiniujesz metodę z tym samym podpisem, co metoda w nadklasie.
| Metoda instancji nadklasy | Metoda statyczna superklasy | |
|---|---|---|
| Metoda instancji podklasy | Zastępuje | Generuje błąd w czasie kompilacji |
| Metoda statyczna podklasy | Generuje błąd w czasie kompilacji | Ukrywa się |
Jawa
zmień nazwę katalogu w systemie Linux
// 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();> >}> }> |
>
>Wyjście
From parent static m1() From child non - static(instance) m2()>
4. Metod prywatnych nie można zastąpić
Metody prywatne nie można zastąpić, ponieważ są one łączone podczas kompilacji. Dlatego nie możemy nawet zastąpić metod prywatnych w podklasie. (Zobacz Ten dla szczegółów).
Jawa
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> >}> }> |
algorytm knn
>
>Wyjście
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. Metoda przesłaniająca musi mieć ten sam typ zwracany (lub podtyp)
Począwszy od wersji Java 5.0 możliwe jest posiadanie różnych typów zwracanych metod przesłaniających w klasie potomnej, ale typ zwracany przez dziecko powinien być podtypem typu zwracanego przez rodzica. Zjawisko to znane jest jako kowariantny typ zwrotu .
Jawa
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();> >}> }> |
>
>Wyjście
This is the method in SuperClass This is the method in SubClass>
6. Wywołanie przesłoniętej metody z podklasy
Metodę klasy nadrzędnej możemy wywołać w metodzie przesłaniającej za pomocą metody super słowo kluczowe .
Jawa
// 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();> >}> }> |
>
>Wyjście
Parent's show() Child's show()>
Przesłanianie i konstruktor
Nie możemy przesłonić konstruktora, ponieważ klasa nadrzędna i podrzędna nigdy nie mogą mieć konstruktora o tej samej nazwie (nazwa konstruktora musi zawsze być taka sama jak nazwa klasy).
Przesłanianie i obsługa wyjątków
Poniżej znajdują się dwie zasady, o których należy pamiętać podczas zastępowania metod związanych z obsługą wyjątków.
Zasada nr 1
Jeśli metoda nadpisania nadklasy nie zgłasza wyjątku, metoda nadpisywania podklasy może jedynie zgłosić wyjątek niesprawdzony wyjątek , zgłoszenie sprawdzonego wyjątku spowoduje błąd w czasie kompilacji.
Jawa
// 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'>);> >}> }> |
>
>
Wyjście
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> Zasada nr 2
Jeśli metoda nadpisania nadklasy rzeczywiście zgłasza wyjątek, metoda nadpisywania podklasy może zgłosić tylko ten sam wyjątek podklasy. Zgłaszanie wyjątków nadrzędnych w Hierarchia wyjątków doprowadzi do błędu czasu kompilacji. Ponadto nie ma problemu, jeśli nadpisana metoda podklasy nie zgłasza żadnego wyjątku.
Jawa
// 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()'>);> >}> }> |
>
>
javascript najbliżej
Wyjście
error: m1() in Child4 cannot override m1() in Parent void m1() throws Exception ^ overridden method does not throw Exception>
Metoda nadrzędna i abstrakcyjna
Metody abstrakcyjne w interfejsie lub klasie abstrakcyjnej mają być zastępowane w pochodnych klasach konkretnych, w przeciwnym razie zostanie zgłoszony błąd w czasie kompilacji.
Metoda zastępowania i synchronizacji/strictfp
Obecność modyfikatora synchronized/strictfp w metodzie nie ma wpływu na zasady override, tzn. możliwe jest, że metoda synchronized/strictfp może zastąpić metodę niezsynchronizowaną/strictfp i odwrotnie.
Notatka:
- W C++ potrzebujemy wirtualne słowo kluczowe aby osiągnąć nadrzędne lub Polimorfizm czasu wykonania . W Javie metody są domyślnie wirtualne.
- Możemy mieć wielopoziomowe nadpisywanie metod.
Jawa
// 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();> >}> }> |
>
>Wyjście
GrandChild's show()>
Przesłanianie metody a przeciążanie metody
1. Przeciążenie dotyczy tej samej metody z różnymi podpisami. Zastępowanie dotyczy tej samej metody i tego samego podpisu, ale różnych klas połączonych poprzez dziedziczenie.
css pogrubione
2. Przeciążanie jest przykładem polimorfizmu w czasie kompilatora, a przesłonięcie jest przykładem czasu wykonywania wielopostaciowość .
Często zadawane pytania dotyczące zastępowania metod Java
Pytanie 1. Co to jest zastępowanie metody?
Jak wspomniano wcześniej, przesłonięte metody umożliwiają obsługę języka Java Polimorfizm czasu wykonywania . Polimorfizm jest niezbędny w programowaniu obiektowym z jednego powodu: pozwala klasie ogólnej określić metody, które będą wspólne dla wszystkich jej pochodnych, jednocześnie pozwalając podklasom na zdefiniowanie konkretnej implementacji niektórych lub wszystkich tych metod. Metody zastępowane to kolejny sposób, w jaki Java implementuje aspekt polimorfizmu z jednym interfejsem i wieloma metodami. Wysyłka metodą dynamiczną to jeden z najpotężniejszych mechanizmów, jakie projektowanie obiektowe zapewnia ponowne wykorzystanie kodu i jego niezawodność. Możliwość istnienia bibliotek kodu umożliwiających wywoływanie metod w instancjach nowych klas bez konieczności ponownej kompilacji przy jednoczesnym zachowaniu czystego, abstrakcyjnego interfejsu jest niezwykle potężnym narzędziem. Metody nadpisane pozwalają nam wywoływać metody dowolnych klas pochodnych, nawet nie znając typu obiektu klasy pochodnej.
Pytanie 2. Kiedy zastosować zastępowanie metody? (z przykładem)
Zastępowanie i Dziedzictwo : Częścią klucza do skutecznego zastosowania polimorfizmu jest zrozumienie, że nadklasy i podklasy tworzą hierarchię, która przechodzi od mniejszej do większej specjalizacji. Używana poprawnie, nadklasa zapewnia wszystkie elementy, których podklasa może używać bezpośrednio. Definiuje także metody, które klasa pochodna musi samodzielnie zaimplementować. Pozwala to podklasie na elastyczność w definiowaniu metod, a jednocześnie wymusza spójny interfejs. Zatem łącząc dziedziczenie z metodami nadpisanymi, nadklasa może zdefiniować ogólną postać metod, które będą używane przez wszystkie jej podklasy. Przyjrzyjmy się bardziej praktycznemu przykładowi, w którym zastosowano przesłanianie metod. Rozważmy oprogramowanie do zarządzania pracownikami dla organizacji, niech kod zawiera prostą klasę bazową Pracownik, a klasa zawiera metody takie jak raiseSalary(), transfer(), promuj(), .. itd. Różne typy pracowników, takie jak menedżer, inżynier, ..etc mogą posiadać implementacje metod występujących w klasie bazowej Pracownik. W naszym kompletnym oprogramowaniu wystarczy, że przekażemy wszędzie listę pracowników i wywołamy odpowiednie metody, nawet nie znając typu pracownika. Przykładowo, w prosty sposób możemy podnieść pensje wszystkich pracowników, przeglądając listę pracowników. Każdy typ pracownika może mieć swoją logikę w swojej klasie, nie musimy się martwić, ponieważ jeśli raiseSalary() jest obecna dla określonego typu pracownika, zostanie wywołana tylko ta metoda.
Jawa
// 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);>>}>}>>>WyjścieManager's salary : 30000 Clerk's salary : 20000>
Powiązany artykuł
- Dynamiczna wysyłka metod lub polimorfizm środowiska wykonawczego w Javie
- Przesłonięcie metody równości() klasy Object
- Zastępowanie metody toString() klasy Object
- Przeciążanie w Javie
- Dane wyjściowe programu Java | Zestaw 18 (Zastąpienie)