Nadređivanje metoda
Nadređivanje metoda (en. method overriding), također premošćivanje metoda, u objektno orijentiranom programiranju, mogućnost je programskog jezika koja omogućuje naslijeđenoj podklasi (djetetu) da pruži specifičniju implementaciju metode koja je već definirana u nadklasi (roditelju).
Implementacija istoimene metode u podklasi nadređuje (zamjenjuje) implementaciju u nadklasi samo ako metoda ima isti funkcijski potpis (isto ime, isti tip i broj parametara te isti povratni tip).[1] Metodu koja će se izvršiti odabire kompilator pri izvršavanju programa, ovisno o objektu koji metodu poziva. Ako roditeljska klasa instancira objekt, pozvat će se metoda roditeljske klase. Suprotno tome, ako je objekt instanca naslijeđene klase, bit će izvedena inačica metode u podklasi.[2]
Neki programski jezici dopuštaju programeru da ručno ograniči nadređivanje metoda.
C# podržava nadređivanje, ali samo ako je ono eksplicitno zatraženo putem modifikatora override
i virtual
ili abstract
.
abstract class Zivotinja
{
public string Ime { get; set; }
// metode
public void Pij();
public virtual void Jedi();
public void Idi();
}
class Pas : Zivotinja
{
public new string Ime { get; set; }
// metode
public void Pij(); // skriva naslijeđenu metodu pij(). Koristi new za pristup
public override void Jedi(); // Nadređuje naslijeđenu metodu jedi()
public new void Idi(); // skriva naslijeđenu metodu idi()
}
Potpisi nadređenih metoda moraju biti identični, i metode moraju imati istu vidljivost. C# dopušta nadređivanje metoda, indeksera, svojstava i događaja.
Ne-virtualne ili statičke metode ne mogu se nadrediti. Bazna klasa uvijek mora imati jedan od modifikatora virtual, abstract, ili override.
Uz gorenavedene modifikatore, C# dopušta prikrivanje naslijeđenog svojstva ili metode, ako metoda ili svojstvo ima jednak potpis, ali koristi modifikator new
.[3]
U gornjem primjeru, zbog prikrivanja se događa sljedeće:
Pas pas = new Pas();
pas.Ime = …; // pristupa Pas.Ime
pas.Jedi(); // poziva Pas.Jedi()
pas.Idi(); // poziva Pas.Idi()
((Zivotinja)pas).Ime = …; // poziva Zivotinja.Ime!
((Zivotinja)pas).Jedi(); // poziva Pas.Jedi()!
((Zivotinja)pas).Idi(); // poziva Zivotinja.Idi()!
C++ zahtjeva eksplicitno definiranje imena klase čiju metodu želimo pozvati, pomoću en. scope resolution operator – „operatora razrješenja dosega”, ::
.
Primjerice, idući kod stvara dvije naslijeđene klase, baznu klasu Pravokutnik (koji može ispisati svoju duljinu i širinu) i naslijeđenu klasu Kutija (koja ima još i visinu). Kutija nadređuje metodu za ispis, kako bi ispisala svoje tri dimenzije.[4]
#include <iostream>
//---------------------------------------------------------------------------
class Pravokutnik {
public:
Pravokutnik(double d, double s) : duljina_(d), sirina_(s) {}
virtual void Ispis() const;
private:
double duljina_;
double sirina_;
};
//---------------------------------------------------------------------------
void Pravokutnik::Ispis() const {
// metoda za ispis bazne klase.
std::cout << "Duljina = " << duljina_ << "; Širina = " << sirina_;
}
//---------------------------------------------------------------------------
class Kutija : public Pravokutnik {
public:
Kutija(double d, double s, double v) : Pravokutnik(d, s), visina_(v) {}
void Ispis() const override;
private:
double visina_;
};
//---------------------------------------------------------------------------
// metoda za ispis naslijeđene klase
void Kutija::Ispis() const {
// Pozovi roditeljsku metodu za ispis
Pravokutnik::Ispis(); // ispisuje duljinu i širinu
std::cout << "; Visina = " << visina_;
}
Metoda za ispis klase Kutija, pozivanjem metode ispis klase Pravokutnik, može ispisati privatne članske varijable duljina i sirina, koje bi joj inaće bile nedostupne.
Iduće će naredbe instancirati objekte tipa Pravokutnik i Kutija, i pozvati njihove metode za ispis:
int main(int argc, char** argv) {
Pravokutnik p(5.0, 3.0);
// Ispisuje: Duljina = 5.0; Širina = 3.0
p.Ispis();
Kutija k(6.0, 5.0, 4.0);
// pokazivač na najviše nadređenu metodu u virtualnoj tablici je na Kutija::Ispis,
// ali to ne demonstrira nadređivanje
k.Ispis();
// Ovaj poziv demonstrira nadređenje
// ispisuje: Duljina = 6.0; Širina = 5.0; Visina= 4.0
static_cast<Pravokutnik&>(k).Ispis();
}
U C++11, slično kao u Javi, metoda s modifikatorom final u nadklasi ne može se nadrediti. Metodama u podklasi se također može nadjenuti modifikator override, kako bi kompilator provjerio nadređuje li metoda zaista neku metodu bazne klase.
U Javi, kada podklasa sadrži metodu koja nadređuje metodu nadklase, metoda podklase može pozvati metodu nadklase koristeći ključnu riječ super
.[2]
Primjer:
class Misao {
public void poruka() {
System.out.println("Osjećam da sam parkiran dijagonalno u paralelnom svemiru.");
}
}
public class Savjet extends Misao {
@Override // anotacija @Override nije nužna u Javi 5
public void poruka() {
System.out.println("Savjet: Datumi u kalendaru bliže su nego što izgleda.");
}
}
Klasa Misao je nadklasa, i implementira poziv metode poruka. Podklasa Savjet nasljeđuje sve metode klase Misao, i nadređuje metodu poruka, jer joj pruža drugu funkcionalnost.
Misao parking = new Misao();
parking.poruka(); // Ispisuje "Osjećam da sam parkiran dijagonalno u paralelnom svemiru."
Misao datumi = new Savjet(); // Polimorfizam
datumi.poruka(); // Ispisuje "Savjet: Datumi u kalendaru bliže su nego što izgleda."
Poziv nadređene metode unutar podklase može se napisati kao:
public class Savjet extends Misao {
@Override
public void poruka() {
System.out.println("Savjet: Datumi u kalendaru bliže su nego što izgleda.");
super.poruka(); // Poziva inačicu metode roditeljske klase (Misao.poruka()).
}
Postoje metode koje podklasa ne može nadrediti. To uključuje[5]:
- metode u nadklasi koje imaju modifikator final
- metode s modifikatorima private ili static jer im je implicitno dodjeljen i modifikator final
- klasa ne može naslijediti drugu klasu s modifikatorom final (klase s modifikatorom final ne mogu biti nadklase)
Ako podklasa u Python, sadrži metodu koja premošćuje metodu nadklase, moguće je eksplicitno pozvati metodu nadklase pozivom super(Subclass, self).method
[6] umjesto self.method
.
Primjer:
class Misao:
def __init__(self) -> None:
print("Ja sam novi objekt tipa Misao!")
def poruka(self) -> None:
print("Osjećam da sam parkiran dijagonalno u paralelnom svemiru.")
class Savjet(Misao):
def __init__(self) -> None:
super(Savjet, self).__init__()
def poruka(self) -> None:
print("Savjet: Datumi u kalendaru bliže su nego što izgleda.")
super(Savjet, self).poruka()
t = Misao()
# ispisuje "Ja sam novi objekt tipa Misao!"
t.poruka()
# ispisuje "Osjećam da sam parkiran dijagonalno u paralelnom svemiru.
a = Savjet()
# ispisuje "Ja sam novi objekt tipa Misao!"
a.poruka()
# ispisuje "Savjet: Datumi u kalendaru bliže su nego što izgleda."
# zatim ispisuje "Osjećam da sam parkiran dijagonalno u paralelnom svemiru.
# ------------------
# provjera:
isinstance(t, Misao)
# True
isinstance(a, Savjet)
# True
isinstance(a, Misao)
# True
- ↑ Flanagan 2002, str. 107
- ↑ a b Lewis & Loftus 2006, str. 454
- ↑ Mössenböck, Hanspeter. 25. ožujka 2002. Advanced C#: Overriding of Methods (PDF). Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. str. 6–8. Pristupljeno 2. kolovoza 2011.
- ↑ Malik 2006, str. 676
- ↑ Deitel & Deitel 2001, str. 474
- ↑ ili
super().method
u Pythonu 3 - vidi https://docs.python.org/3/library/functions.html#super Arhivirana inačica izvorne stranice od 26. listopad 2018. (Wayback Machine)
- Deitel, H. M & Deitel, P. J.(2001). Java How to Program (4th ed.). Upper Saddle River, NJ: Prentice Hall.
- Lewis, J. & Loftus, W. (2008). Java: Software Solutions (6th ed.). Boston, MA: Pearson Addison Wesley.
- Malik, D. S.(2006). C++ Programming: Program Design Including Data Structure. (3rd ed.). Washington, DC: Course Technology.
- Flanagan, David.(2002).Java in a Nutshell. Dohvaćeno s http://oreilly.com/catalog/9780596002831/preview#preview
- Meyer, Bertrand (2009). Touch of Class: Learning to Program Well with Objects and Contracts. Springer.
- Java Method Overriding by Hemanth Balaji
- Introduction to O.O.P. Concepts and More by Nirosh L.w.C.
- Overriding and Hiding Methods by Sun Microsystems
|