Introdução ao Paradigma de
Programação por Objectos
1. Tipos abstractos (Abstract types)
2. Conceitos principais:
Encapsulamento, Herança, Polimorfismo
(Encapsulation, Hierarchy, Polymorphism)
3.1. Classes e Objectos;
3.2. Métodos e Dados;
3.3. Interfaces e Implementação;
3.4. Programação por contracto;
3.5. Gestão de memória
O que é importante:
1. Perceber o que é um tipo abstracto.
2. Perceber o que é um encapsulamento.
3. Perceber o que é uma classe.
4. Perceber a diferença entre classes e objectos.
5. Perceber as regras da linguagem C++ que são aplicadas
para declarar classes e definir objectos dessas classes
6. Estar apto a construir programas triviais que utilizem classes.
Em C podemos definir:
int a,b,c;
e podemos usar
as operações:
+, -, *, etc
?
Será que podemos definir um tipo novo,
por exemplo?
complex a,b,c;
Podemos definir as nossas operações para
o nosso tipo, por exemplo?
?
+, -, *, etc
Tipos abstractos (Abstract types)
Memória
nomes dos dados
int a,b,c;
3
4
7
a
b
c
atribuição simples
a = 3;
b=4
c = a + b;
o tipo de dados
atribuição simples adição
c = a # b;
indefinido
Tipos abstractos (Abstract types)
Memória
nomes dos dados
string a,b,c;
Av
eiro
Aveiro
a
b
c
atribuição simples
a = “Av”;
b = “eiro”
c = a + b;
o tipo de dados
adição
atribuição simples
c = a # b;
indefinido
SET
O tipo novo
a1
a3
Por exemplo:
SET A={a1,a2,a3};
SET B={a3,a4,a5};
SET C;
C = A + B;
a2
a4
a3
a5
+
a1
a2
a3
a4
a5
=
a1,
a2,
a3,
a4,
a5
-
C = A - B;
a1
a2
a3
a3
a4
a5
=
a1,
a2
Um paradigma, designado Abstracção de tipos de dados, consiste em
1. definir os tipos de dados de que se tenha necessidade
e
2. criar para cada um deles um conjunto completo de operações
a1,a2,a3,etc.
SET
+
*
A+B
A*B
A-B
A abstracção de dados assume a definição de tipos de dados abstractos,
ou por outras palavras, alguns tipos de dados introduzidos pelo utilizador,
isto é, definido por ele.
nomes dos dados
pessoa p1,p2,p3;
os atributos:
o tipo de dados
1. Nome.
2. Morada.
3. Idade.
as operações:
&, ==, !=, etc.
Onde mora?
cout << &p1;
Ílhavo
A abstracção de dados requer que consideremos as operações sobre os
dados e as implementações dessas operações
Temos as seguintes operações: &, ==, !=, etc.
Vamos assumir que estas operações já foram implementadas
e, por isso, elas podem ser usadas em programas, por exemplo:
pessoa p1,p2,p3;
// definição das três pessoas p1, p2 e p3
if (p1 == p2) // fazer alguma coisa, por exemplo:
cout << &p3;
Por outro lado, se alguma operação destas não existir deveremos
implementá-la em C++.
Suponhamos que é dado um módulo. Neste caso é suficiente conhecer
as operações que efectua mas não é necessário conhecer detalhes, i.e.
como essas operações são efectuadas
O conceito de tipos abstractos é um conceito chave da programação
Isto assume a separação e consideração independente de duas noções
básicas, que são a implementação e a interface
A modularidade e a abstracção complementam-se
A modularidade assume que escondemos os detalhes
pessoa
da implementação
numa caixa preta
?
A abstracção permite especificar
em particular
&,cada
==, !=,módulo
etc.
antes de escrever o programa
?
&, ==, !=, etc.
Podem-se distinguir dois tipos de abstracção que são:
• a abstracção ao nível dos procedimentos e
• a abstracção dos dados
A primeira requer uma consideração à parte. O objectivo de um
procedimento é a sua implementação interna. Nós assumimos que
um procedimento é algo como uma função em C ou C++
A abstracção dos dados requer que consideremos as operações
sobre os dados e as implementações dessas operações
a
b
void swap(int* a,int* b)
{
int temp;
temp=*a;
&,==, &, ==, !=, etc.
Pessoa
*a = *b;
!=,etc. }
*b=temp;
swap
Suponhamos que é dado um módulo. Neste caso é suficiente conhecer
as operações que efectua mas não é necessário conhecer detalhes, i.e.
como essas operações são efectuadas
Assim, uma abstracção permite separar uma representação
externa de um módulo da sua estrutura interna
A abstracção de dados assume a definição e consideração de tipos de
dados abstractos, ou por outras palavras, alguns tipos de dados
introduzidos pelo utilizador, isto é, definidos por ele
Vamos separar duas noções importantes que são
os tipos de dados abstractos e os tipos abstractos
A primeira noção já foi especificada
A segunda noção é considerada um tipo de dados abstracto
juntamente com o novo conjunto de funções e operações
que foi definido para este tipo de dados abstracto
dados
funções operações
Quando digo função quero dizer qualquer função em linguagem
C/C++, como por exemplo main, função_definida_por_mim,
sqrt (raiz quadrada), etc
Quando digo operação quero dizer qualquer operação pré-definida
ou definida pelo utilizador, como por exemplo soma (+),
subtracção (-), divisão (/), etc.
As operações definidas pelo utilizador são muito úteis para os tipos
de dados definidos pelo utilizador. Permitem redefinir operações já
definidas na linguagem para tipos de dados definidos pelo utilizador
memória
int a=10;
b é o endereço de a na memória
int* b=&a;
pessoa p=“Paulo”;
cout << &p;
Ílhavo, 3830
Rua Coutada, 56
10
Paulo
Vamos criar o tipo “pessoa” em C++:
Por exemplo, podemos
usar uma estrutura que é
qualquer coisa do tipo:
struct pessoa
{
unsigned short Idade;
char* Morada;
char* Nome;
};
De notar que a nossa especificação da estrutura pessoa (do tipo
abstracto pessoa) ainda não está completa
Os valores dos campos que são Nome, Morada e Idade não estão definidos
Por outras palavras, os campos devem, em geral, ser inicializados
Para este efeito podemos usar algumas funções específicas
no contexto da estrutura
Isto é possível na linguagem C++ e não é possível na linguagem C
Inicialização significa atribuir valores iniciais aos atributos do objecto
Este trabalho é efectuado por uma função especial
que é chamada construtor da classe
O construtor
struct
pessoa da classe possui o mesmo nome que a classe e não
nenhum
valor,
nem do tipo void. Todas as outras
{ devolve
unsigned
short
Idade;
características
de um construtor de uma classe são semelhantes
char* Morada;
char* Nome;às de um método normal
pessoa(unsigned
short
Id, char* instala
Mor, char*
No)para
Para
o nosso exemplo
o construtor
valores
{ três atributos
Idade = Id;
que são Nome, Morada e Idade
strcpy(Morada,Mor);
Esta função (ou este método)
strcpy(Nome,No);
}
pode ser construída da seguinte maneira
};
Agora podemos usar o tipo pessoa da seguinte maneira:
pessoa p(25,”Ílhavo”,”Ricardo”);
struct pessoa
{
unsigned short Idade;
char* Morada;
char* Nome;
pessoa(unsigned short Id, char* Mor, char* No)
{
Idade = Id;
Morada=Mor;
Nome=No;
}
};
Agora podemos usar o tipo pessoa da seguinta maneira:
pessoa p(25,”Ílhavo”,”Ricardo”);
Agora temos: p.Idade=25, p.Morada=“Ílhavo”, p.Nome=“Ricardo”
Download

ppt2 - Universidade de Aveiro › SWEET