Na programação orientada a objetos , uma função virtual é uma função definida em uma classe (método) que se destina a ser redefinida nas classes que herdam dela. Na maioria das linguagens, todos os métodos são automaticamente virtuais (Java, Swift…) ou a palavra virtual- chave é usada para indicar que o método de uma classe é virtual (C ++, Delphi , Free Pascal …).
Uma função com apenas uma declaração, sem código implementado, é considerada abstrata ou virtual pura .
Métodos puros virtuais devem ser definidos em classes derivadas.
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(); };Java
/** * 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 } };O método area () é redefinido por cada classe derivada. Na verdade, a maneira de calcular a área de uma forma depende do tipo desta.
Basta que uma classe tenha um método puramente virtual para que se diga abstrata .
Você não pode instanciar uma classe abstrata porque isso não faria sentido. Por exemplo: podemos instanciar um objeto “triângulo” que herda da classe base abstrata “forma geométrica”, mas não podemos criar um objeto de “forma geométrica”, que é muito geral.
Algumas linguagens requerem (Swift, C #, ..) ou aconselham (Java, ...) colocar uma palavra-chave para indicar que um método redefine (sobrescreve) o método pai virtual. Isso documenta o código (o método sobrecarrega um método virtual pai) e permite que o compilador verifique se esse é o desejo de quem escreve o método.
Isso é particularmente interessante ao usar uma biblioteca externa.
Até agora, nada em particular.
E ainda, se o programa for recompilado com a biblioteca na versão 2, há uma boa chance de que ele não funcione mais corretamente. Porque o método m2 de D redefine o método m2 de C e seria muito surpreendente se ele tivesse um código idêntico.
Se uma palavra-chave de sobrecarga é imposta, o programa não compila mais porque o compilador descobre que o método m2 de D sobrecarrega o método m2 de C sem dizer isso explicitamente. O cientista da computação, portanto, descobre o erro durante a compilação e pode corrigir seu programa: