Přepsání metody - Method overriding
Přepsání metody, v objektově orientované programování, je jazyková funkce, která umožňuje a podtřída nebo podřízená třída k poskytnutí konkrétní implementace a metoda který již poskytuje jeden z jeho nadtřídy nebo rodičovské třídy. Implementace v podtřídě přepíše (nahradí) implementaci v nadtřídě poskytnutím metody, která má stejný název, stejný parametry nebo podpis a stejný návratový typ jako metoda v nadřazené třídě.[1] Verze metody, která se provede, bude určena objekt který se používá k jeho vyvolání. Pokud je k vyvolání metody použit objekt nadřazené třídy, bude provedena verze v nadřazené třídě, ale pokud je k vyvolání metody použit objekt podtřídy, bude provedena verze v podřízené třídě.[2] Některé jazyky umožňují a programátor zabránit přepsání metody.
Jazykově specifické příklady
Ada
Ada Ve výchozím nastavení poskytuje přepsání metody. Chcete-li upřednostnit včasnou detekci chyb (např. překlep), je možné určit, kdy se očekává, že metoda skutečně přepíše, nebo ne. To zkontroluje kompilátor.
typ T je Nový Řízeno s ......; postup Op(Obj: v ven T; Data: v Celé číslo); typ NT je Nový T s nulový záznam; převažující - hlavní indikátor postup Op(Obj: v ven NT; Data: v Celé číslo); převažující - hlavní indikátor postup Op(Obj: v ven NT; Data: v Tětiva); - ^ kompilátor vydá chybu: podprogram „Op“ nemá přednost
C#
C# nepodporuje přepsání metody, ale pouze pokud je to výslovně požadováno pomocí modifikátorů přepsat
a virtuální
nebo abstraktní
.
abstraktní třída Zvíře{ veřejnost tětiva název { dostat; soubor; } // Metody veřejnost prázdnota Napít se(); veřejnost virtuální prázdnota Jíst(); veřejnost prázdnota Jít();}třída Kočka : Zvíře{ veřejnost Nový tětiva název { dostat; soubor; } // Metody veřejnost prázdnota Napít se(); // Varování: skryje zděděný nápoj (). Použít nový veřejnost přepsat prázdnota Jíst(); // Přepíše zděděné jíst (). veřejnost Nový prázdnota Jít(); // Skryje zděděné go ().}
Při přepsání jedné metody druhou metodou podpisy ze dvou metod musí být identické (a se stejnou viditelností). V C #, třídní metody, indexery, vlastnosti a události lze všechny přepsat.
Nelze přepsat jiné než virtuální nebo statické metody. Přepsaná základní metoda musí být virtuální, abstraktnínebo přepsat.
Kromě modifikátorů, které se používají pro přepsání metody, C # umožňuje úkryt zděděné vlastnosti nebo metody. To se provádí pomocí stejného podpisu vlastnosti nebo metody, ale přidáním modifikátoru Nový
před ním.[3]
Ve výše uvedeném příkladu způsobí skrytí následující:
Kočka kočka = Nový Kočka();kočka.název = …; // přistupuje k Cat.Namekočka.Jíst(); // volá Cat.Eat ()kočka.Jít(); // volá Cat.Go ()((Zvíře)kočka).název = …; // přistupuje k Animal.Name!((Zvíře)kočka).Jíst(); // volá Cat.Eat ()!((Zvíře)kočka).Jít(); // volá Animal.Go ()!
C ++
C ++ nemá klíčové slovo super
že podtřída může v Javě použít k vyvolání nadtřídy verze metody, kterou chce přepsat. Místo toho se použije název nadřazené nebo základní třídy následovaný operátor rozlišení oboru. Například následující kód představuje dva třídy, základní třída Obdélník
a odvozená třída Krabice
. Krabice
přepíše Obdélník
třídy Tisk
metoda, aby se také vytiskla jeho výška.[4]
#zahrnout <iostream>//---------------------------------------------------------------------------třída Obdélník { veřejnost: Obdélník(dvojnásobek l, dvojnásobek w) : délka_(l), šířka_(w) {} virtuální prázdnota Tisk() konst; soukromé: dvojnásobek délka_; dvojnásobek šířka_;};//---------------------------------------------------------------------------prázdnota Obdélník::Tisk() konst { // Metoda tisku základní třídy. std::cout << "Délka =" << délka_ << "; Šířka =" << šířka_;}//---------------------------------------------------------------------------třída Krabice : veřejnost Obdélník { veřejnost: Krabice(dvojnásobek l, dvojnásobek w, dvojnásobek h) : Obdélník(l, w), výška_(h) {} prázdnota Tisk() konst přepsat; soukromé: dvojnásobek výška_;};//---------------------------------------------------------------------------// Metoda tisku odvozené třídy.prázdnota Krabice::Tisk() konst { // Vyvolání rodičovské metody tisku. Obdélník::Tisk(); std::cout << "; Výška =" << výška_;}
Metoda Tisk
ve třídě Krabice
vyvoláním nadřazené verze metody Tisk
, je také schopen odeslat soukromý proměnné délka
a šířka
základní třídy. Jinak jsou tyto proměnné nepřístupné Krabice
.
Následující prohlášení vůle vytvořit instanci objekty typu Obdélník
a Krabice
a zavolat jejich příslušným Tisk
metody:
int hlavní(int argc, char** argv) { Obdélník obdélník(5.0, 3.0); // Výstupy: Délka = 5,0; Šířka = 3,0 obdélník.Tisk(); Krabice krabice(6.0, 5.0, 4.0); // Ukazatel na nejvíce přepsanou metodu v vtable in na Box :: print, // ale toto volání neznázorňuje přepsání. krabice.Tisk(); // Toto volání ilustruje přepsání. // výstupy: Délka = 6,0; Šířka = 5,0; Výška = 4,0 static_cast<Obdélník&>(krabice).Tisk();}
v C ++ 11, podobně jako Java, metoda, která je deklarována finále
ve super třídě nelze přepsat; také lze deklarovat metodu přepsat
aby kompilátor zkontroloval, že přepíše metodu v základní třídě.
Delphi
v Delphi, přepsání metody se provádí pomocí směrnice přepsat, ale pouze pokud byla metoda označena dynamický nebo virtuální směrnice.
The zdědil vyhrazené slovo musí být voláno, pokud chcete volat chování super třídy
typ Obdélník = třída soukromé Délka: Dvojnásobek; FŠířka: Dvojnásobek; veřejnost vlastnictví Délka číst Délka psát si Délka; vlastnictví Šířka číst FŠířka psát si FŠířka; postup Tisk; virtuální; konec; TBox = třída(Obdélník) veřejnost postup Tisk; přepsat; konec;
Eiffelova
v Eiffelova, předefinování funkcí je analogický přepisu metody v C ++ a Java. Předefinování je jednou ze tří forem adaptace funkcí klasifikovaných jako vyhlášení. Redeklarace také zahrnuje uskutečnění, ve kterém je implementace poskytována pro funkci, která byla odložena (abstraktní) v nadřazené třídě, a nedefinice, ve kterém se vlastnost, která byla účinná (konkrétní) u rodiče, znovu odloží ve třídě dědiců. Když je prvek předefinován, jeho název si ponechá třída dědiců, ale vlastnosti prvku, jako je jeho podpis, smlouva (respektující omezení pro předpoklady a dodatečné podmínky ) a / nebo implementace se bude u dědice lišit. Pokud je původní funkce v nadřazené třídě, nazývá se dědic funkce předchůdce, je efektivní, pak bude předefinovaná funkce v dědici účinná. Pokud je předchůdce odložen, funkce v dědici bude odložena.[5]
Záměr předefinovat prvek, jako zpráva
v níže uvedeném příkladu musí být výslovně deklarováno v zdědit
klauzule dědické třídy.
třída MYSLELVlastnosti zpráva - Zobrazit myšlenkovou zprávu dělat tisk („Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.% N“) koneckonectřída RADAzdědit MYSLEL předefinovat zpráva konecVlastnosti zpráva - Předchůdce dělat tisk ("Varování: Data v kalendáři jsou bližší, než se zdá.% N") koneckonec
Ve třídě RADA
funkce zpráva
dostane implementaci, která se liší od implementace jeho předchůdce ve třídě MYSLEL
.
Zvažte třídu, která používá instance pro oba MYSLEL
a RADA
:
třída APLIKACEvytvořit udělatVlastnosti udělat - Spusťte aplikaci. dělat (vytvořit {MYSLEL}).zpráva; (vytvořit {RADA}).zpráva koneckonec
Při instanci, třída APLIKACE
vytvoří následující výstup:
Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru. Varování: Data v kalendáři jsou blíže, než se zdá.
V rámci předefinované funkce lze přístup k předchůdci funkce získat pomocí klíčového slova language Předchůdce
. Předpokládejme implementaci {RADA}.zpráva
se mění takto:
zpráva - Předchůdce dělat tisk ("Varování: Data v kalendáři jsou bližší, než se zdá.% N") Předchůdce konec
Vyvolání funkce nyní zahrnuje provádění {MYSLEL}.zpráva
, a vytvoří následující výstup:
Varování: Data v kalendáři jsou bližší, než se zdá. Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.
Jáva
v Jáva, když podtřída obsahuje metodu, která přepíše metodu nadtřídy, může také vyvolat metodu nadtřídy pomocí klíčové slovo super
.[2]Příklad:
třída Myslel { veřejnost prázdnota zpráva() { Systém.ven.tisk(„Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.“); }}veřejnost třída Rada rozšiřuje Myslel { @ Přepis // Anotace @Override v Javě 5 je volitelná, ale užitečná. veřejnost prázdnota zpráva() { Systém.ven.tisk(„Upozornění: Data v kalendáři jsou bližší, než se zdá.“); }}
Třída Myslel
představuje nadtřídu a implementuje volání metody zpráva()
. Volala podtřída Rada
zdědí každou metodu, která by mohla být v Myslel
třída. Nicméně, třída Rada
přepíše metodu zpráva()
, nahrazující jeho funkčnost z Myslel
.
Myslel parkoviště = Nový Myslel();parkoviště.zpráva(); // Tiskne „Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.“Myslel Termíny = Nový Rada(); // PolymorfismusTermíny.zpráva(); // Tiskne „Upozornění: Data v kalendáři jsou blíže, než se zdají.“
The super
odkaz může být
veřejnost třída Rada rozšiřuje Myslel { @ Přepis veřejnost prázdnota zpráva() { Systém.ven.tisk(„Varování: Data v kalendáři jsou bližší, než se zdá.“); super.zpráva(); // Vyvolá rodičovskou verzi metody. }
Existují metody, které podtřída nemůže přepsat. Například v Javě nelze přepsat metodu, která je v super třídě deklarována jako konečná. Metody, které jsou deklarovány jako soukromé nebo statické, nelze přepsat, protože jsou implicitně konečné. Je také nemožné, aby se třída, která je prohlášena za konečnou, stala super třídou.[6]
Kotlin
v Kotlin můžeme jednoduše přepsat funkci jako je tato: všimněte si, že funkce musí být otevřená
zábava hlavní(args: Pole<Tětiva>) { var t = test(5) var s = test2(6) t.myFun() s.myFun()}otevřeno třída test(var A : Int) { otevřeno zábava myFun() = tisk(A)}třída test2(var b : Int) : test(b) { přepsat zábava myFun() = tisk(„přepsaná metoda“)}
Krajta
v Krajta, když podtřída obsahuje metodu, která přepíše metodu nadtřídy, můžete metodu nadtřídy zavolat také voláním super(Podtřída, já).metoda
[7] namísto já.metoda
. Příklad:
třída Myslel: def __init__(já) -> Žádný: tisk(„Jsem nový objekt typu Myšlenka!“) def zpráva(já) -> Žádný: tisk(„Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.“)třída Rada(Myslel): def __init__(já) -> Žádný: super(Rada, já).__init__() def zpráva(já) -> Žádný: tisk(„Upozornění: Data v kalendáři jsou blíže, než se zdají“) super(Rada, já).zpráva()t = Myslel()# "Jsem nový objekt typu Thought!"t.zpráva()# "Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru."A = Rada()# "Jsem nový objekt typu Thought!"A.zpráva()# "Upozornění: Data v kalendáři jsou blíže, než se zdá."# "Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru."# ------------------# Introspekce:je instance(t, Myslel)# Skutečnýje instance(A, Rada)# Skutečnýje instance(A, Myslel)# Skutečný
Rubín
v Rubín když podtřída obsahuje metodu, která přepíše metodu nadtřídy, můžete také zavolat metodu nadtřídy voláním super v této přepsané metodě. Alias můžete použít, pokud chcete zachovat přepsanou metodu k dispozici mimo přepisující metodu, jak je znázorněno níže s 'super_message'.
Příklad:
třída Myslel def zpráva uvádí „Mám pocit, že jsem diagonálně zaparkovaný v paralelním vesmíru.“ koneckonectřída Rada < Myslel alias : super_message :zpráva def zpráva uvádí „Upozornění: Data v kalendáři jsou blíže, než se zdají“ super koneckonec
Poznámky
- ^ Flanagan 2002, s. 107
- ^ A b Lewis & Loftus 2006, s. 454
- ^ Mössenböck, Hanspeter (2002-03-25). „Advanced C #: Overriding of Methods“ (PDF). http://ssw.jku.at/Teaching/Lectures/CSharp/Tutorial/: Institut für Systemsoftware, Johannes Kepler Universität Linz, Fachbereich Informatik. s. 6–8. Citováno 2011-08-02.
- ^ Malik 2006, s. 676
- ^ Meyer 2009, strana 572-575
- ^ Deitel a Deitel 2001, s. 474
- ^
super().metoda
v Pythonu 3 - viz https://docs.python.org/3/library/functions.html#super Archivováno 2018-10-26 na Wayback Machine
Viz také
- Dědičnost implementace
- Dědičná sémantika
- Přetížení metody
- Polymorfismus v objektově orientovaném programování
- Vzor metody šablony
- Virtuální dědičnost
- Záhlaví metody X-HTTP-Override HTTP
Reference
- Deitel, H. M & Deitel, P. J. (2001). Java Jak programovat (4. vydání). Upper Saddle River, NJ: Prentice Hall.
- Lewis, J. & Loftus, W. (2008). Java: Softwarová řešení (6. vydání). Boston, MA: Pearson Addison Wesley.
- Malik, D. S. (2006). Programování v C ++: Návrh programu včetně datové struktury. (3. vyd.). Washington, DC: Technologie kurzů.
- Flanagan, David. (2002).Java v kostce.Citováno z http://oreilly.com/catalog/9780596002831/preview#preview
- Meyer, Bertrand (2009). Dotek třídy: Naučit se dobře programovat s objekty a smlouvami. Springer.
externí odkazy
- Přepsání metody Java autor: Hemanth Balaji
- Úvod do O.O.P. Koncepty a další autor: Nirosh L.w.C.
- Přepisování a skrývání metod podle Sun Microsystems