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/