Herança e métodos virtuais

Herança, métodos virtuais, override, reintroduce

Exemplo de herança de classe

O Object Pascal suporta herança e métodos virtuais. No exemplo abaixo, TDog herda de TAnimal:

TDog é a subclasse (classe derivada), TAnimal é a superclasse (classe pai)

program AnimalDemo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses SysUtils;

type
  // Superclasse dos animais
  TAnimal = class
    procedure Cry; virtual; // Método virtual: som do animal
  end; // Fim da definição da classe, apenas end;

  // Subclasse Cachorro, herda Animal e sobrescreve o som
  TDog = class(TAnimal)
    procedure Cry; override;
  end;

procedure TAnimal.Cry;
begin
  WriteLn('O animal emite um som');
end;

procedure TDog.Cry;
begin
  WriteLn('Au au au');
end;

var
  Pet: TAnimal;
begin
  // Instância da superclasse
  Pet := TAnimal.Create;
  try
    Pet.Cry;
  finally
    FreeAndNil(Pet);
  end;

  // Instância da subclasse armazenada em variável da superclasse, polimorfismo ativado
  Pet := TDog.Create;
  try
    Pet.Cry;
  finally
    FreeAndNil(Pet);
  end;
end.Code language: JavaScript (javascript)

Resultado da execução

D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
45 lines compiled, 0.1 sec, 68544 bytes code, 4260 bytes data

D:\fpcdemo>mydemo
O animal emite um som
Au au auCode language: CSS (css)

FreeAndNil

Liberação segura de objetos, combina duas ações em uma:

  1. Chamar o método Free do objeto para liberar memória;
  2. Atribuir nil à variável para evitar ponteiros pendentes.

O código acima guarda um objeto da subclasse TDog dentro de uma variável do tipo TAnimal chamada Pet. Ao chamar Cry através de Pet, é executado o método Cry da TDog e não o da TAnimal, esse conceito é o polimorfismo.

  • Cry; virtual marca o método da classe pai como virtual e habilita o polimorfismo em tempo de execução;
  • A subclasse sobrescreve Cry usando o modificador override;
  • A variável é declarada como TAnimal mas contém um objeto real do tipo TDog, executando automaticamente o latido do cachorro.

Métodos marcados com virtual: o compilador resolve a implementação correspondente no tempo de execução com base no tipo real do objeto.

Se remover virtual e override

As duas chamadas executarão o método da classe pai

A imagem acima é o resultado após excluir virtual e override

Toda a saída vem da implementação da TAnimal

O compilador reconhece apenas o tipo declarado da variável TMyClass e ignora o tipo real do objeto em tempo de execução.

  • Métodos comuns não são virtuais por padrão, apenas com o modificador virtual se tornam virtuais;
  • É obrigatório usar override ao redefinir um método virtual herdado na subclasse, caso contrário o compilador emitirá aviso;
  • Use reintroduce se quiser ocultar um método virtual homônimo da classe pai sem sobrescrevê-lo (não recomendado, causa confusão), equivalente à palavra-chave new do C#

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *