Programação
Orientada a Objeto - Parte V
Um
exemplo prático em Delphi
Exemplo de POO na Linguagem Delphi (cont.)
Iremos agora implementar o conceito de Encapsulamento nas nossas classes, em outras palavras, vamos deixar as nossas classes com o mínimo de funcionalidade visível, mas elas devem ter fácil acoplamento e uma interface acessível. Para os puristas de POO, todos os campos e alguns métodos não podem ser acessados diretamente do meio da classe. Classes e objetos distintos só terão acesso a alguns métodos que permitam a interação com os mesmos. Para isso a Linguagem Delphi implementa níveis de visibilidade dentro da classe.
Palavra reservada |
Visibilidade |
private |
Os campos e métodos declarados nesse escopo só são acessíveis pela classe a qual pertencem e pelas classes “amigas”. Classes “amigas” são as classes definidas na mesma Unit. |
strict private |
Semelhante ao anterior, só que nesse caso é vetado o acesso das classes “amigas” |
protected |
Esse escopo define que os campos e métodos nele declarados são acessíveis pela própria classe e por seus descendentes, além das classes “amigas”. |
strict protected |
Semelhante ao anterior, só que nesse caso é vetado o acesso das classes “amigas”. |
puclic |
Define que os campos e métodos sejam acessíveis por qualquer classe. |
published |
A visibilidade dos campos e métodos desse escopo são semelhantes ao anterior, a diferença é que os mesmos são publicados no Object Inspector. |
automated |
Também semelhante ao public, mas nesse caso são geradas informações de tipo automático (automation type information) normalmente usados em classes Windows. Os Automation Objects que permitem trabalhar com objetos de aplicações como Word e Excel são exemplos de automated. |
Tabela 2 – Níveis de visibilidade dos campos e métodos da classe.
Modifique as classes para podemos incorporar os níveis de visibilidade recomendada pela Encapsulamento.
01 |
type |
02 |
TPessoa = class |
03 |
private |
04 |
FNome: string; |
05 |
FFone: string; |
06 |
public |
07 |
procedure Avaliar; virtual; |
08 |
procedure Lancar_Nota; virtual; abstract; |
09 |
procedure SetFone(pNome: string); |
10 |
function GetFone: string; |
11 |
constructor Create; virtual; |
12 |
destructor Destroy; virtual; |
13 |
published |
14 |
property Nome: string |
15 |
read FNome write FNome; |
16 |
end; |
17 |
|
18 |
TAluno = class(TPessoa) |
19 |
private |
20 |
FTurma: string; |
21 |
public |
22 |
procedure Avaliar; override; |
23 |
procedure Lancar_Nota; override; |
24 |
procedure SetTurma(pTurma: string); |
25 |
function GetTurma: string; |
26 |
constructor Create; override; |
27 |
destructor Destroy; override; |
28 |
published |
29 |
property Turma: string |
30 |
read GetTurma write SetTurma; |
31 |
end; |
32 |
|
33 |
TProf = class(TPessoa) |
34 |
private |
35 |
FDisciplina: string; |
36 |
FCurso: string; |
37 |
public |
38 |
procedure Avaliar; override; |
39 |
procedure Lancar_Nota; override; |
40 |
procedure SetDisciplina(pDisciplina:
string); |
41 |
function GetCurso: string; |
42 |
constructor Create; override; |
43 |
destructor Destroy; override; |
44 |
published |
45 |
property Disciplina: string |
46 |
read FDisciplina write SetDisciplina; |
47 |
property Curso: string |
48 |
read GetCurso write FCurso; |
49 |
end; |
Implementamos os níveis de acesso private, public e published nas três classes, note que os campos mudaram de nome (foi incluída letra F no seu inicio), além da inclusão de um novo campo na classe TProf. Isso obriga a alteração dos nomes dos campos em todas as partes das classes, mas essas alterações só devem ser feitas dentro da UClasses, no momento não mude nada na UPrincipal.
Todos os campos foram implementados com visibilidade private, dessa maneira foi atendido uma exigência do encapsulamento que diz “nenhum campo pode ser acessado diretamente”.
Os métodos foram colocados com visibilidade public, pois todos os métodos apresentados são usados como ponto de acoplamento entre a classe e outras classes e objetos. Foram criados novos métodos do tipo Get e Set, esses métodos servem para ler e escrever, respectivamente, dados de um campo dentro da classe.
Na visibilidade published temos outra forma de manipulação de campo que pode ser usada na Linguagem Delphi, as propriedades. Uma propriedade pode realizar leitura e escrita num campo de forma “indireta”. Declaramos nas linhas 14 e 15 a propriedade Nome que ler(write) e escreve(get) dados no campo FNome da classes TPessoa. Foram declaradas propriedades mesclando o uso dos Gets e Sets.
Observação |
Caso se deseje cria uma propriedade de somente leitura (read-only) basta omitir a diretiva write, se for o caso de se ter uma propriedade de somente gravação (write-only) omita a diretiva read. |
Segue as mudanças acontecidas na seção implementation da UClasses:
001 |
{
TPessoa } |
002 |
|
003 |
procedure
TPessoa.Avaliar; |
004 |
begin |
005 |
ShowMessage('Avaliação sendo executada'); |
006 |
end; |
007 |
|
008 |
constructor
TPessoa.Create; |
009 |
begin |
010 |
Self.FNome := 'Novo Nome'; |
011 |
Self.FFone := 'Novo Fone'; |
012 |
end; |
013 |
|
014 |
destructor
TPessoa.Destroy; |
015 |
begin |
016 |
Self.FNome := ''; |
017 |
Self.FFone := ''; |
018 |
end; |
019 |
|
020 |
procedure
TPessoa.SetFone(pNome: string); |
021 |
begin |
022 |
FFone := pNome; |
023 |
end; |
024 |
|
025 |
function TPessoa.GetFone:
string; |
026 |
begin |
027 |
Result := FFone; |
028 |
end; |
029 |
|
030 |
{
TAluno } |
031 |
|
032 |
procedure
TAluno.Avaliar; |
033 |
begin |
034 |
inherited; |
035 |
ShowMessage('Respondendo a prova'); |
036 |
end; |
037 |
|
038 |
constructor
TAluno.Create; |
039 |
begin |
040 |
inherited; |
041 |
Self.FTurma := 'Nova Turma'; |
042 |
end; |
043 |
|
044 |
destructor
TAluno.Destroy; |
045 |
begin |
046 |
Self.FTurma := ''; |
047 |
inherited; |
048 |
end; |
049 |
|
050 |
procedure
TAluno.Lancar_Nota; |
051 |
var |
052 |
Nota: string; |
053 |
begin |
054 |
InputQuery('Nota', 'Qual foi a nota?',
Nota); |
055 |
end; |
056 |
|
057 |
procedure
TAluno.SetTurma(pTurma: string); |
058 |
begin |
059 |
FTurma := pTurma; |
060 |
end; |
061 |
|
062 |
function TAluno.GetTurma:
string; |
063 |
begin |
064 |
Result := FTurma; |
065 |
end; |
066 |
|
067 |
{
TProf } |
068 |
|
069 |
procedure
TProf.Avaliar; |
070 |
begin |
071 |
inherited; |
072 |
ShowMessage('Aplicando a prova'); |
073 |
end; |
074 |
|
075 |
constructor
TProf.Create; |
076 |
begin |
077 |
inherited; |
078 |
Self.FDisciplina := 'Nova Disciplina'; |
079 |
Self.FCurso := 'Novo Curso'; |
080 |
end; |
081 |
|
082 |
destructor
TProf.Destroy; |
083 |
begin |
084 |
Self.FDisciplina := ''; |
085 |
Self.FCurso := ''; |
086 |
inherited; |
087 |
end; |
088 |
|
089 |
procedure
TProf.Lancar_Nota; |
090 |
var |
091 |
Aluno, Nota: string; |
092 |
begin |
093 |
InputQuery('Aluno', 'Nome do aluno?',
Aluno); |
094 |
InputQuery('Nota', 'Qual foi a nota do
aluno ' + |
095 |
Aluno + '?', Nota); |
096 |
end; |
097 |
|
098 |
procedure
TProf.SetDisciplina(pDisciplina: string); |
099 |
begin |
100 |
FDisciplina := pDisciplina; |
101 |
end; |
102 |
|
103 |
function TProf.GetCurso:
string; |
104 |
begin |
105 |
Result := FCurso; |
106 |
end; |
Este artigo foi cedido por http://www.cassic.com.br/ |