logo

Suprascriere în Java

În Java, suprascrierea este o caracteristică care permite unei subclase sau clase copil să ofere o implementare specifică a unei metode care este deja furnizată de una dintre superclasele sau clasele părinte ale acesteia. Când o metodă dintr-o subclasă are același nume, aceiași parametri sau semnătură și același tip de returnare (sau sub-tip) ca o metodă din super-clasa, atunci metoda din subclasă se spune că trece peste metoda din superclasa.

Suprascrierea metodei este una dintre modalitățile prin care Java realizează Polimorfismul timpului de rulare . Versiunea unei metode care este executată va fi determinată de obiectul care este utilizat pentru a o invoca. Dacă un obiect al unei clase părinte este folosit pentru a invoca metoda, atunci versiunea din clasa părinte va fi executată, dar dacă un obiect al subclasei este folosit pentru a invoca metoda, atunci versiunea din clasa copil va fi executată. Cu alte cuvinte, este tipul obiectului la care se face referire (nu tipul variabilei de referință) care determină ce versiune a unei metode suprascrise va fi executată.



Exemplu de înlocuire a metodei în Java

Mai jos este implementarea suprascrierii metodei 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();> >}> }>

>

>

Ieșire

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

Reguli pentru înlocuirea metodei Java

1. Modificatori de suprascriere și acces

The modificator de acces pentru o metodă de suprascriere poate permite mai mult, dar nu mai puțin, acces decât metoda suprascrisă. De exemplu, o metodă de instanță protejată din superclasă poate fi făcută publică, dar nu privată, în subclasă. Procedând astfel, va genera o eroare de compilare.

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

>

>

Ieșire

From parent m2() From child m2()>

2. Metodele finale nu pot fi anulate

Dacă nu dorim ca o metodă să fie înlocuită, o declarăm ca final . Te rog vezi Utilizarea Final cu Moștenire .

Java

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

>

>

Ieșire

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

3. Metodele statice nu pot fi suprascrise (Anularea metodei vs Ascunderea metodei):

Când definiți o metodă statică cu aceeași semnătură ca o metodă statică din clasa de bază, aceasta este cunoscută ca ascunderea metodei . Următorul tabel rezumă ce se întâmplă atunci când definiți o metodă cu aceeași semnătură ca o metodă dintr-o super-clasă.

Metoda de instanță superclasă Metoda statică a superclasei
Metoda Instanțelor Subclasei Anulează Generează o eroare de compilare
Subclasa Metoda statică Generează o eroare de compilare Se ascunde

Java




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

>

>

Ieșire

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

4. Metodele private nu pot fi anulate

Metode private nu pot fi suprascrise deoarece sunt legate în timpul compilării. Prin urmare, nici măcar nu putem suprascrie metodele private dintr-o subclasă. (vezi acest pentru detalii).

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

nullpointerexception
>

>

Ieșire

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 de suprascriere trebuie să aibă același tip de returnare (sau subtip)

Începând cu Java 5.0, este posibil să existe diferite tipuri de returnare pentru o metodă de suprascriere în clasa copil, dar tipul de returnare al copilului ar trebui să fie un subtip al tipului de returnare al părintelui. Acest fenomen este cunoscut sub numele de tip de returnare covariant .

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

>

>

Ieșire

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

6. Invocarea metodei suprascrise din subclasă

Putem apela metoda clasei părinte în metoda suprascrierii folosind super cuvânt cheie .

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

>

>

Ieșire

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

Suprascriere și Constructor

Nu putem suprascrie constructorul, deoarece clasa părinte și fiul nu pot avea niciodată un constructor cu același nume (Numele constructorului trebuie să fie întotdeauna același cu numele clasei).

Depășirea și gestionarea excepțiilor

Mai jos sunt două reguli de reținut atunci când înlocuiți metodele legate de gestionarea excepțiilor.

Regula #1

Dacă metoda supra-scrisă de super-clasă nu aruncă o excepție, metoda de înlocuire a subclaselor poate arunca doar excepție nebifată , aruncarea unei excepții bifate va duce la o eroare de compilare.

Java


exemplu java do while



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

>

>

Ieșire

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>

Regula #2

Dacă metoda suprascrisă de superclasă aruncă o excepție, metoda de înlocuire a subclasei poate arunca doar aceeași excepție, subclasă. Aruncarea de excepții pentru părinți în Ierarhia excepțiilor va duce la o eroare de timp de compilare. De asemenea, nu există nicio problemă dacă metoda suprascrisă subclasă nu aruncă nicio excepție.

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

>

>

Ieșire

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

Metoda de suprascriere și abstractă

Metodele abstracte dintr-o interfață sau clasă abstractă sunt menite să fie suprascrise în clase concrete derivate, altfel va fi aruncată o eroare de compilare.

Metoda de suprascriere și sincronizată/strictfp

Prezența unui modificator sincronizat/strictfp cu metoda nu are niciun efect asupra regulilor de suprascriere, adică este posibil ca o metodă sincronizată/strictfp să o înlocuiască pe una nesincronizată/strictfp și invers.

Notă:

  1. În C++, avem nevoie cuvânt cheie virtual pentru a realiza depăşirea sau Polimorfismul timpului de rulare . În Java, metodele sunt virtuale în mod implicit.
  2. Putem avea o suprascriere a metodei pe mai multe niveluri.

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

>

>

Ieșire

GrandChild's show()>

Suprascrierea metodei vs supraîncărcarea metodei

1. Supraîncărcare este aproximativ aceeași metodă având semnături diferite. Suprascrierea este aproximativ aceeași metodă și aceeași semnătură, dar clase diferite conectate prin moștenire.

2. Supraîncărcarea este un exemplu de polimorfism în timpul compilatorului, iar suprascrierea este un exemplu de timp de rulare polimorfism .

Întrebări frecvente despre înlocuirea metodei Java

Î1. Ce este suprascrierea metodei?

După cum sa menționat mai devreme, metodele suprascrise permit Java să accepte polimorfism în timp de rulare . Polimorfismul este esențial pentru programarea orientată pe obiect dintr-un singur motiv: permite unei clase generale să specifice metode care vor fi comune tuturor derivatelor sale, permițând în același timp subclaselor să definească implementarea specifică a unora sau a tuturor acestor metode. Metodele suprascrise sunt un alt mod prin care Java implementează aspectul polimorfismului cu o singură interfață, cu mai multe metode. Expediere prin metoda dinamică este unul dintre cele mai puternice mecanisme pe care proiectarea orientată pe obiecte le aduce asupra reutilizării și robusteței codului. Capacitatea de a exista biblioteci de cod pentru a apela metode pe instanțe de clase noi fără a se recompila, menținând în același timp o interfață abstractă curată, este un instrument profund puternic. Metodele suprascrise ne permit să apelăm metode ale oricăreia dintre clasele derivate fără să știm măcar tipul de obiect al clasei derivate.

Q2. Când să aplicați anularea metodei? (cu exemplu)

Depășind și Moştenire : O parte a cheii pentru aplicarea cu succes a polimorfismului este înțelegerea faptului că superclasele și subclasele formează o ierarhie care trece de la o specializare mai mică la cea mai mare. Folosită corect, superclasa furnizează toate elementele pe care o subclasă le poate folosi direct. De asemenea, definește acele metode pe care clasa derivată trebuie să le implementeze singură. Acest lucru permite subclasei flexibilitatea de a-și defini metodele, dar impune totuși o interfață consistentă. Astfel, combinând moștenirea cu metode suprascrise, o superclasă poate defini forma generală a metodelor care vor fi utilizate de toate subclasele sale. Să ne uităm la un exemplu mai practic care folosește înlocuirea metodei. Luați în considerare un software de management al angajaților pentru o organizație, lăsați codul să aibă o clasă de bază simplă Employee, iar clasa are metode precum raiseSalary(), transfer(), promote(), .. etc. Diferite tipuri de angajați precum Manager, Inginer, ..etc pot avea implementările lor ale metodelor prezente în clasa de bază Employee. În software-ul nostru complet, trebuie doar să trecem peste tot o listă de angajați și să apelăm metode adecvate fără să știm măcar tipul de angajat. De exemplu, putem crește cu ușurință salariul tuturor angajaților prin iterarea listei de angajați. Fiecare tip de angajat poate avea logica sa în clasa sa, nu trebuie să ne facem griji, deoarece dacă raiseSalary() este prezent pentru un anumit tip de angajat, va fi apelată doar acea metodă.

do while loop în java

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

>

>

Ieșire

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

Articol înrudit

  • Expedierea metodei dinamice sau polimorfismul runtime în Java
  • Suprascrierea metodei equals() a clasei Object
  • Suprascrierea metodei toString() a clasei Object
  • Supraîncărcare în java
  • Ieșirea programului Java | Setul 18 (Anulare)