Delphi Orientada a Objetos
DELPHI
Conceitos de Programação Orientada a Objetos
Introdução
Fatos
• Crescimento no tamanho das aplicações.
• Aumento na complexidade das aplicações.
• Necessidade de manutenção de sistemas antigos.
• Aumento da demanda por sistemas novos.
• Baixa produtividade.
Problemas
• Necessidade de reescrever algoritmos e estruturas de dados para novas aplicações.
• Mudanças em sistemas necessitam alterações em muitos módulos.Solução
• Estruturas de dados associadas às operações.Evolução
Conceitos
Componentes Básicos da Orientação a Objetos
Objeto Abstração que agrupa características e comportamentos.
Classe Tipo de Objeto. Define quais características um objeto pode ter e seu comportamento.
Instância É o Objeto propriamente dito. Possui características próprias
Mensagem Representa uma ação do objeto ou uma mudança de estado. Define a comunicação entre objetos.
Método Define a implementação de uma mensagem, ou seja, o comportamento dos objetos de uma classe.
Propriedade Define uma característica de um objeto.
Conceitos Adicionais
Protocolo Conjunto de mensagens que define o comportamento de um objeto. Interface.
Encapsular Garantir que os atributos só podem ser alterados por algum método.
Construtor Método encarregado de criar e estabelecer valores iniciais para um objeto.
Destrutor Método encarregado de destruir o objeto e fazer a coleta de lixo.
Herança
Conceitos
• Permite que uma nova classe seja descrita a partir de outra classe já existente.
• A subclasse herda as características e o comportamento da superclasse.
• A subclasse pode adicionar novas características e comportamentos aos herdados da superclasse.
• A subclasse pode ter um comportamento diferente da superclasse, redefinindo o método herdado.
• A subclasse é uma especialização da superclasse.
• Toda instância da subclasse é também uma instância da superclasse.
• O resultado de uma sequência de heranças é uma hierarquia de classes.
Classes Abstratas
• Não pode ser instanciada.
• Possui métodos que não estão implementados.
• Definida para ser a base de uma hierarquia.
Polimorfismo
• Sobrecarga do Nome do Método
• Objetos de classes diferentes podem ter métodos com mesmo nome e cada objeto responderá adequadamente de acordo com seu método.
• Métodos da mesma classe podem ter o mesmo nome, desde que possuam quantidade ou tipo de parâmetros diferentes.
• Métodos da classe derivada podem ter nomes iguais aos da classe base, inclusive com parâmetros iguais.
Sobrecarga de Operadores
• Todos os operadores da linguagem, se possível, devem ser passíveis de sobrecarga.
• Permite uma melhor legibilidade do código implementado.
• Permite que novos tipos de dados fiquem totalmente integrados com a linguagem.
Métodos Virtuais
• As mensagens são vinculadas ao objeto no momento da execução – Vínculo Tardio.
• Permite maior flexibilidade de envio de mensagem.
• A mesma implementação de método pode se comportar de maneira diferente, em função do objeto que enviou a mensagem.
• Diminui a eficiência.
• A maior parte das linguagens deixa a cargo do programador definir quais métodos serão virtuais.
Um exemplo de Orientação a Objetos
unit Datas;
interface
type
TData = Class(TObject)
private
Dia, Mes, Ano : Integer;
public
constructor Init (d,m,a : integer);
procedure DefVal (d,m,a : integer);
function AnoBis : boolean;
procedure Incrementa;
procedure Decrementa;
procedure Adiciona (NumDeDias : integer);
procedure Subtrai (NumDeDias : integer);
function GetText : string;
private
function DiasNoMes : Integer;
end;
implementation
constructor TData.Init (d,m,a : integer);
begin
dia := d; Mes := m; ano := a;
end;
procedure TData.DefVal (d,m,a : integer);
begin
dia := d; Mes := m; ano := a;
end;
function TData.AnoBis : boolean;
begin
if (ano mod 4 <> 0)
then AnoBis := false
else
if (ano mod 100 <> 0)
then AnoBis := true
else
if (ano mod 400 <> 0)
then AnoBis := False
else AnoBis := True;
end;
function TData.DiasNoMes : integer;
begin
case Mes of
1,3,5,7,8,10,12 : DiasNoMes := 31;
4,6,9,11 : DiasNoMes := 30;
2 : if (AnoBis)
then DiasNoMes := 29
else DiasNoMes := 28;
end;
end;
procedure TData.Incrementa;
begin
if (dia < DiasNoMes) {se não for o último dia do Mes}
then inc(dia)
else
if (Mes < 12) {se não for dezembro}
then
begin
inc(Mes);
dia := 1;
end
else {se for o dia de ano novo}
begin
inc(ano);
Mes := 1;
dia := 1;
end;
end;
procedure TData.Decrementa;
begin
if (dia > 1)
then Dec(dia) {se não for o primeiro dia do mês}
else
if (Mes > 1) {se não for o primeiro dia do ano}
then
begin
Dec(Mes);
dia := DiasNoMes;
end
else
begin
Dec(ano);
Mes := 12;
dia := DiasNoMes;
end;
end;
function TData.GetText : string;
var d, m, a : string;
begin
d := IntToStr(dia);
case Mes of
1 : m := ‘Janeiro’;
2 : m := ‘Fevereiro’;
3 : m := ‘Março’;
4 : m := ‘Abril’;
5 : m := ‘Maio’;
6 : m := ‘Junho’;
7 : m := ‘Julho’;
8 : m := ‘Agosto’;
9 : m := ‘Setembro’;
10: m := ‘Outubro’;
11: m := ‘Novembro’;
12: m := ‘Dezembro’;
end;
a := IntToStr(ano);
GetText := d + ‘, ‘ + m + ‘ de ‘ + a;
end;
procedure TData.Adiciona (NumDeDias : integer);
var n : integer;
begin
for n := 1 to NumDeDias do
Incrementa;
end;
procedure TData.Subtrai (NumDeDias : integer);
var n : integer;
begin
for n := 1 to NumDeDias do
Decrementa;
end;
end.
Object Pascal
Introdução
Estrutura de um Programa
Program <identificador>;
[uses <lista de units>;]
<seções de declaração>
begin.
<instruções>
end.
Identificadores
• São nomes assinalados a qualquer elemento em um programa escrito em Object Pascal.
• É formado por uma sequência de letras, dígitos e sublinhados, onde somente os 63 primeiros caracteres são significativos.
• Não pode iniciar com um dígito.
• Não são permitidos espaços em branco na formação do nome.
Características
• Tamanho Máximo da Linha: 126 caracteres
• Toda instrução finaliza em um ponto-e-vírgula.
Seções de Declaração
<Seção de declaração de constantes>
<Seção de declaração de tipos>
<Seção de declaração de variáveis>
<Seção de declaração de procedimentos e funções>
Estrutura de uma Unit
Unit <identificador>;
Interface
[uses <lista de units>;]
<seções de declaração>
Implementation
[uses <lista de units>;]
<definições>
[Initialization
<instruções>]
end.
Comentários
Qualquer seqüência de caracteres delimitada por { } ou por (* *).
Procedimentos Básicos de Entrada e Saída
Entrada
Readln ( <lista de variáveis> )
• Preenche uma variável com dados vindos do teclado.
Exemplos:
Read ( Dia, Mes, Ano );
Read ( Nome );
Saída
Write ( <lista de valores> )
ou
Writeln ( <lista de valores> )
• Imprime os valores na janela principal da aplicação. O procedimento writeln move o cursor de impressão para a linha seguinte, após a impressão dos valores
Exemplos:
Writeln ( Dia, ‘/’, Mes, ‘/’, Ano );
Write ( Nome );
Tipos
Tipos Inteiros
Tipo Faixa Formato
Shortint -128 .. 127 8 bits Sinalizado
Integer -32768 .. 32767 16 bits Sinalizado
Longint -2147483648 .. 2147483647 32 bits Sinalizado
Byte 0 .. 255 8 bits não Sinalizado
Word 0 .. 65535 16 bits não Sinalizado
Tipos Booleanos
Tipo Memória False True
Boolean 1 byte 0 1
ByteBool 1 byte 0 diferente de 0
WordBool 2 bytes (uma word) 0 diferente de 0
LongBool 4 bytes (duas words) 0 diferente de 0
Tipo Sub-Faixa
<valor inicial> .. <valor final>
• É definido por um subconjunto de um tipo ordinal.
• Possui as mesmas propriedades do tipo original.
• Não é permitido faixa com valores do tipo longint.
Tipo Enumerado
( <lista de identificadores> )
• Define uma sequência de identificadores como valores válidos para um tipo.
• Cada elemento da lista de identificadores é associado sequencialmente a números inteiros, iniciando pelo número 0.
Tipos Ordinais
• Tipos Inteiros e Booleanos
• Char (armazena um caracter)
• Tipo Sub-Faixa
• Tipo Enumerado
Os tipos ordinais permitem a utilização das seguintes funções:
Função Descrição
Ord Retorna o número de ordem do elemento no conjunto.
Pred Retorna o elemento anterior.
Succ Retorna o elemento seguinte.
Low Retorna o primeiro elemento do conjunto.
High Retorna o último elemento do conjunto.
Tipos Reais
Tipo
Faixa Dígitos Significativos Tamanho
em Bytes
Real 2.9 * 10-39 .. 1.7 * 1038 11-12 6
Single 1.5 * 10-45 .. 3.4 * 1038 7-8 4
Double 5.0 * 10-324 .. 1.7 * 10308 15-16 8
Extended 3.4 * 10-4932 .. 1.1 * 104932 19-20 10
Comp -263+1 .. 263-1 19-20 8
• O tipo Comp armazena somente números inteiros na faixa aproximada de -9.2 * 1018 a 9.2 * 1018.
• Todos os tipos reais são armazenados no formato de ponto flutuante.
• As operações em ponto flutuante podem ser executadas tanto por Hardware como emuladas por Software.
Tipo String
string
ou
string [ <valor inteiro positivo> ]
• Armazena uma string com o tamanho máximo de até 255 caracteres.
• Pode ser especificado um tamanho máximo menor que 255.
• Permite a concatenação utilizando-se o operador +.
Seção de Declaração de Tipos Definidos pelo Usuário
type
<declaração de tipos>
• Um tipo pode ser declarado no corpo principal de um programa, em um procedimento ou função ou em uma unit, tanto na interface como na implementation.
Declaração de Tipos
<identificador> = <tipo>;
Variáveis
Seção de Declaração de Variáveis
var
<declaração de variáveis>
Declaração de Variáveis
<identificador> : <tipo>;
Exemplo:
var
Dia: Shortint;
Nota: Real;
Nome: string;
Operadores
Aritméticos
+ (unário) Positivo
– (unário) Negativo
+ (binário) Adição
– (binário) Subtração
* Multiplicação
/ Divisão real
div Divisão Inteira
mod Resto da Divisão Inteira
Lógicos
not Não
and E
or OU Inclusivo
xor OU Exclusivo
Bit-a-bit
not Não
and E
or OU Inclusivo
xor OU Exclusivo
shl Deslocamento a esquerda
shr Deslocamento a direita
Relacionais
= Igual
> Maior
< Menor
<> Diferente
>= Maior ou Igual
<= Menor ou Igual
Precedência
+ (unário), – (unário), not
*, /, div, mod, and, shl, shr
+ (binário), – (binário), or, xor
=, <>, <, >, <=, >=
Constantes
Categoria Definição
Numérica Inteira Qualquer sequência de dígitos decimais (0 a 9), sinalizados ou não, entre 2.147.483.648 e 2.147.483.647.
Numérica Real Qualquer sequência de dígitos decimais (0 a 9), sinalizados ou não, com um separador decimal ou em notação científica.
Hexadecimal Qual sequência de dígitos hexadecimais (0 a F), precedidos por um sifrão ($), entre $00000000 e $FFFFFFFF.
Caracter Um único caracter entre apóstrofos ou o caracter # seguido de um número inteiro entre 0 e 255 (código ASCII).
String Qualquer sequência de caracteres escrito em uma linha de programa e delimitado por apóstrofos. Dois apóstrofos ëm sequência dentro de uma string representam um único.
Seção de Declaração de Constantes
const
<declarações de constantes>
Declaração de Constantes Simples
<identificador> = <valor>;
Declaração de Constantes Tipadas
<identificador> : <tipo> = <valor>;
• Utilizadas como variáveis inicializadas no momento da definição.
Funções Constantes
• Funções de tipos ordinais: Ord, Pred, Succ, Low, High.
• Funções da lista abaixo:
Função Descrição
Chr Retorna o caracter correspondente ao código ASCII.
Abs Retorna o valor absoluto.
Round Retorna o valor arredondado.
Trunc Retorna a parte inteira de um número.
Odd Retorna se um número é ímpar.
Length Retorna o comprimento de uma string.
SizeOf Retorna o número de bytes ocupados por uma variável.
Ptr Converte um segmento e um offset em um ponteiro.
Hi Retorna o byte de maior ordem em uma word.
Lo Retorna o byte de menor ordem em uma word.
Swap Inverte os bytes de uma word.
Exemplos:
const
Pi = 3.14;
MaiorValor = 1024 * 64 – 16;
NumCaracteres = Ord(‘Z’) – Ord(‘A’) + 1;
Mensagem = ‘Hello world…’;
Minimo: Integer = 0;
Maximo: Integer = 9999;
Salario: Real = 44322.34;
Blocos
• Um Bloco ou Instrução Composta é definido como sendo uma seqüência de instruções entre as palavras chaves BEGIN e END.
• Corresponde a estrutura de programação seqüencial.
begin
<instrução 1>;
<instrução 2>;
<instrução 3>;
.
.
.
<instrução n>
end
Atribuição
<variável> := <expressão>
• Armazena um valor em uma variável.
Exemplos:
Dia := 20;
Nome := ‘José’;
Seleção
Seleção Simples
• Permite que o fluxo de execução seja desviado em função de uma condição
if <condição> then
<instrução>
else
<instrução>
Exemplos:
if Nota < 5 then
Writeln(‘Reprovado’)
else
Writeln(‘Aprovado’);
Seleção Múltipla
• Permite que o fluxo de execução seja desviado em função de uma condição
case <expressão ordinal> of
<lista de opções> : <instrução>;
.
.
.
[else
<instrução>;]
end
Exemplos:
case EstadoCivil of
‘C’: Writeln(‘Casado’);
‘S’: Writeln(‘Solteiro’);
‘D’: Writeln(‘Divorciado’);
‘V’: Writeln(‘Viúvo’);
else
Writeln(‘Estado Civil Desconhecido’);
end;
• A lista de opções pode ser um valor ordinal, uma seqüência de valores ordinais separados por vírgula ou uma faixa de valores.
• A cláusula else é opcional e será executada caso nenhuma das opções corresponda ao resultado da expressão.
• Os valores devem ser colocados em ordem crescente e não devem ser repetidos em mais de uma opção.
Repetição
Repetição Contada
for <variável> := <início> to <fim> do
<instrução>
ou
for <variável> := <início> downto <fim> do
<instrução>
• A cláusula to da estrutura for incrementa um ao valor da variável a cada iteração.
• A cláusula downto da estrutura for decrementa um do valor da variável a cada iteração.
• O valor da variável é indefinido ao finalizar o processo de repetição.
Exemplos:
for Contador := 1 to 10 do
Writeln(Contador);
Repetição Condicional
while <condição> do
<instrução>
ou
repeat
<instrução 1>;
<instrução 2>;
<instrução 3>;
.
.
.
<instrução n>
until <condição>
• A estrutura while é executada enquanto a condição for verdadeira
• A estrutura repeat é executada até que a condição seja verdadeira, ou seja, enquanto for falsa.
Exemplos:
Soma := 0;
Read(Valor);
while Valor <> 0 do
begin
Soma := Soma + Valor;
Read(Valor)
end;
Writeln(Soma); Soma := 0;
repeat
Read(Valor);
Soma := Soma + Valor;
until Valor = 0;
Writeln(Soma);
Instruções de Salto
Break
• Finaliza a iteração (for, while ou repeat) mais “próxima”, transferindo o controle para a instrução seguinte.
continue
• Transfere o controle para o teste da condição da iteração (for, while ou repeat) mais “próxima”.
Resumo
Estrutura Quando Usar
for Quando se conhece a quantidade de vezes que se deve repetir.
while…do Quando se deseja testar a condição antes de executar a primeira vez.
repeat…until Quando se deseja executar a primeira vez e só então testar a condição.
Conjunto
• Define um conjunto de elementos com o mesmo tipo ordinal.
• O Conjunto não pode ter mais que 256 elementos.
Definição do Conjunto
set of <tipo>
Conjunto Constante
[ <lista de valores> ]
Operadores
Operador Descrição
+ União
– Diferença
* Interseção
in Pertinência
Exemplos:
const
DigitoHexa: set of Char = [‘0’..’9′, ‘A’..’Z’,
‘a’..’z’];
var
Feriado: set of 1..31;
begin
Feriado := [];
.
.
.
Vetores e Matrizes
• Define uma estrutura de dados com elementos do mesmo tipo.
Vetores
array [ <tipo do índice> ] of <tipo do elemento>
• O tipo do índice deve ser um tipo ordinal e normalmente é uma sub-faixa.
• O tipo Longint não é permitido como índice do vetor.
Matriz
array [ <lista de tipos> ] of <tipo do elemento>
ou
array [ <tipo do índice> ] of
array [ <tipo do índice> ] of <tipo do elemento>
• O compilador dá tratamento igual aos dois formatos acima.
Acesso aos Elementos
<variável do tipo vetor> [ <índice> ]
Vetor Constante
( <lista de valores> )
• Utilizado na definição de constantes tipadas.
Exemplos:
const
Fatorial: array[1..7] of Integer = (1, 2, 6, 24,
120, 720, 5040);
type
TipoNotas = array[1..3] of real;
var
Notas: TipoNotas;
begin
Write(‘Digite a segunda Nota: ‘);
Read(Nota[2]);
Notas[1] := 10;
Notas[3] := 8.5;
Writeln(‘O fatorial de 5 é ‘, Fatorial[5]);
.
.
.
Registros
• Define um conjunto de elementos que podem ter tipos diferentes.
Definição do Registro
record
<lista de campos 1> : <tipo 1>;
<lista de campos 2> : <tipo 2>;
<lista de campos 3> : <tipo 3>;
.
.
.
<lista de campos n> : <tipo n>;
end;
Acesso aos Elementos
<variável do tipo registro> . <campo>
Cláusula with
with <lista de variáveis do tipo registro> do
<instrução>
• Retira a obrigatoriedade do uso do nome da variável no acesso aos campos do registro.
• Normalmente é utilizado com bloco de instruções.
Registro Constante
( <campo 1> : <valor 1> ,
<campo 2> : <valor 2> ,
<campo 3> : <valor 3> ,
.
.
.
<campo n> : <valor n> )
• Utilizado na definição de constantes tipadas.
Exemplos:
type
Ponto = record
X, Y: real
end;
const
Origem: Ponto = (X: 0.0; Y: 0.0);
var
Pontos: array[0..9] of Ponto;
begin
Pontos[0] := Origem;
Ponto[4].X := 2.5;
Ponto[4].Y := 53.2;
.
.
.
Procedimentos e Funções
Escopo
• Define o local onde um identificador pode ser usado.
• Pode ser: local, de procedimento ou função, de unit ou de classe.
Visibilidade
• Define a região do programa onde é legal o acesso ao elemento associado ao identificador.
Tempo de Vida
• Define o período de tempo durante o qual o identificador possui um elemento na memória real. Pode ser:
Categoria Descrição
Estático Existe durante toda a execução do programa.
Local Criado e destruído automaticamente na chamada de um procedimento ou função
Dinâmico Alocado dinâmicamente na memória livre.
Procedimentos
procedure <identificador> ( <parâmetros formais> );
<seções de declaração>
begin
<instrução 1>
<instrução 2>
<instrução 3>
.
.
.
<instrução n>
end;
Exemplos:
type
TipoData = record
Dia, Mes, Ano: Shortint;
end;
procedure Dividir(var Data: TData);
begin
with Data do
Read(Dia, Mes, Ano)
end;
Funções
function <ident.> ( <parâmetros formais> ) : <tipo>;
<seções de declaração>
begin
<instrução 1>
<instrução 2>
<instrução 3>
.
.
.
<instrução n>
end;
Exemplos:
function Fatorial(const n: Longint): Longint;
begin
if n = 0 then
Result := 1
else
Result := n * Fatorial(n – 1);
end;
Parâmetros Formais
• Permite receber dados de entrada e enviar dados de resposta em um procedimento ou função.
• As passagens de dados podem ser efetuadas por valor, por referência, constante e aberta.
• Cada declaração de parâmetro deve ser separada por ponto-e-vírgula.
Parâmetro com Passagem por Valor
<lista de identificadores> : <tipo>
• Cria uma variável local com uma cópia do valor passado para o procedimento ou função.
• O valor do parâmetro pode ser alterado e não é refletido na variável original.
Parâmetro com Passagem por Referência
var <lista de identificadores> : <tipo>
• O identificador aponta para o mesmo endereço de memória que a variável original.
• Ao se alterar o valor do parâmetro, altera-se o valor da variável original.
• Arquivos só podem ser passados por referência.
Parâmetro Constante
const <lista de identificadores> : <tipo>
• Garante que o valor do parâmetro não vai poder ser alterado.
• Deve ser utilizado sempre que possível, pois o compilador gera um código mais otimizado para esse tipo de passagem de parâmetro.
Parâmetro Aberto
<lista de identificadores> : string
ou
<lista de identificadores> : array of <tipo>
• Permite que sejam criadas funções para manipular strings ou vetores independente do tamanho dessas strings e vetores.
• Assume o tamanho do vetor ou string passados como parâmetro.
• Pode ser passado por valor, por referência ou constante.
• Normalmente é utilizado em conjunto com as funções:
Função Valor de Retorno
Low Zero
High O índice do último elemento do vetor original
SizeOf O tamanho do vetor original
Valor de Retorno
Result := <valor>
• Toda função possue uma variável de Result do mesmo tipo do retorno da função.
• O valor atribuido à variável Result é considerado o valor de retorno da função.
Chamada a um Procedimento ou Função
<identificador> ( <parâmetros reais> )
• Um procedimento não pode ser utilizado em uma expressão, por não possuir valor de retorno.
• As funções, mesmo retornando valor, podem ser chamadas como instrução isolada.
• Os parâmetros reais devem ser colocados na mesma ordem e devem ter tipos compatíveis com os tipos definidos nos parâmetros formais do procedimento ou função chamado.
Ponteiros
• Um ponteiro é uma variável que armazena um endereço de memória.
• Não possue elemento associado até ser atribuído a um endereço ou ter uma área da memória livre alocada para ele.
• Caso o ponteiro não esteja apontando para nenhum elemento, a ele deve ser atribuído o valor nil.
Definição do Tipo
^ <tipo original>
Alocação de Memória
New ( <variável ponteiro> )
ou
<variável ponteiro> := New ( <tipo> ) ;
Alocação de Memória
Dispose ( <variável ponteiro> )
Acesso a uma variável apontada
<variável ponteiro> ^
Arquivos
Tipo Descrição
TextFile Arquivo Texto
File of <tipo> Arquivo Tipado, associado a um registro
File Arquivo Não Tipado
Procedimentos e funções pré-definidos são responsáveis pela manipulação dos arquivos. Os principais são:
Associação com Nome Externo
AssignFile ( <variável arquivo> , <nome externo> )
Abrir Arquivo para Leitura
Reset ( <variável arquivo> )
Criar e Abrir um Arquivo Novo
Rewrite ( <variável arquivo> )
Abrir um Arquivo Texto para Expansão
Append ( <variável arquivo> )
Fechar um Arquivo
CloseFile ( <variável arquivo> )
Fim de Arquivo
Eof ( <variável arquivo> )
Leitura de Dados
Read ( < variável arquivo> , <variável> )
Gravação de Dados
Write ( < variável arquivo> , <variável> )
Exemplos:
type
Funcionario = record
Nome: string[30];
Salario: real;
end;
var
Arq: File of Funcionario;
Func: Funcionario;
begin
AssignFile(Arq , ‘teste.txt’);
Reset(Arq);
while not eof(Arq)
begin
Read(Arq, Func); {Lê um registro do arquivo}
Writeln(Func.Nome, Func.Salario); {Exibe na tela}
end
CloseFile(Arq);
end.
Classes
Definição de uma Classe Base
<identificador> = class
<atributos e métodos>
end;
• Deve ser feita na seção de declaração de tipos principal de um programa ou de uma unit.
Atributos e Métodos
<visibilidade 1>
<lista de variáveis>
<lista de procedimentos ou funções>
<visibilidade 2>
<lista de variáveis>
<lista de procedimentos ou funções>
<visibilidade 3>
<lista de variáveis>
<lista de procedimentos ou funções>
.
.
.
<visibilidade n>
<lista de variáveis>
<lista de procedimentos ou funções>
Exemplos:
type
TData = class
private
Ano: Word;
Mes: Word;
Dia: Word;
public
constructor Ler;
constructor Copy(d: TData);
constructor Create(dd, mm, aa: Word);
function AsString: string;
end;
Visibilidade
• Define quem tem permissão de acessar e alterar os atributos e métodos da classe.
• Em uma mesma classe podem existir atributos e métodos com visibilidades diferentes.
Visibilidade Descrição
Private Os atributos e métodos só podem ser manipulados pela própria classe.
Protected Os atributos e métodos podem ser manipulados pela própria classe ou por qualquer subclasse desta.
Public Os atributos e métodos podem ser manipulados por qualquer classe.
Definição de uma Herança
<identificador> = class( <identif. da classe base> )
<características e comportamentos>
end;
Métodos Virtuais
• Para tornar um método virtual, basta acrescentar no final de sua declaração na classe, a palavra virtual ou a palavra dynamic seguida de um ponto-e-vírgula.
• A palavra virtual define métodos virtuais otimizados pela velocidade na execução, enquanto a palavra dynamic define otimizando pelo tamanho do código gerado.
• A sobrecarga do método subclasse é feita, acrescentando-se a palavra override, no final de sua declaração, seguida de um ponto-e-vírgula.
Métodos Abstratos
• Para tornar um método virtual, basta acrescentar no final de sua declaração na classe, a palavra abstract seguida de um ponto-e-vírgula.
• Para um método ser abstrato, é necessário que ele seja também virtual.
Método Construtor
constructor <identificador> ( <parâmetros formais> );
• Aloca memória e inicializa o objeto, baseado nos parâmetros passados.
• Normalmente a primeira ação é invocar o construtor da base classe, através da instrução:
inherited <construtor> ( <parâmetros reais > );
Método Destrutor
destructor <identificador> ( <parâmetros formais> );
• Destroi o objeto, baseado nos parâmetros passados, e libera a memória alocada para ele.
• Normalmente a última ação é invocar o destrutor da base classe, através da instrução:
inherited <destrutor> ( <parâmetros reais > );
Exemplos:
type
TCoordenada = class
private
X: Word;
Y: Word;
public
constructor Create(x1, y1: Word);
constructor Nulo;
function GetX: Word;
function GetY: Word;
procedure SetX(x1: Word);
procedure SetY(y1: Word);
end;
TFigura = class(TCoordenada)
private
Cor: TColor;
protected
Visivel: Boolean;
public
constructor Create(x1, y1: Word; cor1: TColor);
constructor Nulo;
function SetCor(cor1: TColor): TColor;
function GetCor: TColor;
procedure Desenhar; virtual; abstract;
procedure Apagar;
procedure Mover(x1, y1: Word);
function EstaVisivel: Boolean;
end;
TPonto = class(TFigura)
public
procedure Desenhar; override;
end;
Referência para um Objeto
• É declarado da mesma maneira que uma variável.
• Se comporta como um ponteiro, mas é manipulado como uma variável normal.
• Necessita ser construído e destruído explicitamente.
• Pode ser atribuído ao valor nil.
Conversão de Tipo
<objeto> as <subclasse>
• Converte, se possível, uma referência para objeto de uma classe base em uma referência para objeto da subclasse.
Verificação de Tipo
<objeto> is <classe>
• Verifica se a referência para objeto é uma instância da classe ou de alguma subclasse desta.
• Retorna true ou false.
Tratamento de Exceção
Aplicações Robustas
O tratamento de exceção é um mecanismo capaz de dar robustez a uma aplicação, permitindo que os erros sejam manipulados de uma maneira consistente e fazendo com que a aplicação possa se recuperar de erros se possível ou finalizar a execução quando necessário, sem perda de dados ou recursos.
Para que uma aplicação seja segura, seu código necessita reconhecer uma exceção quando esta ocorrer e respondê-la. Se não houver tratamento para uma exceção, será exibida uma mensagem descrevendo o erro. Uma exceção deve ser respondida sempre que houver perigo de perda de dados ou de recursos do sistema.
Os Recursos do Sistema que necessitam proteção e podem causar danos na execução caso sejam perdidos são: Arquivos, Memória, Recursos do Windows e Objetos.
Criação de um Bloco Protegido
try
<instrução 1>;
.
.
.
<instrução n>
finally
<instrução n + 1>;
.
.
.
<instrução m>
end;
• Tanto as instruções da cláusula try quanto as instruções da cláusula finally são executadas sequencialmente.
• Se houver uma exceção em qualquer das instruções da cláusula try o controle de execução será desviado para a primeira instrução da cláusula finally.
• As instruções da cláusula finally são sempre executadas, mesmo que não haja exceção.
• try … finally não trata exceção em particular, apenas permite a garantia de que não haja perda de recursos.
Exemplos:
var
PValor: ^Real;
Resultado, Dividendo: Integer;
begin
Dividendo := 0;
New(PValor);
try
Resultado := 10 div Dividendo;
finally
Dispose(PValor);
end;
end;
Tratamento de Exceções
try
<instrução 1>;
<instrução 2>;
<instrução 3>;
.
.
.
<instrução n>
except
<lista de tratamentos>
[else
<instrução 1>;
<instrução 2>;
<instrução 3>;
.
.
.
<instrução n>]
end;
Tratamento de um Exceção
on <tipo de exceção> do
<instrução>;
• Quando uma exceção é tratada, o fluxo de execução continua na instrução seguinte ao tratamento.
• Para permitir que o tratamento da exceção prossiga no tratamento default, utiliza-se a palavra-chave raise no fim do bloco de instruções do tratamento para que a exceção seja lançada novamente.
Principais Classes de Exceção
Classe Descrição
EDivByZero Divisão de inteiro por zero
EZeroDivide Divisão de real por zero
ERangeError Valor excede a faixa definida
EGPFault Acesso a memória não permitido
EOutOfMemory Memória Livre insuficiente para alocar objeto
EInOutError Erro de Entrada ou Saída
EInvalidOp Operação inválida com número real
EOverflow Número real excedeu a faixa válida
EUnderflow Número real menor que a faixa válida
Exemplos:
function Media(Soma, NumeroDeItens: Integer): Integer;
begin
try
Result := Soma div NumeroDeItens;
except
on EDivByZero do
Result := 0;
end;
end;
Criação de Classes de Exceção
<identificador> = class(Exception);
• Qualquer anormalidade na execução de um programa pode ser transformada em uma exceção pela criação de uma classe para fazer esse tratamento.
• As classes de exceção devem ser subclasses da classe Exception.
• No momento em que houver uma anormalidade, um objeto do classe de exceção criada deve ser lançado, seguindo o modelo:
if <condição anormal> then
raise <classe de exceção >.Create( <descrição> );
Exemplos:
type
EFatorialNegativo = class(Exception)
public
constructor Create;
end;
.
.
.
constructor EFatorialNegativo.Create;
begin
inherited Create(‘Fatorial Negativo’);
end;
function Fatorial(const n: Longint): Longint;
begin
if n < 0 then
raise EFatorialNegativo.Create;
if n = 0 then
Result := 1
else
Result := n * Fatorial(n – 1);
end;
var
N: Longint;
begin
Write(‘Digite um valor (-1 para sair): ‘);
Read(N);
while N <> -1 do
begin
try
Writeln(n, ‘! = ‘, Fatorial(N));
except
on E:EFatorialNegativo do
Writeln(E.Message);
end;
Write(‘Digite um valor (-1 para sair): ‘);
Read(N);
end;
end.