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. |
* 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.