logo

Перевизначення в Java

У Java Overriding — це функція, яка дозволяє підкласу або дочірньому класу забезпечувати конкретну реалізацію методу, який уже надається одним із його суперкласів або батьківських класів. Якщо метод у підкласі має таке ж ім’я, ті самі параметри або підпис і той самий тип (або підтип) повернення, що й метод у його суперкласі, тоді метод у підкласі називається перевизначити метод в супер-класі.

Перевизначення методу є одним із способів досягнення Java Поліморфізм часу виконання . Версія методу, що виконується, визначатиметься об’єктом, який використовується для його виклику. Якщо для виклику методу використовується об’єкт батьківського класу, тоді буде виконана версія в батьківському класі, але якщо для виклику методу використовується об’єкт підкласу, тоді буде виконана версія в дочірньому класі. Іншими словами, це тип об'єкта, про який йдеться (а не тип посилальної змінної), яка визначає, яка версія перевизначеного методу буде виконана.



Приклад перевизначення методу в Java

Нижче наведено реалізацію перевизначення методу 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();> >}> }>

>

>

Вихід

Parent's show() Child's show()>

Правила перевизначення методів Java

1. Перевизначення та модифікатори доступу

The модифікатор доступу для перевизначеного методу можна дозволити більше, але не менше доступу, ніж перевизначений метод. Наприклад, захищений метод екземпляра в суперкласі можна зробити загальнодоступним, але не приватним у підкласі. Це призведе до помилки під час компіляції.

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();> >}> }>

>

>

Вихід

From parent m2() From child m2()>

2. Методи Final не можуть бути перевизначені

Якщо ми не хочемо, щоб метод був перевизначений, ми оголошуємо його як остаточний . Будь ласка, подивіться Використання Final з успадкуванням .

Java




// 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() {}> }>

>

>

Вихід

13: error: show() in Child cannot override show() in Parent  void show() { }  ^  overridden method is final>

3. Статичні методи не можна перевизначати (заміна методу проти приховування методу):

Коли ви визначаєте статичний метод із такою самою сигнатурою, як і статичний метод у базовому класі, він відомий як метод приховування . У наведеній нижче таблиці підсумовується те, що відбувається, коли ви визначаєте метод із такою ж сигнатурою, як і метод у суперкласі.

Метод екземпляра суперкласу Статичний метод суперкласу
Метод екземпляра підкласу Перевизначення Генерує помилку під час компіляції
Статичний метод підкласу Генерує помилку під час компіляції ховає

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();> >}> }>

>

>

Вихід

From parent static m1() From child non - static(instance) m2()>

4. Приватні методи не можуть бути перевизначені

Приватні методи не можна перевизначити, оскільки вони пов’язані під час компіляції. Тому ми навіть не можемо перевизначити приватні методи в підкласі. (Див це для деталей).

Java




двійковий пошук в 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> >}> }>

>

>

Вихід

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. Перевизначений метод повинен мати той самий тип повернення (або підтип)

Починаючи з Java 5.0 і далі, можна мати різні типи повернення для основного методу в дочірньому класі, але дочірній тип повернення повинен бути підтипом батьківського типу. Це явище відоме як коваріантний тип повернення .

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();> >}> }>

>

>

Вихід

This is the method in SuperClass This is the method in SubClass>

6. Виклик перевизначеного методу з підкласу

Ми можемо викликати метод батьківського класу в методі перевизначення за допомогою супер ключове слово .

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();> >}> }>

>

>

Вихід

Parent's show() Child's show()>

Перевизначення та конструктор

Ми не можемо перевизначити конструктор, оскільки батьківський і дочірній класи ніколи не можуть мати конструктор з однаковою назвою (ім’я конструктора завжди має збігатися з ім’ям класу).

Перевизначення та обробка винятків

Нижче наведено два правила, на які слід звернути увагу під час перевизначення методів, пов’язаних із обробкою винятків.

Правило №1

Якщо перевизначений метод суперкласу не створює винятку, метод перевизначення підкласу може видавати лише неперевірений виняток , виклик перевіреного винятку призведе до помилки під час компіляції.

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'>);> >}> }>

>

>

Вихід

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>

Правило №2

Якщо перевизначений метод суперкласу генерує виняток, метод перевизначення підкласу може викликати лише той самий виняток підкласу. Викидання батьківських винятків у Ієрархія винятків призведе до помилки часу компіляції. Крім того, немає проблеми, якщо перевизначений метод підкласу не створює винятків.

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()'>);> >}> }>

>

>

Вихід

error: m1() in Child4 cannot override m1() in Parent  void m1() throws Exception  ^  overridden method does not throw Exception>

Перевизначення та абстрактний метод

Абстрактні методи в інтерфейсі або абстрактному класі призначені для перевизначення в похідних конкретних класах, інакше під час компіляції виникне помилка.

Перевизначення та метод синхронізації/strictfp

Наявність модифікатора synchronized/strictfp у методі не впливає на правила перевизначення, тобто можливо, що метод synchronized/strictfp може перевизначити несинхронізований/strictfp і навпаки.

Примітка:

  1. У C++ нам потрібно віртуальне ключове слово досягти перевищення або Поліморфізм часу виконання . У Java методи віртуальні за замовчуванням.
  2. Ми можемо мати багаторівневе перевизначення методу.

Java




// 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();> >}> }>

>

>

Вихід

GrandChild's show()>

Перевизначення методу проти перевантаження методу

1. Перевантаження це приблизно той самий метод із різними підписами. Перевизначення — це приблизно той самий метод і однаковий підпис, але різні класи, пов’язані через успадкування.

2. Перевантаження є прикладом поліморфізму часу компіляції, а перевизначення є прикладом часу виконання поліморфізм .

Поширені запитання щодо перевизначення методів Java

Q1. Що таке перевизначення методу?

Як було зазначено раніше, перевизначені методи дозволяють підтримувати Java поліморфізм часу виконання . Поліморфізм важливий для об’єктно-орієнтованого програмування з однієї причини: він дозволяє загальному класу вказувати методи, які будуть спільними для всіх його похідних, одночасно дозволяючи підкласам визначати конкретну реалізацію деяких або всіх цих методів. Перевизначені методи — це ще один спосіб, за допомогою якого Java реалізує аспект поліморфізму «один інтерфейс і кілька методів». Динамічний метод диспетчеризації є одним із найпотужніших механізмів, які об’єктно-орієнтоване проектування дає для повторного використання коду та надійності. Можливість існування бібліотек коду для виклику методів екземплярів нових класів без перекомпіляції, зберігаючи чистий абстрактний інтерфейс, є дуже потужним інструментом. Перевизначені методи дозволяють нам викликати методи будь-якого з похідних класів, навіть не знаючи типу об’єкта похідного класу.

Q2. Коли застосовувати перевизначення методу? (з прикладом)

Перевизначення і Спадщина : частиною ключа до успішного застосування поліморфізму є розуміння того, що суперкласи та підкласи утворюють ієрархію, яка рухається від меншої спеціалізації до більшої. При правильному використанні суперклас забезпечує всі елементи, які підклас може використовувати безпосередньо. Він також визначає ті методи, які похідний клас повинен реалізувати самостійно. Це дає підкласу гнучкість у визначенні своїх методів, але все ще забезпечує послідовний інтерфейс. Таким чином, поєднуючи успадкування з перевизначеними методами, суперклас може визначити загальну форму методів, які будуть використовуватися всіма його підкласами. Давайте розглянемо більш практичний приклад, який використовує перевизначення методу. Розглянемо програмне забезпечення для управління персоналом для організації, нехай код має простий базовий клас Employee, а клас має такі методи, як raiseSalary(), transfer(), promote(), .. тощо. Різні типи працівників, як-от менеджер, інженер, ..etc можуть мати свої реалізації методів, присутніх у базовому класі Employee. У нашому повному програмному забезпеченні нам просто потрібно передавати всюди список співробітників і викликати відповідні методи, навіть не знаючи типу працівника. Наприклад, ми можемо легко підвищити зарплату всім співробітникам, перебираючи список співробітників. Кожен тип співробітника може мати свою логіку у своєму класі, нам не потрібно хвилюватися, тому що якщо raiseSalary() присутній для певного типу співробітника, буде викликаний лише цей метод.

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);> >}> }>

>

>

Вихід

Manager's salary : 30000 Clerk's salary : 20000>

Пов'язана стаття

  • Відправка динамічного методу або поліморфізм часу виконання в Java
  • Перевизначення метода equals() класу Object
  • Перевизначення методу toString() класу Object
  • Перевантаження в java
  • Вихід програми Java | Набір 18 (перевизначення)