Atenção: por essa edição ser muito antiga não há arquivo PDF para download. Os artigos dessa edição estão disponíveis somente através do formato HTML.
Polimorfismo aplicado
Técnicas de orientação a objetos na prática
Além de desmistificar um dos conceitos mais interessantes da orientação a objetos, esse artigo irá discutir e propor uma metodologia para a implementação de um cenário bem comum em aplicações comercias: a integração com impressoras fiscais.
Conceitos
Chamamos de polimorfismo a capacidade de tratar objetos de tipos diferentes de uma mesma maneira, desde que eles tenham a mesma superclasse. Isso é muito comum na programação do dia-a-dia. Embora não percebamos, usamos essa abordagem constantemente, induzidos pela própria arquitetura da VCL.
Sempre que chamamos o método Free de um determinado objeto, por exemplo, estamos usando o polimorfismo para o liberarmos de forma correta. Para entendermos isso melhor, vamos recorrer ao código fonte da VCL e analisar um trecho da classe TObject, definida na unit System.pas:
TObject = class
{...}
procedure Free;
destructor Destroy; virtual;
end;
{...}
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
Como podemos ver, o método Free é estático e o "destructor" Destroy é virtual (uma explicação sobre mecanismos de chamada de métodos será vista mais à frente). O método Free verifica se a própria instância encontra-se assinalada e depois chama o Destroy. Este é normalmente reimplementado nas classes descendentes de TObject para assegurar a desalocação da memória previamente reservada por elas.
Quando chamamos o método Free, sempre será executado o comportamento codificado na classe TObject, porém com Destroy é diferente: este comportamento será o da codificação da classe corrente.
Mecanismos de chamada
No que diz respeito ao modo de chamada (dispatch), um método pode ser classificado em static, virtual ou dynamic. Vamos ver uma pequena descrição de como funciona cada um deles:
static – Esse é o padrão para todos os métodos que não especificarem um modificador. Esses métodos são linkados à referência (variável) em tempo de compilação, por isso são bem mais rápidos que os do tipo virtual ou dynamic. Por outro lado, os métodos static não podem ser redefinidos numa classe descendente. Caso declaremos um método com o mesmo nome e parâmetros que coincidam com um existente na superclasse, esse novo irá sobrepor – ou esconder – o da superclasse.
virtual – Os métodos virtuais são mais flexíveis, porém mais lentos. O endereço para o método não é determinado durante a compilação, mas durante a execução. Métodos virtuais podem ser redefinidos numa classe descendente. Cada objeto é associado a uma tabela de métodos virtuais (VMT–Virtual Method Table), que contém uma entrada para cada método virtual presente na classe e nas suas superclasses. Quando um método virtual é solicitado, é feita uma pesquisa na VMT para determinar qual implementação deve ser chamada.
dynamic – Assim como os métodos virtuais, os do tipo dynamic também podem ser redefinidos na classe descendente, ou seja, também permitem comportamento polimórfico. A diferença básica em relação aos métodos virtuais reside na forma em que é determinado o endereço da implementação correta a ser chamada. Esse endereço é consultado na ...