Guia Delphi

Introdução à POO - Partes 3 e 4

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (2)  (0)

Artigo da Revista Clube Delphi Edição 111.

[links]Introdução à POO - Partes 1 e 2
Introdução à Poo - Partes 5 e 6[/links][rotulo-curso/]

Introdução à POO - Parte 3

Atenção: esse artigo tem uma palestra complementar. Clique e assista!

[lead]Do que trata o artigo

Este artigo aborda a orientação a objetos com o Delphi, usando uma metodologia simples, didática, de fácil aprendizado. Veremos na teoria, e também na prática, todos os conceitos, fundamentos e recursos oferecidos pelo Delphi para promover a POO.

Para que serve

A POO pode e deve ser aplicada de forma inteligente, ela serve para construir sistemas mais robustos, mais confiáveis, de fácil manutenção, que permitam maior reaproveitamento de código.

Em que situação o tema é útil

A POO é útil em qualquer sistema, seja ele Web, Desktop, Mobile, não importa o tipo de aplicação. Os conceitos aqui apresentados, em um exemplo simples, podem ser utilizados em aplicações reais, como é apresentado em um estudo de caso no final desta série.

Resumo do DevMan

Neste artigo aprenderemos mais sobre métodos virtuais e polimorfismo, dando um passo além, estudando métodos abstratos. Também examinaremos o que são construtores e destrutores. Entendermos o que são e para que servem os especificadores de visibilidade (modificadores) public, protected e private. Criaremos propriedades para nossas classes e reforçaremos princípios básicos de encapsulamento. E finalmente, entenderemos o que são métodos get / set. [/lead]

Nas partes anteriores deste mini-curso, aprendemos importantes técnicas da orientação a objetos com o Delphi. Vimos como criar classes, aplicar a herança (TCarro e TAviao agora herdam de TMeioTransporte), vimos como criar métodos virtuais e aplicar o polimorfismo, como sobrescrever métodos virtuais e chamar funcionalidades da classe base com inherited. Nesta terceira parte do nosso curso, vamos avançar mais na orientação a objetos, chegando em um nível muito próximo de aplicações reais, inclusive fazendo novamente comparações com o design de classes da VCL.

[subtitulo]Métodos abstratos[/subtitulo]

Se lembrar da última parte do curso, implementamos no método Mover a funcionalidade básica para todos os meios de transporte, que é o ato de ligar. Mas imagine o seguinte: e se cada meio de transporte for ligado de uma forma? O que é comum nesse caso é a chamada do método, ou seja, todos devem ser ligados antes de entrar em movimento. O que muda é a maneira como são ligados (já viu que vamos falar de polimorfismo novamente). Então altere o código do método Mover da classe TMeioTransporte como mostrado na Listagem 1.

Listagem 1. Comportamento básico para todos os meios de transporte

  procedure TMeioTransporte.Mover();
  begin
    Ligar();
  end; 

Isso diz que um meio de transporte deve ser ligado sempre que entrar em movimento (tudo bem que na vida real não seja exatamente assim, mas para fins didáticos, está bom). Agora declare o método Ligar na interface da classe TMeioTransporte (Listagem 2).

Listagem 2. Método abstrato

  unit uMeioTransporte;
   
  interface
   
  type
    TMeioTransporte = class
      Descricao : string;
      Capacidade : integer;
      procedure Mover; virtual;
      procedure Ligar; virtual; abstract;
    end;
   
  implementation
   
  { TMeioTransporte }
   
  uses
    Dialogs;
   
  procedure TMeioTransporte.Mover;
  begin
    ShowMessage('Ligando ' + Descricao);
  end;
   
  end. 

Abstract é sempre usado junto da diretiva virtual e indica que o método não possui implementação na classe em que é declarado (algo muito semelhante a uma interface, técnicas que discutiremos adiante neste curso). Ligar não é implementado nessa classe, ou seja, ele é totalmente abstrato, só possui a definição para poder ser chamado (no método Mover). Ou seja, sabemos que todos os meios de transporte são ligados antes de entrar em movimento, então podemos fazer essa chamada na classe base para não precisar fazer isso em todas as classes descendentes. Todos os TMeioTransporte são ligados antes de mover, mas são ligados de forma diferente, novamente, polimorfismo. Um carro é ligado com chave, um avião..., bom deixa pra lá.

Nota: Em uma situação real, por exemplo, poderíamos ter um cadastro base que tem um método polimórfico chamado Gravar. Sabemos que antes de Gravar dados no BD precisamos sempre Validar as informações, mas essa validação vai depender das classes concretas descendentes. Validamos um cliente de uma forma, um produto de outra, e assim por diante. Então, poderíamos ter uma classe base chamada TCadastro que possui um método virtual chamado Gravar, que sempre chama Validar, que por sua vez é abstrato. Nunca mais precisamos chamar o Validar, apenas implementar.

Usando recursos de polimorfismo vamos sobrescrever o Ligar na classe descendente. Abra a classe TCarro e sobrescreva o método Ligar e o implemente como na Listagem 3. Fazemos o mesmo para a classe TAviao (Listagem 4).

Listagem 3. Sobrescrevendo um método virtual e abstrato: TCarro

  unit uCarro;
   
  interface
   
  uses
    // coloque essa unit p/ acessar a classe TMeioTransporte
    uMeioTransporte;
   
  type
   // observe que TCarro agora herda de TMeioTransporte
    TCarro = class(TMeioTransporte)
    // observe que retiramos os campos Capacidade e Descricao daqui
      Quilometragem : integer;
      procedure Mover(); override;
      procedure Ligar(); override;
    end;
   
  implementation
   
  uses Dialogs;
  { TCarro }
   
  procedure TCarro.Ligar();
  begin
    // repare que não vai inherited aqui
    // pois não existe nada na classe base
    ShowMessage('Ligando o carro ' + Descricao);
  end;
   
  procedure TCarro.Mover();
  begin
    inherited; // isso vai chamar o Ligar
    ShowMessage(Descricao + ' entrou em movimento.');
  end;
   
  end. 

Listagem 4. Sobrescrevendo um método virtual e abstrato: TAviao

  unit uAviao;
   
  interface
   
  uses
    // coloque essa unit p/ acessar a classe TMeioTransporte
    uMeioTransporte;
   
  type
   // observe que TAviao agora herda de TMeioTransporte
    TAviao = class(TMeioTransporte)
    // observe que retiramos os campos Capacidade e Descricao daqui
      HorasVoo : integer;
      procedure Mover(); override;
      procedure Ligar(); override;
    end;
   
  implementation
   
  uses Dialogs;
  { TAviao }
   
  procedure TAviao.Ligar();
  begin
    // repare que não vai inherited aqui
    // pois não existe nada na classe base
    ShowMessage('Ligando o aviao '+Descricao);
  end;
   
  procedure TAviao.Mover();
  begin
    inherited; // isso vai chamar o Ligar
    ShowMessage(Descricao+' está voando.');
  end;
   
  end.
   
  E na classe base, TMeioTransporte, simplesmente chamamos o Ligar:
   
  procedure TMeioTransporte.Mover();
  begin
    Ligar();
  end; 

Vamos executar a aplicação agora e ver como tudo isso vai funcionar. No form principal preencha os Edits e crie um carro. Veja o que acontece passo a passo:

1 – Ao clicar no botão Mover, será chamado o Mover da classe TMeioTransporte. Como esse método é virtual, ele identifica o método pela instância criada e não pelo tipo declarado, logo será chamado Mover de TCarro;

2 – Mover de TCarro faz uma chamada à inherited o que invoca o método de mesmo nome na classe base, "

A exibição deste artigo foi interrompida :(
Este post está disponível para assinantes MVP

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?