Cassic

Programação Orientada a Objeto

Autor: Tadeu Pereira



Conceito de POO

     A programação tradicional (estruturada) leva o programador a pensar no fluxo do programa da primeira linha de código até a ultima, fixando o foco nos programas (procedimento e funções). Já os dados são colocados em segundo plano, sendo seu manuseio de forma passível e em alguns casos retirando sua importância do contexto.


Figura 1 – Arquitetura das linguagens tradicionais

  O paradigma da programação orientada a objetos (POO) muda esse conceito, pois em vez do programador ficar pensando no fluxo do programa, ele deve analisar quais objetos estão relacionados a uma tarefa especifica e quais dados e métodos os torna único.


Figura 2 – Arquitetura da POO

  Na prótica a POO proporciona inúmeros benefícios ao desenvolvimento de sistemas, tais como uma maneira eficiente de representar elementos do mundo real para a construção desses sistemas, usando-se para isso classes e objetos. Dessa maneira a reutilização de classes e objetos, alúm da sua manutenibilidade, diminuem os efeitos causados pelas manutenções dos sistemas.

  Mas sé com o real conhecimento dos conceitos da orientação a objetos e sua utilização eficiente poderemos obter os benefícios propostos pela POO.

  - Classe: É a representação de elementos do mundo real, sendo formado, basicamente, por atributos e métodos. Um atributo é o local onde de armazenamento dos dados, enquanto um método é responsável por realizar ações sobre um ou mais atributos, tais como obter ou modificar os seus valores.

  - Objeto: É uma instância de uma classe. Para melhor entender tenha em mente uma analogia com uma variável e seu tipo, onde substituímos a variível pelo objeto e o tipo pela classe.

  - Método: É uma sub-rotina interna de uma classe, ela é responsável por executar eventos na classe, estando, dessa maneira, ligadas a mesma.

  - Evento: É uma ação, direta ou indireta, sofrida por uma classe. Um exemplo já bastante utilizado nesse curso é o evento OnClick, esse evento chama um método que tem sua funcionalidade implementada pelo programador.

  - Abstração: É a capacidade de recriar os objetos do mundo real em um programa, mas levando em consideração somente o relevante ao mesmo. Um exemplo disso seria a utilização de um objeto cliente que é baseado na idéia de uma pessoa, que por sua vez é um ser humano. Não precisamos recriar todas as características de um ser humano, mas somente o relevante ao cliente e que é de interesse do programa.

  - Encapsulamento: É a capacidade de tornar atributos e métodos de um objeto ocultos a outros objetos. Evidentemente que devem existir alguns métodos que permitam sua utilização, bastando somente saber quais são e como utilizá-los. Imagine que você está dirigindo um carro, para fazer isso você não precisa conhecer o funcionamento interno do motor, só precisa saber como e quando passa as marchas, entre outras funções.

  - Herança: É a capacidade de uma classe definida como filha receber características já existentes de outra classe definida como pai ou mãe, em outras palavras, é a classificação hierárquica existente entre classes. Para entender melhor vamos analisar o exemplo da figura 3, nele temos a classe Mamíferos que dá origem as classes Cachorros e Humanos, essas duas novas classes herdam características da classe Mamíferos mas também têm características distintas entre si. Em seguida a classe Humanos dá origem a outras duas classes, Homens e Mulheres, que herdarão caracteríticas jí definidas na classe Humanas além de terem suas próprias características. Dessa maneira cada nova classe (subclasse) tem características mais especificas do que a classe de origem (superclasse).

  - Polimorfismo: É a capacidade de classes diferentes responderem a mesma ordem, mas de maneira diferente. Ainda usando a figura 3 como exemplo, podemos ver que Homens e Cachorros são classes diferentes, mas ambos são capazes de correr, embora que o cachorro corra com as quatro patas, já o homem corre sobre os dois pés.


Figura 3 – Herança entre objetos

Exemplo de POO na Linguagem Delphi

  Crie um novo projeto, renome o Form para FPrincipal, salve a Unit com o nome de UPrincipal e o projeto com o nome de AplicacaoPOO. Selecione o menu File > New > Unit – Delphi for Win32 para cria uma nova Unit sem um formulário anexo e salve essa com o nome de UClasses.

  Na seção interface entre com o cédigo abaixo;

01
type
02
  TPessoa = class
03
    Nome: string;
04
    Fone: string;
05
    procedure Avaliar;
06
    constructor Create;
07
    destructor Destroy;
08
  end;

  Nesse código estamos usando o conceito de Abstração para criarmos uma nova classe. Como toda classe é um tipo comeéamos digitando a palavra reservada type.

  Na linha 02 iniciamos a criação da nossa classe que é finalizado com a palavra reservada end; que se encontra na linha 08.

  Nas linhas 03 e 04 declaramos dois campos (atributos) do tipo string.

  Na linha 05 foi declarado o método Avaliação e nas linhas 06 e 07 são declarados dois outros métodos extremamente importantes. O mótodo constructor cria a instância do objeto, fazendo as alocações em memória e disponibilizando o objeto para uso, dessa maneira sempre que precisarmos instanciar um objeto devemos chamar esse método. Já o método destructor faz o inverso do constructor, ele destrói o objeto instanciado liberando a memória.

Observação
  Os métodos constructor e destructor são opcionais, eles foram colocados aqui por motivos didáticos, mas eles são implementados por default, uma vez que um objeto para ser instanciado e destruído necessita desses dois métodos.

  Com o prompot dentro da declaração da classe pressione Ctrl+Shift+C e entre com o seguinte código:

01
implementation
02
 
03
uses Dialogs;
04
 
05
{ TPessoa }
06
 
07
procedure TPessoa.Avaliar;
08
begin
09
  ShowMessage('Avaliação sendo executada');
10
end;
11
 
12
constructor TPessoa.Create;
13
begin
14
  Self.Nome := 'Novo Nome';
15
  Self.Fone := 'Novo Fone';
16
end;
17
 
18
destructor TPessoa.Destroy;
19
begin
20
  Self.Nome := '';
21
  Self.Fone := '';
22
end;
23
 
24
end.

  Esse código é bem simples e praticamente dispensa explicações, o único detalhe novo que temos aqui é a palavra reservada Self, poderíamos ter atribuído valores aos campos Nome e Fone sem utilizá-la, mas para evitar ambigüidade utilizamos o Self para fazer uma referência implícita própria classe.

  Volte para o FPrincipal, declare UClasses na cláusula uses da seção implementation, coloque um componente TButton e em seu evento OnClick entre com o código abaixo, compile e teste:

01
procedure TFPrincipal.Button1Click(Sender: TObject);
02
var
03
  Aluno: TPessoa;
04
begin
05
  Aluno := TPessoa.Create;
06
  ShowMessage( Aluno.Nome +#13+ Aluno.Fone );
07
  Aluno.Nome := 'Tadeu';
08
  Aluno.Fone := '1111-1111';
09
  Aluno.Avaliar;
10
  ShowMessage( Aluno.Nome +#13+ Aluno.Fone );
11
  Aluno.Destroy;
12
end;

  Na linha 03 estamos declarando o objeto Aluno do tipo TPessoa. A linha 05 estamos instanciando o objeto Aluno. A linha 06 nos mostra o valor dos campos após o objeto ter sido instanciado. Nas linhas 07 e 08 estamos atribuindo novos valores nos campos do objeto. A linha 09 executa o método Avaliação, enquanto na linha 10 é mostrado os novos valores atribuídos aos campos.

  Vó para a UClasses e abaixo da declaração da classe TPessoa crie duas classes descendentes da mesma como mostrado no código:

01
type
02
  TPessoa = class
03
    Nome: string;
04
    Fone: string;
05
    procedure Avaliar;
06
    constructor Create;
07
    destructor Destroy;
08
  end;
09
 
10
  TAluno = class(TPessoa)
11
    Turma: string;
12
    procedure Avaliar;
13
    constructor Create;
14
    destructor Destroy;
15
  end;
16
 
17
  TProf = class(TPessoa)
18
    Disciplina: string;
19
    procedure Avaliar;
20
    constructor Create;
21
    destructor Destroy;
22
  end;

  Nesse momento aplicamos o conceito de Herança, um vez que as classes TAluno e TProf são descendentes da classe TPessoa. Em seguida use o Ctrl+Shift+C nas classes e entre com o código em negrito:

01
implementation
02
 
03
uses Dialogs;
04
 
05
{ TPessoa }
06
 
07
procedure TPessoa.Avaliar;
08
begin
09
  ShowMessage('Avaliação sendo executada');
10
end;
11
 
12
constructor TPessoa.Create;
13
begin
14
  Self.Nome := 'Novo Nome';
15
  Self.Fone := 'Novo Fone';
16
end;
17
 
18
destructor TPessoa.Destroy;
19
begin
20
  Self.Nome := '';
21
  Self.Fone := '';
22
end;
23
 
24
{ TAluno }
25
 
26
procedure TAluno.Avaliar;
27
begin
28
  ShowMessage('Respondendo a prova');
29
end;
30
 
31
constructor TAluno.Create;
32
begin
33
  Self.Nome := 'Novo Aluno';
34
  Self.Turma := 'Nova Turma';
35
end;
36
 
37
destructor TAluno.Destroy;
38
begin
39
  Self.Turma := '';
40
end;
41
 
42
{ TProf }
43
 
44
procedure TProf.Avaliar;
45
begin
46
  ShowMessage('Aplicando a prova');
47
end;
48
 
49
constructor TProf.Create;
50
begin
51
  Self.Disciplina := 'Nova Disciplina';
52
end;
53
 
54
destructor TProf.Destroy;
55
begin
56
  Self.Disciplina := '';
57
end;
58
 
59
end.

     Novamente volte para o FPrincipal, mude o evento OnClick do TButton, compile e teste:

01
procedure TFPrincipal.Button1Click(Sender: TObject);
02
var
03
  Pessoa: TPessoa;
04
  Aluno: TAluno;
05
  Prof: TProf;
06
begin
07
  // Trabalhando com o objeto Pessoa
08
  Pessoa := TPessoa.Create;
09
  ShowMessage( 'Objeto Pessoa' +#13+
10
    Pessoa.Nome +#13+ Pessoa.Fone );
11
  Pessoa.Nome := 'Tadeu';
12
  Pessoa.Fone := '1111-1111';
13
  Pessoa.Avaliar;
14
  ShowMessage( 'Objeto Pessoa' +#13+
15
    Pessoa.Nome +#13+ Pessoa.Fone );
16
  Pessoa.Destroy;
17
 
18
  // Trabalhando com o objeto Aluno
19
  Aluno := TAluno.Create;
20
  ShowMessage( 'Objeto Aluno' +#13+
21
    Aluno.Nome +#13+ Aluno.Fone +#13+ Aluno.Turma );
22
  Aluno.Nome := 'José';
23
  Aluno.Fone := '2222-2222';
24
  Aluno.Turma := 'Comp02';
25
  Aluno.Avaliar;
26
  ShowMessage( 'Objeto Aluno' +#13+
27
    Aluno.Nome +#13+ Aluno.Fone +#13+ Aluno.Turma );
28
  Aluno.Destroy;
29
 
30
  // Trabalhando com o objeto Prof
31
  Prof := TProf.Create;
32
  ShowMessage( 'Objeto Prof' +#13+
33
    Prof.Nome +#13+ Prof.Fone +#13+ Prof.Disciplina );
34
  Prof.Nome := 'Maria';
35
  Prof.Fone := '3333-3333';
36
  Prof.Disciplina := 'Linguagem II';
37
  Prof.Avaliar;
38
  ShowMessage( 'Objeto Prof' +#13+
39
    Prof.Nome +#13+ Prof.Fone +#13+ Prof.Disciplina );
40
  Prof.Destroy;
41
end;

  Note que mesmo sem termos declarado os campos Nome e Fone nas subclasses, elas herdaram esses campos da superclasse, dessa maneira a cada novo nível criada mais específico vai ficando a subclasse. O mesmo acontece com métodos que são declarados na superclasse e não o são na subclasse, mas no nosso exemplo redefinimos os métodos da superclasse, aplicando assim o conceito de Polimorfismo. Linguagem Delphi garante o funcionamento correto do método desejado através do uso das palavras reservadas mostrada a tabela.

Palavra reservada
Uso
static
Os métodos estáticos usam a implementação feita na subclasse que instância o objeto.

Por default todo método é estático.
virtual
Embora os métodos virtuais usem a implementação feita na subclasse que instância o objeto, também podem ativar a implementação da superclasse.
dynamic
Semelhante ao anterior, o que os diferencia é que no caso anterior a velocidade de acesso é otimizada, enquanto no dynamic a otimização é feita em cima do código.

Vale ressaltar que a diretiva virtual é a forma mais comum e eficiente de implementar o polimorfismo.
override
Essa diretiva garante que apenas uma implementação exista na classe descendente, ocultando as implementações das classes ancestrais.

A assinatura do método deve ser igual em todas as classes descendentes e ancestrais, isso quer dizer que os métodos devem ter o mesmo nome e os seus parâmetros devem ter o mesmo número, tipo e ordem.

Essa diretiva só pode ser usada com os métodos virtuais e dinâmicos.
overload
Essa diretiva permite que os métodos tenham assinaturas diferentes e não oculta as implementações das classes ancestrais, podendo ser usada com qualquer método – estético, virtual ou dinâmico.
reintroduce
Assim como a anterior permite que os métodos tenham assinaturas diferentes, mas nesse caso os métodos ancestrais sáo ocultados.

Essa diretiva só pode ser usada com os métodos virtuais.
abstract
Essa diretiva é usada para determinar que o método não será implementado na classe onde foi declarada. Sua implementação deverá ser feita nas classes descendentes.

Quando definimos um método como abstrato devemos ter em mente que a classe passa também a ser abstrata, não pode ser instanciada.

Essa diretiva só pode ser usada em métodos virtuais e dinâmicos.
final
O uso dessa diretiva impede que classes descendentes redefinam métodos ancestrais.
inherited
Essa diretiva é usada para fazer uma chamada ao método ancestral e reaproveitar sua funcionalidade.
Tabela 1 – Palavras reservadas para uso com métodos ancestrais e descendentes

  Vamos tornar os métodos da nossa superclasse em métodos virtuais:

01
unit UClasses;
02
 
03
interface
04
 
05
type
06
  TPessoa = class
07
    Nome: string;
08
    Fone: string;
09
    procedure Avaliar; virtual;
10
    constructor Create; virtual;
11
    destructor Destroy; virtual;
12
  end;
13
 
14
  TAluno = class(TPessoa)
15
    Turma: string;
16
    procedure Avaliar; override;
17
    constructor Create; override;
18
    destructor Destroy; override;
19
  end;
20
 
21
  TProf = class(TPessoa)
22
    Disciplina: string;
23
    procedure Avaliar; override;
24
    constructor Create; override;
25
    destructor Destroy; override;
26
  end;
27
 
28
implementation
29
 
30
uses Dialogs;
31
 
32
{ TPessoa }
33
 
34
procedure TPessoa.Avaliar;
35
begin
36
  ShowMessage('Avaliação sendo executada');
37
end;
38
 
39
constructor TPessoa.Create;
40
begin
41
  Self.Nome := 'Novo Nome';
42
  Self.Fone := 'Novo Fone';
43
end;
44
 
45
destructor TPessoa.Destroy;
46
begin
47
  Self.Nome := '';
48
  Self.Fone := '';
49
end;
50
 
51
{ TAluno }
52
 
53
procedure TAluno.Avaliar;
54
begin
55
  inherited;
56
  ShowMessage('Respondendo a prova');
57
end;
58
 
59
constructor TAluno.Create;
60
begin
61
  inherited;
62
  Self.Turma := 'Nova Turma';
63
end;
64
 
65
destructor TAluno.Destroy;
66
begin
67
  Self.Turma := '';
68
  inherited;
69
end;
70
 
71
{ TProf }
72
 
73
procedure TProf.Avaliar;
74
begin
75
  inherited;
76
  ShowMessage('Aplicando a prova');
77
end;
78
 
79
constructor TProf.Create;
80
begin
81
  inherited;
82
  Self.Disciplina := 'Nova Disciplina';
83
end;
84
 
85
destructor TProf.Destroy;
86
begin
87
  Self.Disciplina := '';
88
  inherited;
89
end;
90
 
91
end.

  Vemos uma das vantagens da POO, mudamos as classes mas não precisamos mudar nada no FPrincipal, para as alterações entrarem em vigor apenas compile e teste.

  O código a seguir transforma a superclasse TPessoa em uma classe abstrata, obrigando as subclasses TAluno e TProf a implementar o método abstrato:

01
type
02
  TPessoa = class
03
    Nome: string;
04
    Fone: string;
05
    procedure Avaliar; virtual;
06
    procedure Lancar_Nota; virtual; abstract;
07
    constructor Create; virtual;
08
    destructor Destroy; virtual;
09
  end;
10
 
11
  TAluno = class(TPessoa)
12
    Turma: string;
13
    procedure Avaliar; override;
14
    procedure Lancar_Nota; override;
15
    constructor Create; override;
16
    destructor Destroy; override;
17
  end;
18
 
19
  TProf = class(TPessoa)
20
    Disciplina: string;
21
    procedure Avaliar; override;
22
    procedure Lancar_Nota; override;
23
    constructor Create; override;
24
    destructor Destroy; override;
25
  end;

  Pressione Crtl+Shift+C dentro das classes TAluno e TProf, em seguida entre com código mostrado:

01
procedure TAluno.Lancar_Nota;
02
var
03
  Nota: string;
04
begin
05
  InputQuery('Nota', 'Qual foi a nota?', Nota);
06
end;
07
 
08
procedure TProf.Lancar_Nota;
09
var
10
  Aluno, Nota: string;
11
begin
12
  InputQuery('Aluno', 'Nome do aluno?', Aluno);
13
  InputQuery('Nota', 'Qual foi a nota do aluno ' +
14
    Aluno + '?', Nota);
15
end;

     Mude o evento OnClick do TButton que está FPrincipal, compile, teste e verifique o erro que dá:

01
procedure TFPrincipal.Button1Click(Sender: TObject);
02
var
03
  Pessoa: TPessoa;
04
  Aluno: TAluno;
05
  Prof: TProf;
06
begin
07
  // Trabalhando com o objeto Pessoa
08
  Pessoa := TPessoa.Create;
09
  ShowMessage( 'Objeto Pessoa' +#13+
10
    Pessoa.Nome +#13+ Pessoa.Fone );
11
  Pessoa.Nome := 'Tadeu';
12
  Pessoa.Fone := '1111-1111';
13
   Pessoa.Avaliar;
14
  Pessoa.Lancar_Nota;
15
  ShowMessage( 'Objeto Pessoa' +#13+
16
    Pessoa.Nome +#13+ Pessoa.Fone );
17
  Pessoa.Destroy;
18
 
19
  // Trabalhando com o objeto Aluno
20
  Aluno := TAluno.Create;
21
  ShowMessage( 'Objeto Aluno' +#13+
22
    Aluno.Nome +#13+ Aluno.Fone +#13+ Aluno.Turma );
23
  Aluno.Nome := 'José';
24
  Aluno.Fone := '2222-2222';
25
  Aluno.Turma := 'Comp02';
26
  Aluno.Avaliar;
27
  Aluno.Lancar_Nota;
28
  ShowMessage( 'Objeto Aluno' +#13+
29
    Aluno.Nome +#13+ Aluno.Fone +#13+ Aluno.Turma );
30
  Aluno.Destroy;
31
 
32
  // Trabalhando com o objeto Prof
33
  Prof := TProf.Create;
34
  ShowMessage( 'Objeto Prof' +#13+
35
    Prof.Nome +#13+ Prof.Fone +#13+ Prof.Disciplina );
36
  Prof.Nome := 'Maria';
37
  Prof.Fone := '3333-3333';
38
  Prof.Disciplina := 'Linguagem II';
39
  Prof.Avaliar;
40
  Prof.Lancar_Nota;
41
  ShowMessage( 'Objeto Prof' +#13+
42
    Prof.Nome +#13+ Prof.Fone +#13+ Prof.Disciplina );
43
  Prof.Destroy;
44
end;

     A classe TPessoa não poderia ter sido instanciado pois ela é uma classe abstrata, mas caso se deseje utilizá-la e desprezar a regra de náo poder instanciar uma classe abstrata, basta comentar a linha 14 com a barra dupla.

     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;

     Para finalizar vamos muda o código do evento OnClick do TButton que está no FPrincipal, em seguida compile e teste:

01
procedure TFPrincipal.Button1Click(Sender: TObject);
02
var
03
  Aluno: TAluno;
04
  Prof: TProf;
05
begin
06
  // Trabalhando com o objeto Aluno
07
  Aluno := TAluno.Create;
08
  ShowMessage( 'Objeto Aluno' +#13+
09
      Aluno.Nome +#13+ Aluno.GetFone +#13+ Aluno.Turma );
10
  Aluno.Nome := 'José';
11
  Aluno.SetFone('2222-2222');
12
  Aluno.Turma := 'Comp02';
13
  Aluno.Avaliar;
14
  Aluno.Lancar_Nota;
15
  ShowMessage( 'Objeto Aluno' +#13+
16
      Aluno.Nome +#13+ Aluno.GetFone +#13+ Aluno.Turma );
17
  Aluno.Destroy;
18
 
19
  // Trabalhando com o objeto Prof
20
  Prof := TProf.Create;
21
  ShowMessage( 'Objeto Prof' +#13+
22
      Prof.Nome +#13+ Prof.GetFone +#13+ Prof.Disciplina +#13+
23
          Prof.Curso );
24
  Prof.Nome := 'Maria';
25
  Prof.SetFone('3333-3333');
26
  Prof.Disciplina := 'Linguagem II';
27
  Prof.Curso := 'Análise';
28
  Prof.Avaliar;
29
  Prof.Lancar_Nota;
30
  ShowMessage( 'Objeto Prof' +#13+
31
      Prof.Nome +#13+ Prof.GetFone +#13+ Prof.Disciplina +#13+
32
          Prof.Curso );
33
  Prof.Destroy;
34
end;