Professional Documents
Culture Documents
Apostila de
Programação Orientada a Objetos
Classes e Objetos
Este é um exemplo bem simples, mas imagine que você necessitasse das funções de um
cronômetro. Você não sabe (e também não tem interesse em saber) como um cronômetro
funciona internamente. Você está preocupado com os resultados que um objeto do tipo
cronômetro pode lhe fornecer, apenas apertando os botões corretos.
Neste momento você é um cliente do cronômetro e o enxerga como uma caixa preta,
interagindo com ele através dos botões, mas não se preocupando com as engrenagens ou
circuitos internos que possibilitam seu funcionamento.
Esta característica que isola os detalhes internos de implementação do cliente (usuário) de um
objeto chama-se encapsulamento.
Exercício 1
Coloque um segundo objeto de contador, adicionando à interface os botões necessários.
Os atributos (variáveis) e serviços (funções) de uma classe são conhecidos como membros.
Se você vai se utilizar apenas de uma classe, sendo sua cliente, basta conhecer quais as
funções-membro que são públicas, ou seja, que formam o protocolo daquela classe. Como
resultado do encapsulamento, não é necessário conhecer outras funções-membro internas ou
variáveis-membro. Exemplo de implementação: membros.dpr
Construtores
A declaração de uma variável do tipo objeto apenas cria um ponteiro para o objeto
correspondente, que vai ser instanciado mais tarde. Quando for necessário utilizar este objeto
pela primeira vez, deve-se chamar explicitamente seu construtor. A partir deste momento, o
objeto está pronto para ser utilizado.
O programador pode determinar o conteúdo da função construtora, porém sempre deve fazer
uma chamada explícita ao construtor da classe ancestral imediata. Não há restrições em
funções construtoras e elas podem executar uma vasta gama de ações iniciais tanto na classe
quanto nos seus membros constituintes. Aqui estão algumas das ações típicas de inicialização:
• criar outros objetos;
• atribuir valores específicos a variáveis-membro;
• executar programa de inicialização de máquina ou dispositivo;
• abrir arquivos;
• chamar outras funções .
Esta lista não encerra todas as possibilidades. Exemplo de implementação: funcion.dpr
Exercício 3
Modifique os construtores implementados para que eles também recebam o nome.
Destrutores
Exercício 5
Sobre o exemplo Alcatraz, implemente uma segunda prisão colocando também os
componentes de interface necessários.
Imagine que em algum de seus programas você esteja precisando de alguma coisa que
armazenasse valores de uma forma LIFO (last in first out) , como por exemplo uma pilha.
Nesta pilha seriam armazenados e retirados valores, além de se querer saber se a pilha está
vazia, se está cheia e qual é o elemento que está no seu topo. Empilha, Desempilha, Vazia,
Cheia e MostraTopo são as operações desejadas.
Para implementar este requisito, você possui duas maneiras na programação tradicional:
a primeira é criar uma estrutura de dados que comporte a pilha (como por exemplo um vetor e
um indicador de topo) e cada ponto do programa que necessite armazenar ou retirar elementos
pode atuar diretamente sobre esta estrutura de dados. Porém, não há garantias de que todos os
pontos vão trabalhar corretamente. Além de haver o mesmo código (ou códigos similares) em
vários pontos. Exemplo de implementação: pilha1.dpr
A segunda forma é criar funções para manipular esta estrutura (vetor e indicador). Assim os
pontos do programa que necessitam armazenar e retirar valores se utilizam destas funções. Já
há uma melhor modularização e otimização de escrita de código, porém ainda não há nenhuma
garantia que algum ponto do programa vá sempre utilizar estas funções, ou seja, não vá
acessar diretamente a estrutura de dados. Tudo isto é uma questão apenas de disciplina
(cultura) dos programadores. Exemplo de implementação: pilha2.dpr
Observe que em termos de resultado final (execução) não há diferenças entre os três
programas-exemplo.
Exercício 6
Faça as seguintes alterações nos programas pilha2 e pilha3, comparando as dificuldades na
manutenção:
• colocar mais um botão para verificar se a pilha está cheia;
• aumentar o tamanho da pilha para 15 elementos;
• colocar uma segunda pilha.
Exercício 7
Imagine que você está procurando auxiliar uma secretária de um consultório odontológico. Ela
está necessitando de algum aplicativo que organize os dados dos pacientes que estão
aguardando sua consulta. Esta organização se dá por ordem de chegada, ou seja, uma fila de
pacientes. Implemente então uma classe Fila, que irá enfileirar os dados: Nome e Hora de
Chegada.
Você implementará os métodos:
ü Create , que será o construtor;
ü IncluiPaciente( string, TdateTime) : boolean ;
ü ExcluiPaciente (var string, TdateTime) : boolean;
ü Listar;
ü Free, que será o destrutor.
Herança simples
A herança é um novo conceito, implementado apenas nas linguagens orientadas a objeto. Ela
não significa apenas uma série de estruturas agrupadas, mas sim um poderoso mecanismo que
beneficia tanto em termos de reutilização como em termos de manutenção.
Os membros de estruturas agrupadas são de difícil acesso. Pense que você está desenvolvendo
um sistema para bancos e que possui a necessidade de representar as Contas-correntes dos
clientes. Poderia criar a seguinte estrutura (exemplo em Object Pascal) :
Type
S_CCEspecial = record
Conta : S_ContaCorrente;
Limite : double; // valor do limite em R$
DataVcto: TDateTime; // data de vencimento do especial
end;
Var
Conta_Esp : S_CCEspecial; // declarada uma variável
Para acessar o nome do cliente desta variável Conta_Esp, você teria que utilizar a seguinte
sintaxe: Conta_Esp.Conta.Cliente.
Em uma hierarquia, o uso de classes possui acesso mais transparente aos membros.
Normal
Nome
Entrada()
LeNome()
Especial
Limite
Quando se define uma classe base, deve-se cuidar com o tipo de acesso definido às suas
variáveis e funções membro, para que as classes derivadas a partir desta tenham acesso aos
membros corretamente. Esta definição ocorre de acordo com a necessidade em relação ao
problema.
Em Delphi, são quatro os tipos de acesso permitidos, sendo que public é o default.
Construtores em hierarquias
Quando há uma hierarquia de generalização-especialização, os construtores das classes-base
também devem ser invocados. Na realidade, os construtores são chamados da classe mais base
até a classe mais derivada ao longo da hierarquia.
Caso haja parâmetros na chamada dos construtores, os construtores devem ser explicitamente
colocados indicando os parâmetros que estão sendo passados. Exemplo: um sistema bancário
onde, de acordo com os dados fornecidos, é criada uma conta normal ou conta especial. Ao
final, são mostrados os saldos de todas as contas cadastradas. Exemplo de implementação:
contas.dpr
Normal
Cliente
Número
Saldo
Cria()
LeSaldo()
Especial
Limite
DataVencto
Cria()
Exercício 8
Implemente a hierarquia seguinte. Um sistema que atenda a dois tipos de pessoas: física e
jurídica. Implemente apenas um cadastramento de nome e CPF/CGC, criando o objeto de
acordo com o tipo da pessoa. O serviço Cria deve ser construtor. O serviço Mostra deve
mostrar todos os dados existentes.
Pessoa
Nome
Cria()
Mostra*()
Jurídica Física
CGC CPF
Cria() Cria()
Mostra() Mostra()
Destrutores em hierarquias
Quando há uma hierarquia de generalização-especialização, os destrutores das classes-base
também são invocados, no entanto geralmente o acesso ocorre na ordem inversa, ou seja,
partindo da classe mais especializada e indo até a classe mais base. Exemplo de
implementação: her_dest.dpr
Deve-se lembrar que a criação e deleção de objetos deveria funcionar como um acesso a pilha,
a remoção se dá sempre pela classe criada por último.
Exercício 9
Experimente retirar a palavra reservada virtual da função mostrar da classe Venda e verifique
o que acontece.
Recoloque-a na classe e crie uma subclasse de Venda_Prazo, criando também uma função
mostrar. Altere o programa principal para que seja criado um objeto desta nova classe e
requerida a nova função mostrar.
Classes Abstratas
Normalmente quando há uma hierarquia complexa de classes, as classes mais acima costumam
ser bastante genéricas. De fato, esta generalidade pode ser tal que estas classes não possuam
objetos. Desta forma ela é apenas uma classe ou classe abstrata. Em Delphi não há a
possibilidade de se implementar classes abstratas, porém métodos abstratos podem ser
definidos. Isto é alcançado através da utilização da palvra reservada abstract após a definição
da função membro. Neste caso, não deve haver código para esta função na classe base.
Exemplo:
Há uma hierarquia de classes definindo a criação de figuras geométricas. Para cada classe ou
classe&objeto criada há um construtor e um destrutor definido. Eles funcionam perfeitamente,
pois os construtores sempre são chamados e os destrutores foram definidos como virtuais. Há
também a definição de uma classe (Figura) através da utilização de uma função virtual pura.
Figura
Visivel
Coordenada
Desenha()
X
Apaga()
Y
Expande()
Contrai()
MovePara()
EstaVisivel()
Círculo Quadrado
Raio Diagonal
Desenha() Desenha()
Expande() Expande()
Exercício 10
Crie uma nova figura - triângulo - com a mesma funcionalidade das outras figuras existentes.
Compare as dificuldades de manutenção entre os projetos Exe_Pes e Exe_Poo. Obs: para
desenhar o triângulo, utilize o método Polygon.
Agregação (Todo-parte)
Em orientação a objetos, os objetos podem ser compostos por outros objetos. Nas aplicações
isto vai ser implementado através de agregação. Em Delphi a agregação é construída
declarando uma variável membro sendo do tipo de uma classe.
Funcionário
Nome
Data Nasc
Data Admissão
0..*
Dependente
Nome
Data Nasc
Parentesco
Exercício 11
Há atributos e serviços comuns entre Funcionário e Dependente. Portanto, os dois podem ser
derivados de mesma classe base. Crie esta classe e implemente a herança, com as modificações
necessárias.
Exercício 12
A agregação também aparece na relação entre uma Nota Fiscal e seus Itens. Implemente estas
classes, definindo os atributos e serviços necessários.
Bibliografia
- BERRY, John. Programando em C++: Unix e MS/DOS. São Paulo: Makron, 1991.
- COAD, Peter, YOURDON, Edward. Análise baseada em objetos. Rio de Janeiro: Campus,
1991.
- COAD, Peter, YOURDON, Edward. Projeto baseado em objetos. Rio de Janeiro: Campus,
1993.
- COAD, Peter, NICOLA, Jill. Object-oriented programming. Englewood Cliffs: Prentice
Hall, 1993.
- HOLZNER, Steven, The Peter Norton Computing Group. Programando em C++: um guia
prático para a programação profissional. Rio de Janeiro: Campus, 1993.
- JALOTE, Pankaj. An integrated approach to software engineering. New York: Springer-
Verlag, 1991.
- MARTIN, James. Princípios de análise e projeto baseados em objetos. Rio de Janeiro:
Campus, 1994.
- PACHECO, Roberto C.S., MONTENEGRO, Fernando B. Introdução a programação
orientada a objetos em C++. Florianópolis: FEEESC, 1993. Apostila de curso
PPGEEP/ UFSC.
- PETTINATI, Fábio. Programação orientada para objetos: fundamentos e aplicações. São
Paulo: USP, 1991. Tese de Doutoramento em Engenharia, Escola Politécnica USP.
- POHL, Ira. C++ para programadores de pascal. Rio de Janeiro: Berkeley, 1991.
- RUMBAUGH, James et ali. Modelagem e projetos baseados em objetos. Rio de Janeiro:
Campus, 1994.
- SOMMERVILLE, Ian. Software engineering. 4th ed. New York: Addison-Wesley, 1992.
- TAKAHASHI, Tadao, LIESENBERG, Hans K.E. Programação orientada para objeto. São
Paulo: VII Escola de Computação, 1990.
- WINBLAD, Ann L., EDWARDS, Samuel D., KING David R. Object-oriented software.
Addison Wesley, 1991.
Comentário de linha: //
Comentários: abertura com { ou (* fechamento com } ou *)
Identificadores: são os nomes arbitrários dados às classes, aos objetos, às funções, às
variáveis, aos tipos de dados definidos pelo programador, ao nome das unidades e do projeto,
etc. Podem conter as letras de a à z , de A à Z, o caracter _ e os números de 0 a 9. A única
restrição é de que o primeiro caracter deve ser uma letra ou o caracter _ ;
Operador de atribuição:
Atribuição: := Ex: Nome:=’José’;
Operadores aritméticos:
Adição: + Ex: Conta1 := Conta1 + 10;
Subtração: - Ex: Conta1 := Conta1 - 15;
Multiplicação: * Ex: Conta1 := Conta1 * 1.02;
Divisão: / Ex: Conta1 := Conta1 / 2;
Divisão inteira: div Ex: Conta1:=Conta1 div 2; (O resultado da operação irá
retornar um número inteiro)
Resto da Divisão: mod Ex: Resto:=Conta1 mod 2;
Operadores lógicos:
Prof. Marcel Hugo - marcel@furb.rct-sc.br 13
Tópicos Especiais III - Análise e Programação Orientada a Objetos – BCC/FURB
E lógico: and Ex: X:=Y and Z;
Ou lógico: or Ex: X:=Y or Z;
Ou exclusivo: xor Ex: X:=Y xor Z;
Negação: not Ex: X:=not Y;
Operadores relacionais:
Igualdade: = Ex: B = C;
Diferença: <> Ex: B <> C;
Menor que: < Ex: B < C;
Maior que: > Ex: B > C;
Menor ou igual: <= Ex: B <= C;
Maior ou igual: >= Ex: B >= C;
Obs.:O resultado para estes operadores são sempre True ou False (Booleanos).
1. Classes
Definição: type
Nome_classe =class
tipo_de_acesso
membro1 : tipo;
...
declaração de procedimentos;
...
declaração de funções
...
end;
tipo_de_acesso: private, protected, public(default) ou published
tipo: qualquer tipo da linguagem ou definido pelo programador
constructor CriaPessoa;
end;
Exemplo: TPessoa=class
public
function Numero_dias_Aniversario(Data_hoje:TDateTime):integer
procedure LimpaCampos;
end;
function TPessoa.Numero_dias_Aniversario(Data_Hoje:TDateTime):integer;
var
Resultado : integer;
begin
// Código da função
Numero_dias_Aniversario:=Resultado;
end;
procedure TPessoa.LimpaCampos;
begin
// Código do procedimento
end;
3. Funções Construtoras
Nome_classe=class
tipo_de_acesso
constructor Nome_função_construtora (tipo(s)_parâmetros);
end;
Ex : TCalendario=class
Prof. Marcel Hugo - marcel@furb.rct-sc.br 15
Tópicos Especiais III - Análise e Programação Orientada a Objetos – BCC/FURB
public
constructor CriaCalendario;
end;
constructor TCalendario.CriaCalendario;
begin
// Código de inicialização do objeto
end;
4. Funções Destrutoras
Nome_classe=class
tipo_de_acesso
destructor Nome_da_função_Destrutora;
end;
Ex:
TCalendario=class
destructor DestroiCalendario;
end;
destructor TCalendario.DestroiCalendario;
begin
// Código da função destrutora;
end;
5. Herança
Nome_classe_derivada =class(Nome_classe_base)
// declaração
end;
Exemplo: TMorador=class(TPessoa)
public
Tipo : char;
constructor CriaMorador;
procedure EmitirCartao(Cartao:integer);
end;
- uma classe derivada pode ter construtores e destrutores independentemente da classe base
Acesso à classe base:
Tipo de Acesso na Classe Acesso Herdado à
Base Classe Base
public public
protected protected
private inacessível
published published