Kiedy podklasa zapewnia specyficzną implementację metody, która jest już zdefiniowana w jej klasie nadrzędnej, nazywa się to przesłonięciem metody. Przesłonięta metoda w podklasie musi mieć takie same parametry nazwy i typ zwracany jak metoda w klasie nadrzędnej.
Zasady zastępowania metod
- Parametry nazwy i typ zwracany muszą odpowiadać metodzie nadrzędnej.
- Java wybiera metodę do uruchomienia w czasie wykonywania na podstawie rzeczywistego typu obiektu, a nie tylko typu zmiennej referencyjnej.
- Metod statycznych nie można zastąpić.
- The Adnotacja @Zastąp wyłapuje błędy, takie jak literówki w nazwach metod.
class Animal { void move(){ System.out.println( 'Animal is moving.'); } void eat(){ System.out.println( 'Animal is eating.'); } } class Dog extends Animal{ @Override void move(){ // move method from Base class is overriden in this // method System.out.println('Dog is running.'); } void bark(){ System.out.println('Dog is barking.'); } } public class Geeks { public static void main(String[] args) { Dog d = new Dog(); d.move(); d.eat(); d.bark(); } }
Wyjście
Dog is running. Animal is eating. Dog is barking.
Wyjaśnienie: Klasa Animal definiuje podstawowe funkcjonalności, takie jak przenosić() I jeść() . Klasa Dog dziedziczy po Animal i zastępuje metoda move() zapewniająca określone zachowanie Pies biega. Obie klasy mogą uzyskać dostęp do własnych metod. Podczas tworzenia obiektu Dog wywołanie funkcji move() powoduje wykonanie przesłoniętej metody.

Specjalne przypadki w zastępowaniu
1. Wywołanie metody nadrzędnej przy użyciu super
The super słowo kluczowe może wywołać metodę klasy nadrzędnej z metody przesłaniającej.
obudowa przełącznika JavaJava
class Parent{ void show(){ System.out.println('Parent's show()'); } } class Child extends Parent{ @Override void show(){ super.show(); System.out.println('Child's show()'); } } public class Main{ public static void main(String[] args){ Parent obj = new Child(); obj.show(); } }
Wyjście
Parent's show() Child's show()
2. Metod końcowych nie można zastąpić
Jeśli nie chcemy, aby metoda została zastąpiona, deklarujemy ją jako finał . Proszę zobaczyć Używanie wersji finalnej z dziedziczeniem .
Javaclass Parent{ // Can't be overridden final void show(){ } } class Child extends Parent{ // This would produce error void show() {} }
Wyjście :
stany zjednoczone, ile miast
3. Metody statyczne
- Metod statycznych nie można zastąpić; zdefiniowanie metody statycznej w podklasie z taką samą sygnaturą jak w nadklasie ukrywa metodę nadklasy.
- Metody instancji można przesłonić, ale podklasa nie może przesłonić metody statycznej nadklasy.
- Metoda statyczna w podklasie z tym samym podpisem co metoda statyczna nadklasy ukrywa oryginalną metodę.
class Parent{ static void staticMethod(){ System.out.println('Parent static method'); } void instanceMethod(){ System.out.println('Parent instance method'); } } class Child extends Parent{ static void staticMethod(){ // Hides Parent's static method System.out.println('Child static method'); } @Override void instanceMethod(){ // Overrides Parent's instance method System.out.println('Child instance method'); } } public class GFG{ public static void main(String[] args){ Parent p = new Child(); // Calls Parent's static method (hiding) p.staticMethod(); // Calls Child's overridden instance method p.instanceMethod(); } }
Wyjście
Parent static method Child instance method
4. Metody prywatne
- Metod prywatnych nie można zastąpić, ponieważ nie są one widoczne dla podklas.
- Metoda podklasy o tej samej nazwie jest traktowana jako nowa niezależna metoda niezwiązana z klasą nadrzędną.
class Parent{ private void display(){ System.out.println('Parent private method'); } } class Child extends Parent{ void display(){ // This is a new method not overriding System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ Child c = new Child(); // Calls Child's method c.display(); } }
Wyjście
Child method
5. Kowariantne typy zwrotów
- W metodzie przesłaniającej typ zwracany przez metodę przesłaniającą może być podklasą typu zwracanego przez metodę zastępowaną.
- Ta funkcja jest nazywana kowariantnym typem zwracanym i umożliwia bardziej szczegółowe typy zwracanych wartości w podklasie.
class Parent{ Parent getObject(){ System.out.println('Parent object'); return new Parent(); } } class Child extends Parent{ @Override // Covariant return type Child getObject() { System.out.println('Child object'); return new Child(); } } public class GFG{ public static void main(String[] args){ Parent obj = new Child(); // Calls Child's method obj.getObject(); } }
Wyjście
Child object
Obsługa wyjątków w zastępowaniu
- Metoda przesłaniająca nie może generować nowych ani szerszych sprawdzonych wyjątków niż metoda w nadklasie.
- Może zgłaszać mniej lub węższe sprawdzane wyjątki.
- Może zgłosić dowolne niesprawdzone wyjątki (takie jak RuntimeException) niezależnie od metody nadklasy.
import java.io.IOException; class Parent { void display() throws IOException { System.out.println('Parent method'); } } class Child extends Parent { @Override void display() throws IOException { System.out.println('Child method'); } } public class GFG{ public static void main(String[] args){ // Parent reference Child object Parent obj = new Child(); try{ // Calls Child's overridden method obj.display(); } catch (IOException e){ System.out.println('Exception caught: ' + e.getMessage()); } } }
Wyjście
Child method
Dlaczego używamy przesłaniania metod?
- Aby zmienić lub ulepszyć zachowanie istniejącej metody w podklasie.
- Aby osiągnąć polimorfizm w czasie wykonywania — wywołania metod zależą od rzeczywistego typu obiektu.
- Aby ponownie użyć nazw metod, logicznie zmniejszając redundancję.
Przykład z życia wzięty: System zarządzania pracownikami
Rozumiemy zastąpienie przez analogię ze świata rzeczywistego.
Wyobraź sobie system zarządzania pracownikami organizacji. Wszyscy pracownicy mają wspólne pewne zachowania, takie jak raiseSalary() i promowanie(), ale logika jest inna w przypadku różnych ról, takich jak menedżer czy inżynier. Możemy utworzyć pojedynczą tablicę Employee, w której poszczególni pracownicy należą do różnych typów (technicy sprzedaży itp.) i wywołać ich funkcje. To znacznie upraszcza cały kod.
Javaabstract class Employee { abstract void raiseSalary(); abstract void promote(); } class Manager extends Employee{ @Override void raiseSalary(){ System.out.println( 'Manager salary raised with incentives.'); } @Override void promote(){ System.out.println( 'Manager promoted to Senior Manager.'); } } class Engineer extends Employee{ @Override void raiseSalary(){ System.out.println( 'Engineer salary raised with bonus.'); } @Override void promote(){ System.out.println( 'Engineer promoted to Senior Engineer.'); } } public class Company{ public static void main(String[] args){ Employee[] employees = { new Manager() new Engineer() }; System.out.println('--- Raising Salaries ---'); for (Employee e : employees){ e.raiseSalary(); } System.out.println('n--- Promotions ---'); for (Employee e : employees) { e.promote(); } } }
Wyjście
--- Raising Salaries --- Manager salary raised with incentives. Engineer salary raised with bonus. --- Promotions --- Manager promoted to Senior Manager. Engineer promoted to Senior Engineer.
Wyjaśnienie: Chociaż zarówno obiekty Menedżera, jak i Inżyniera są określane przy użyciu typu Pracownik, Java wywołuje przesłonięte metody rzeczywistych obiektów w czasie wykonywania, demonstrując dynamiczne wysyłanie metod (polimorfizm środowiska wykonawczego).
Powiązany artykuł: Przeciążanie metod i zastępowanie metod
Java równa się metoda