Virtuální funkce

V objektově orientovaného programování , je virtuální funkce je funkce definovaná v třídě (metoda), která má být nově definována ve třídách, které dědí z ní. Ve většině jazyků jsou buď všechny metody automaticky virtuální (Java, Swift…), nebo klíčové slovo virtualoznačuje, že metoda třídy je virtuální (C ++, Delphi , Free Pascal …).

O funkci, která má pouze jednu deklaraci bez implementovaného kódu, se říká, že je abstraktní nebo čistě virtuální .

Čisté virtuální metody mají být definovány v odvozených třídách.

příklad

Delphi

type { ----------------------------------- } { Classe TForme. } { ----------------------------------- } TForme = class public function aire():integer; virtual; end; { ----------------------------------- } { Classe TTriangle dérivée de TForme. } { ----------------------------------- } TTriangle = class(TForme) public function aire():integer; virtual; end; { ----------------------------------- } { Classe TCercle dérivée de TForme. } { ----------------------------------- } TCercle = class(TForme) public function aire():integer; virtual; end;

C ++

//--------------------------------------------------------------------------- // Classe Forme. //--------------------------------------------------------------------------- class Forme { public: // La méthode est virtuelle pure. virtual unsigned int aire() = 0; }; //--------------------------------------------------------------------------- // Classe Triangle dérivée de Forme. //--------------------------------------------------------------------------- class Triangle : public Forme { public: virtual unsigned int aire(); }; //--------------------------------------------------------------------------- // Classe Cercle dérivée de Forme. //--------------------------------------------------------------------------- class Cercle : public Forme { public: virtual unsigned int aire(); };

Jáva

/** * Classe Forme. **/ public abstract class Forme { /** * La méthode est virtuelle pure. **/ public abstract int aire(); }; /** * Classe Triangle dérivée de Forme. **/ public class Triangle extends Forme { /** * Implémentation de la méthode. **/ @Override public int aire() { return ...; // calcul de l'aire à partir des champs définis } }; /** * Classe Cercle dérivée de Forme. **/ public class Cercle extends Forme { /** * Implémentation de la méthode. **/ @Override public int aire() { return ...; // calcul de l'aire à partir des champs définis } };

Metoda area () je předefinována každou odvozenou třídou. Způsob výpočtu plochy tvaru skutečně závisí na typu tohoto.

Třídě stačí čistá virtuální metoda, aby se o ní dalo říci, že je abstraktní .

Nemůžete vytvořit instanci abstraktní třídy, protože by to nedávalo smysl. Například: můžeme vytvořit instanci „trojúhelníkového“ objektu, který zdědí z abstraktní základní třídy „geometrický tvar“, ale nemůžeme vytvořit objekt „geometrického tvaru“, který je příliš obecný.

Explicitní přetížení

Některé jazyky vyžadují (Swift, C #, ..) nebo doporučují (Java, ...) umístit klíčové slovo, které označuje, že metoda předefinuje (přepíše) metodu virtuálního rodiče. Toto dokumentuje kód (metoda přetíží nadřazenou virtuální metodu) a umožňuje kompilátoru ověřit, že je to přání toho, kdo metodu píše.

To je zvláště zajímavé při použití externí knihovny.

  • Zvažte třídu C z knihovny verze 1, která definuje jedinou metodu m1.
  • Program používá tuto knihovnu a definuje třídu D, která dědí z C a která definuje metodu m2.

Zatím nic konkrétního.

  • Knihovna se přepne na verzi 2 a nyní definuje metodu m2 (v podpisu naprosto identická s metodou D).
  • Vezměte v úvahu, že knihovna verze 2 je naprosto kompatibilní se všemi hovory uskutečněnými s verzí 1.

A přesto, pokud je program překompilován s knihovnou ve verzi 2, existuje velká šance, že již nebude správně fungovat. Protože m2 metoda D předefinuje m2 metodu C a bylo by velmi překvapivé, kdyby měla identický kód.

Pokud je vynuceno klíčové slovo přetížení, program již nebude kompilován, protože kompilátor zjistí, že metoda m2 metody D přetíží metodu m2 metody C, aniž by to výslovně řekla. Počítačový vědec proto zjistí chybu během kompilace a může svůj program opravit:

  • buď nepoužívejte verzi 2,
  • buď přejmenujte metodu m2 na D,
  • buď proveďte metodu m2 kompatibilní s desiderata C.

Podívejte se také