Desenvolvimento - Delphi

Delphi: Programação Orientada à Objetos - Parte 02

Estamos de volta com mais um artigo, dando continuidade com o assunto: Orientação a Objetos em Delphi.

por Daniel Nascimento



Olá pessoal...

Estamos de volta com mais um artigo, dando continuidade com o assunto: Orientação a Objetos em Delphi.

Antes de iniciar, gostaria de agradecer todos os e-mails enviados a mim, e deixar claro que estarei respondendo a todos os e-mails assim que possível. Também gostaria de agradecer os comentários e considerações deixadas na página no primeiro artigo...

Agora vamos ao que interessa...

Semana passada falei sobre as principais propriedades da POO: encapsulamento, polimorfismo e herança, caso tenham alguma dúvida sobre o assunto, recorra a coluna anterior ou enviem-me um e-mail.

A coleção de objetos que possuem as mesmas características e propriedades recebe o nome de classe. Uma classe pode ser comparada a uma espécie sofisticada de tipo de dados, sendo assim, sua declaração exige a presença da palavra
type, além da inclusão dos atributos (campos) e métodos (operações). Veja o exemplo da declaração de uma classe abaixo.

unit Exemplo_Classe;

interface

implementation

type
T_Pessoa = (Fisica, Juridica);

Pessoa = Class
//Declaração dos atributos.
Nome, Endereco, Cidade, Estado, Telefone: String;
CodigoID, CEP: Integer;
TPessoa = T_Pessoa;
//Declaração dos Procedimentos e Funções.
function Inserir(CodigoID: Integer; Nome, Endereco, Cidade, Estado, Telefone: String;
TPessoa: T_Pessoa): Integer;
function Excluir(CodigoID: Integer): Integer;
function Alterar(CodigoID: Integer; Nome, Endereco, Cidade, Estado, Telefone: String; TPessoa: T_Pessoa): Integer;
procedure Pesquisar(Nome: String);
end;

end.

Pessoa *

+ Nome, Endereço, Cidade, Telefone: String
CodigoID, CEP: Integer
+ TPessoa: T_Pessoa

+ function Inserir (CodigoID: Integer; Nome, Endereco, Cidade, Estado, Telefone: String
+ function Alterar (CodigoID: Integer; Nome, Endereco, Cidade, Estado, Telefone: String
+ function Excluir (CodigoID: Integer): Integer
+ procedure Pesquisar (Nome: String)

* Diagrama de Classes da Classe Pessoa (UML).


No Delphi, quando
não for informado o nome da classe-pai da qual sua classe deriva, a nova classe será derivada da classe TObject, sendo sua declaração opcional, classe pai (superclasse) de toda e qualquer classe criada.
Uma propriedade, como um campo, define um atributo para um objeto. Mas, como um campo é somente um local para armazenamento cujo conteúdo pode ser examinado e modificado, uma propriedade associa ações específicas à leitura ou alteração de seus dados. Estas oferecem controle sobre acesso aos atributos de um objeto e permitem que atributos possam ser calculados1. A declaração de uma propriedade especifica um nome e um tipo, e inclui pelo menos um especificador de acesso. Sua sintaxe é:

property NomePropriedade[índices]: TipoPropriedade ÍndiceConstanteInteira Especificadores;

Onde:
NomePropriedade: é um identificador válido.
[índices]: é opcional, e é uma seqüência de declarações de parâmetros separados por vírgula.
TipoPropriedade: precisa ser um tipo pré-definido ou previamente declarado.
ÍndiceConstanteInteira: é opcional.
Especificadores: são uma seqüência de read, write, stored, default. Cada propriedade precisa ter pelo menos um especificador read ou write.
Read: indica como será obtido o valor da propriedade. Pode ser através da leitura do valor de um campo (read fNomeCampo) ou calculado1 através de uma função que retorne um valor do mesmo tipo da propriedade (read NomeFunção).
Write: indica como será alterado o valor do campo associado à propriedade. Pode ser uma escrita no campo (write fNomeCampo) ou a execução de um procedimento a fim de calcular1 o campo (write NomeProcedimento).

Veremos agora sobre a declaração dos métodos. Estas podem usar diretivas que não são usadas por outras funções ou procedimentos. Diretivas devem aparecem somente na declaração da classe, não na implementação do método e devem obedecer sempre a seguinte ordem.

reintroduce; overload; amarração(binding); ConvençãoDeChamada (calling convention); abstract;
advertência
(warning);

Onde:
amarração (binding): é virtual, dynamic ou override.
ConverçãoDeChamada: é register, Pascal, cdecl, stdcall ou safecall.
advertência (warning): é platform, deprecated ou library.

Bem... vamos detalhar um pouco mais as características acima.

Na amarração (binding) use virtual ou dynamic na classe pai, (superclasse imediatamente superior) quanto estiver declarando um método que poderá ser modificado nas classes herdadas. Nesta classe, o método deverá ser redeclarado usando a diretiva override. Porém, se numa classe descendente, uma declaração de método especificar o mesmo identificador e a mesma assinatura de um método virtual existente na superclasse, e não incluir a palavra override, a nova declaração irá ocultar o método herdado, sem sofrer alterações, ou seja, os dois métodos existirão na classe descendente.

Você pode estar pensando, então a amarração, nada mais é do que uma técnica de polimorfismo! Muito cuidado neste momento, pois no polimorfismo as assinaturas dos métodos diferem em tipos e/ou quantidade. Portando amarração e polimorfismo são diferentes!

Já a diretiva reintroduce, oculta as mensagens do compilador sobre os métodos virtuais declarados na superclasse. Melhorando este conceito, use reintroduce quando desejar que um novo método da classe descendente oculte o método virtual herdado.

Um método abstrato é também um método virtual ou dinâmico que não possui implementação na classe onde foi declarado, sua implementação é delegada para a classe descendente. É exatamente isto... Na superclasse ficará somente o método com sua assinatura e a declaração abstract. Particularmente, utilizo muito dessa diretiva. Ao longo do tempo exploraremos toda sua utilidade.

E por fim vamos falar da diretiva overload. Utilizamos esta diretiva quando o método redeclarado tiver uma lista de parâmetros diferente da declaração na superclasse. Sendo assim, a nova classe irá sobrecarregar o método herdado, sem ocultá-lo. Se você sobrecarregar um método virtual, use a diretiva reintroduce para redeclará-los nas classes descendentes.

Estamos chegando ao fim de nossos artigos sobre POO. Semana que vem, falarei sobre construtores e destrutores, e opções de visibilidade.

Antes de terminar este artigo, gostaria de agradecer a todos os leitores, e também as pessoas que deixaram seus comentários e enviaram e-mails contendo sugestões, dúvidas e críticas. E comentar, que por esta parte ser muito teórica, estarei citando somente alguns trechos de códigos para focar um assunto de maior importância.

Não se esqueçam de procurar mais informações sobre a POO.

Um abraço a todos, e até semana que vêm.

________________________________
1 - Ao referenciar a palavra calculado, seu significado não implica no fato do cálculo literal de uma variável, e sim, ao referenciar o verbo calcular, refiro-me ao processo de obtenção do valor de uma variável, seja, o próprio cálculo, seja através de outros meios, como por exemplo funções ou o método OnCalcFields de um objeto TQuery.

OBS.: Não me preocupei com a implementação dos procedimentos e funções do trecho de código acima. Deixo-o como exercício para você, leitor.

Daniel Nascimento

Daniel Nascimento - Trabalha com Delphi a 3 anos desde a versão 5.0. Atualmente é Analista/Desenvolvedor de aplicações cliente/servidor e aplicações multicamadas com acesso a banco de dados SQL Server e Oracle.