Nadređivanje metoda (), 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).Flanagan 2002, str. 107 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.Lewis & Loftus 2006, str. 454

Neki programski jezici dopuštaju programeru da ručno ograniči nadređivanje metoda.

Primjeri po jezicima

C# 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.

Prikrivanje imena Uz gorenavedene modifikatore, C# dopušta prikrivanje naslijeđenog svojstva ili metode, ako metoda ili svojstvo ima jednak potpis, ali koristi modifikator new.

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++ C++ zahtjeva eksplicitno definiranje imena klase čiju metodu želimo pozvati, pomoću , ::. 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.Malik 2006, str. 676

#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.

Java 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. 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čujeDeitel & Deitel 2001, str. 474: 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)

Python Ako podklasa u Python, sadrži metodu koja premošćuje metodu nadklase, moguće je eksplicitno pozvati metodu nadklase pozivom super(Subclass, self).methodili super().method u Pythonu 3 - vidi https://docs.python.org/3/library/functions.html#super 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

Bilješke

Vidi još Preopterećenje funkcija Polimorfizam (računarstvo) Virtualno nasljeđivanje

Izvori 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.

Vanjske poveznice 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

Kategorija:Objektno orijentirano programiranje