logo

Anul·lació a Java

A Java, la substitució és una característica que permet que una subclasse o classe secundària proporcioni una implementació específica d'un mètode que ja proporciona una de les seves superclasses o classes pare. Quan un mètode d'una subclasse té el mateix nom, els mateixos paràmetres o signatura i el mateix tipus de retorn (o subtipus) que un mètode de la seva superclasse, es diu que el mètode de la subclasse és anul·lar el mètode a la superclasse.



La substitució de mètodes és una de les maneres d'aconseguir Java Polimorfisme en temps d'execució . La versió d'un mètode que s'executa estarà determinada per l'objecte que s'utilitza per invocar-lo. Si s'utilitza un objecte d'una classe pare per invocar el mètode, s'executarà la versió de la classe pare, però si s'utilitza un objecte de la subclasse per invocar el mètode, s'executarà la versió de la classe secundaria. En altres paraules, és el tipus d'objecte al qual es fa referència (no el tipus de variable de referència) que determina quina versió d'un mètode anul·lat s'executarà.

Exemple de substitució de mètodes a Java

A continuació es mostra la implementació de la substitució del mètode 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();> >}> }>

>

>

Sortida

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

Regles per a la substitució del mètode Java

1. Modificadors d'accés i anul·lació

El modificador d'accés per a un mètode anul·lat pot permetre més, però no menys, accés que el mètode anul·lat. Per exemple, un mètode d'instància protegit a la superclasse es pot fer públic, però no privat, a la subclasse. Si ho feu, es generarà un error en temps de compilació.

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

>

>

derivada parcial del làtex
Sortida

From parent m2() From child m2()>

2. Els mètodes finals no es poden anul·lar

Si no volem que se substitueixi un mètode, el declarem com final . Siusplau mira Ús de Final amb Herència .

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

>

>

Sortida

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

3. Els mètodes estàtics no es poden anul·lar (Anul·lació de mètodes vs Ocultació de mètodes):

Quan definiu un mètode estàtic amb la mateixa signatura que un mètode estàtic a la classe base, es coneix com mètode d'amagat . La taula següent resumeix el que passa quan es defineix un mètode amb la mateixa signatura que un mètode en una superclasse.

Mètode d'instància superclasse Mètode estàtic de superclasse
Mètode d'instància de subclasse Anul·lació Genera un error en temps de compilació
Subclasse Mètode estàtic Genera un error en temps de compilació S'amaga

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

>

>

Sortida

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

4. Els mètodes privats no es poden anul·lar

Mètodes privats no es poden anul·lar ja que s'uneixen durant el temps de compilació. Per tant, ni tan sols podem anul·lar mètodes privats en una subclasse (vegeu això per als detalls).

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

>

cadena inversa java
>

Sortida

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. El mètode d'anul·lació ha de tenir el mateix tipus de retorn (o subtipus)

A partir de Java 5.0 és possible tenir diferents tipus de retorn per a un mètode de substitució a la classe fill, però el tipus de retorn del fill hauria de ser un subtipus del tipus de retorn del pare. Aquest fenomen es coneix com a tipus de retorn 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();> >}> }>

>

>

Sortida

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

6. Invocació del mètode anul·lat des de la subclasse

Podem cridar el mètode de classe pare en el mètode d'anul·lació utilitzant el súper paraula clau .

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

jdbc jdbc

>

>

Sortida

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

Anul·lació i Constructor

No podem anul·lar el constructor, ja que la classe pare i la classe fill mai poden tenir un constructor amb el mateix nom (El nom del constructor sempre ha de ser el mateix que el nom de la classe).

Anul·lació i gestió d'excepcions

A continuació es mostren dues regles a tenir en compte quan es substitueixen mètodes relacionats amb el maneig d'excepcions.

Regla #1

Si el mètode d'anul·lació de la superclasse no llança una excepció, el mètode d'anul·lació de la subclasse només pot llançar el excepció no marcada , llançar una excepció marcada provocarà un error en temps de compilació.

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

>

>

Sortida

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>

Regla #2

Si el mètode d'anul·lació de la superclasse llança una excepció, el mètode de substitució de la subclasse només pot llançar la mateixa excepció de la subclasse. Llançar excepcions dels pares al Jerarquia d'excepcions donarà lloc a un error de temps de compilació. A més, no hi ha cap problema si el mètode anul·lat de la subclasse no llança cap excepció.

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

>

>

Sortida

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

Anul·lació i mètode abstracte

Els mètodes abstractes d'una interfície o classe abstracta s'han de substituir en classes concretes derivades, en cas contrari es produirà un error en temps de compilació.

Anul·lació i mètode sincronitzat/strictfp

La presència d'un modificador sincronitzat/strictfp amb el mètode no té cap efecte sobre les regles d'anul·lació, és a dir, és possible que un mètode sincronitzat/strictfp pugui anul·lar-ne un de no sincronitzat/strictfp i viceversa.

Nota:

  1. En C++, necessitem paraula clau virtual per aconseguir l'anul·lació o Polimorfisme en temps d'execució . A Java, els mètodes són virtuals per defecte.
  2. Podem tenir una substitució de mètodes multinivell.

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

>

>

entrada java
Sortida

GrandChild's show()>

Anulació de mètodes vs sobrecàrrega de mètodes

1. Sobrecàrrega és aproximadament el mateix mètode amb signatures diferents. La substitució és aproximadament el mateix mètode i la mateixa signatura, però diferents classes connectades mitjançant l'herència.

2. La sobrecàrrega és un exemple de polimorfisme en temps del compilador i la substitució és un exemple de temps d'execució polimorfisme .

Preguntes freqüents sobre la substitució del mètode Java

Q1. Què és la substitució del mètode?

Com s'ha dit anteriorment, els mètodes anul·lats permeten suportar Java polimorfisme en temps d'execució . El polimorfisme és essencial per a la programació orientada a objectes per una raó: permet a una classe general especificar mètodes que seran comuns a totes les seves derivades alhora que permet a les subclasses definir la implementació específica d'alguns o tots aquests mètodes. Els mètodes anul·lats són una altra manera en què Java implementa l'aspecte d'una interfície, múltiples mètodes del polimorfisme. Enviament del mètode dinàmic és un dels mecanismes més potents que té el disseny orientat a objectes per a la reutilització i la robustesa del codi. La capacitat d'existir biblioteques de codi per cridar mètodes en instàncies de classes noves sense recompilar mentre es manté una interfície abstracta neta és una eina profundament poderosa. Els mètodes anul·lats ens permeten cridar mètodes de qualsevol de les classes derivades sense ni tan sols conèixer el tipus d'objecte de classe derivada.

P2. Quan aplicar la substitució del mètode? (amb exemple)

Anul·lació i Herència : Part de la clau per aplicar amb èxit el polimorfisme és entendre que les superclasses i subclasses formen una jerarquia que passa d'una especialització menor a una major. Utilitzada correctament, la superclasse proporciona tots els elements que una subclasse pot utilitzar directament. També defineix aquells mètodes que la classe derivada ha d'implementar per si mateixa. Això permet a la subclasse la flexibilitat per definir els seus mètodes, però encara imposa una interfície coherent. Així, combinant l'herència amb mètodes anul·lats, una superclasse pot definir la forma general dels mètodes que seran utilitzats per totes les seves subclasses. Vegem un exemple més pràctic que utilitza la substitució de mètodes. Penseu en un programari de gestió d'empleats per a una organització, deixeu que el codi tingui una classe base simple Employee, i la classe tingui mètodes com raiseSalary(), transfer(), promotion(), .. etc. Diferents tipus d'empleats com Gerent, Enginyer, ..etc poden tenir les seves implementacions dels mètodes presents a la classe base Employee. En el nostre programari complet, només hem de passar una llista d'empleats a tot arreu i trucar als mètodes adequats sense ni tan sols saber el tipus d'empleat. Per exemple, podem augmentar fàcilment el sou de tots els empleats iterant per la llista d'empleats. Cada tipus d'empleat pot tenir la seva lògica a la seva classe, no ens hem de preocupar perquè si raiseSalary() està present per a un tipus d'empleat específic, només s'anomenaria aquest mètode.

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

>

>

Sortida

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

Article relacionat

  • Enviament de mètodes dinàmics o polimorfisme en temps d'execució a Java
  • Anul·lació del mètode equals() de la classe Object
  • Anul·lació del mètode toString() de la classe Object
  • Sobrecàrrega en java
  • Sortida del programa Java | Set 18 (Anul·lació)