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.
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ý.
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.
Zatím nic konkrétního.
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: