Linguagem Técnica de Programação Delphi Orientada a Objetos

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.