I Java er overstyring en funksjon som lar en underklasse eller barneklasse gi en spesifikk implementering av en metode som allerede er levert av en av dens superklasser eller overordnede klasser. Når en metode i en underklasse har samme navn, samme parametere eller signatur, og samme returtype (eller undertype) som en metode i sin superklasse, så sies metoden i underklassen å overstyring metoden i superklassen.
Metodeoverstyring er en av måtene Java oppnår Run Time Polymorphism . Versjonen av en metode som utføres vil bli bestemt av objektet som brukes til å påkalle den. Hvis et objekt av en overordnet klasse brukes til å påkalle metoden, vil versjonen i den overordnede klassen bli utført, men hvis et objekt av underklassen brukes til å påkalle metoden, vil versjonen i underklassen bli kjørt. Med andre ord, det er typen av objektet det refereres til (ikke typen referansevariabel) som bestemmer hvilken versjon av en overstyrt metode som skal kjøres.
Eksempel på metodeoverstyring i Java
Nedenfor er implementeringen av Java-metodeoverstyringen:
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();> >}> }> |
>
>Produksjon
Parent's show() Child's show()>
Regler for Java-metodeoverstyring
1. Overstyring og tilgangsmodifikatorer
De tilgangsmodifikator for en overstyrende metode kan tillate mer, men ikke mindre, tilgang enn den overstyrte metoden. For eksempel kan en beskyttet forekomstmetode i superklassen gjøres offentlig, men ikke privat, i underklassen. Å gjøre det vil generere en kompileringstidsfeil.
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();> >}> }> |
>
>Produksjon
From parent m2() From child m2()>
2. Endelige metoder kan ikke overstyres
Hvis vi ikke vil at en metode skal overstyres, erklærer vi den som endelig . Vær snill å se Bruker Final med arv .
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() {}> }> |
>
>
Produksjon
13: error: show() in Child cannot override show() in Parent void show() { } ^ overridden method is final> 3. Statiske metoder kan ikke overstyres (Metodeoverstyring vs Metodeskjul):
Når du definerer en statisk metode med samme signatur som en statisk metode i basisklassen, er den kjent som metode skjule . Tabellen nedenfor oppsummerer hva som skjer når du definerer en metode med samme signatur som en metode i en superklasse.
| Superklasse-forekomstmetode | Superklasse statisk metode | |
|---|---|---|
| Underklasse forekomstmetode | Overstyrer | Genererer en kompileringstidsfeil |
| Underklasse Statisk metode | Genererer en kompileringstidsfeil | Skjuler |
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();> >}> }> |
>
>Produksjon
From parent static m1() From child non - static(instance) m2()>
4. Private metoder kan ikke overstyres
Private metoder kan ikke overstyres da de er bundet under kompileringstiden. Derfor kan vi ikke engang overstyre private metoder i en underklasse.(Se dette for detaljer).
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> >}> }> |
>
>Produksjon
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. Den overordnede metoden må ha samme returtype (eller undertype)
Fra Java 5.0 og utover er det mulig å ha forskjellige returtyper for en overordnet metode i barneklassen, men barnets returtype bør være en undertype av forelderens returtype. Dette fenomenet er kjent som kovariant returtype .
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();> >}> }> |
>
>Produksjon
This is the method in SuperClass This is the method in SubClass>
6. Påkalle overstyrt metode fra underklasse
Vi kan kalle den overordnede klassemetoden i den overordnede metoden ved å bruke super nøkkelord .
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();> >}> }> |
>
>Produksjon
Parent's show() Child's show()>
Overordnet og Konstruktør
Vi kan ikke overstyre konstruktøren da overordnet og underordnet klasse aldri kan ha en konstruktør med samme navn (Konstruktørnavnet må alltid være det samme som klassenavnet).
Overstyring og unntakshåndtering
Nedenfor er to regler å merke seg når du overstyrer metoder knyttet til unntakshåndtering.
Regel #1
Hvis den overstyrte metoden for superklassen ikke gir et unntak, kan den overordnede metoden for underklassen bare kaste uavmerket unntak , vil å kaste et sjekket unntak føre til en kompileringstidsfeil.
Java
hvis annet 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'>);> >}> }> |
>
>
Produksjon
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> Regel #2
Hvis den overstyrte metoden for superklassen gir et unntak, kan den overordnede metoden for underklassen bare kaste det samme underklasseunntaket. Kaste foreldre unntak i Unntakshierarki vil føre til kompileringstidsfeil. Det er heller ikke noe problem hvis den overstyrte underklassens metode ikke gir noe unntak.
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()'>);> >}> }> |
>
>
Produksjon
error: m1() in Child4 cannot override m1() in Parent void m1() throws Exception ^ overridden method does not throw Exception>
Overordnet og abstrakt metode
Abstrakte metoder i et grensesnitt eller abstrakt klasse er ment å bli overstyrt i avledede konkrete klasser ellers vil en kompileringstidsfeil bli kastet.
Overstyring og synkronisert/strictfp-metode
Tilstedeværelsen av en synkronisert/strictfp-modifikator med metoden har ingen effekt på reglene for overstyring, det vil si at det er mulig at en synkronisert/strictfp-metode kan overstyre en ikke-synkronisert/strictfp-metode og omvendt.
Merk:
- I C++ trenger vi virtuelt nøkkelord å oppnå overordnet eller Run Time Polymorphism . I Java er metoder virtuelle som standard.
- Vi kan ha metodeoverstyring på flere nivåer.
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();> >}> }> |
>
>Produksjon
GrandChild's show()>
Metodeoverstyring vs metodeoverbelastning
1. Overbelastning er omtrent samme metode som har forskjellige signaturer. Overstyring handler om samme metode, og samme signatur, men forskjellige klasser koblet sammen gjennom arv.
2. Overbelastning er et eksempel på kompilator-tidspolymorfisme og overstyring er et eksempel på kjøretid polymorfisme .
Vanlige spørsmål om overstyring av Java-metoder
Q1. Hva er metodeoverstyring?
Som nevnt tidligere lar overstyrte metoder Java støtte kjøretidspolymorfisme . Polymorfisme er essensielt for objektorientert programmering av én grunn: den lar en generell klasse spesifisere metoder som vil være felles for alle dens derivater, samtidig som det lar underklasser definere den spesifikke implementeringen av noen eller alle disse metodene. Overstyrte metoder er en annen måte Java implementerer det ene grensesnittet, flere metodeaspektet ved polymorfisme. Dynamisk metodeutsendelse er en av de kraftigste mekanismene som objektorientert design gir utslag på gjenbruk og robusthet av kode. Evnen til å eksistere kodebiblioteker for å kalle metoder på forekomster av nye klasser uten å rekompilere mens du opprettholder et rent abstrakt grensesnitt er et svært kraftig verktøy. Overstyrte metoder lar oss kalle metoder for noen av de avledede klassene uten engang å vite typen avledet klasseobjekt.
Q2. Når skal man bruke metodeoverstyring? (med eksempel)
Overordnede og Arv : En del av nøkkelen til vellykket anvendelse av polymorfisme er å forstå at superklassene og underklassene danner et hierarki som beveger seg fra mindre til større spesialisering. Brukt riktig, gir superklassen alle elementer som en underklasse kan bruke direkte. Den definerer også de metodene som den avledede klassen må implementere på egen hånd. Dette gir underklassen fleksibilitet til å definere metodene sine, men fremtvinger likevel et konsistent grensesnitt. Dermed, ved å kombinere arv med overstyrte metoder, kan en superklasse definere den generelle formen til metodene som skal brukes av alle dens underklasser. La oss se på et mer praktisk eksempel som bruker metodeoverstyring. Tenk på en ansattadministrasjonsprogramvare for en organisasjon, la koden ha en enkel basisklasse Employee, og klassen har metoder som raiseSalary(), transfer(), promote(), .. etc. Ulike typer ansatte som Manager, Engineer, ..etc kan ha sine implementeringer av metodene til stede i basisklassen Employee. I vår komplette programvare trenger vi bare å sende en liste over ansatte overalt og ringe passende metoder uten engang å vite hvilken type ansatt. For eksempel kan vi enkelt heve lønnen til alle ansatte ved å iterere gjennom listen over ansatte. Hver type ansatt kan ha sin logikk i sin klasse, vi trenger ikke å bekymre deg fordi hvis raiseSalary() er tilstede for en spesifikk ansatttype, vil bare den metoden bli kalt.
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);>>}>}>>>ProduksjonManager's salary : 30000 Clerk's salary : 20000>
Relatert artikkel
- Dynamic Method Dispatch eller Runtime Polymorphism i Java
- Overstyre equals()-metoden for objektklassen
- Overstyre toString()-metoden for Object-klassen
- Overbelastning i java
- Utgang av Java-program | Sett 18 (overstyrer)