Tipos Abstratos de Dados
Entendendo TADs e criando TADs simples (com Douglas Macharet)
Definição
- Modelo matemático, acompanhado das operações definidas sobre o modelo.
- Conjunto dos inteiros acompanhado das operações de adição, subtração e multiplicação.
- A implementação do algoritmo em uma linguagem de programação exige a representação do TAD em termos dos tipos de dados e dos operadores suportados.
Contrato
- TADs são contratos
- Funções que operam em cima da memória
Encapsulamento
- Conceito importante em TADs
- Usuário:
- Enxerga a interface
- Não se preocupa, em primeiro momento, como é o TAD por baixo
- Usuário:
Definindo Contratos
O que é um contrato?
- Acordo entre duas ou mais partes
- Quais contratos existem em um programa?
- Requisitos de funcionalidade, desempenho, …
- Operações disponíveis em um TAD
- Entradas e saídas
Ideia de Contratos
TADs vs Structs
Então TADs são structs?
- Não!
- TADs são um conceito mais geral
- Existem em qualquer tipo de linguagem
- Em C++:
- Sim, mapeiam bem para structs/classes + .h
- Ou para interfaces
- Assuntos futuro
TADs vs Algoritmos
Algoritmo
- Sequência de ações executáveis:
entrada → saída
- Algoritmos usam TADs
TADs
- Contrato + Memória
- Podemos considerar TADs como generalizações de tipos primitivos e procedimentos como generalizações de operações primitivas.
- O TAD encapsula tipos de dados. A definição do tipo e todas as operações ficam localizadas numa seção do programa.
- Os usuários do TAD só tem acesso a algumas operações disponibilizadas sobre esses dados
Em outras Linguagens
- TADs são um conceito de programação
- Vamos aprender como implementar os mesmos usando classes e objetos
- Outras linguagens
- structs + funções ( C )
- traits ( Rust )
- duck typing ( Python, Ruby )
- classes e interfaces ( Java, C++ )
Como criar um TAD?
Supondo que vamos criar um TAD qualquer. Temos que responder:
- Como organizar a memória?
- Quais dados vão no struct/classe
- Quais operações?
- Contratos
A primeira pergunta é mais de implementação, o TAD é descrito pela 2.
Como fazer um TAD ponto?
Primeiro problema
- Quais dados temos que representar?
- Valor no eixo-x
- Valor no eixo-y
Vamos fazer em C:
typedef struct {
double _x;
double _y;
} ponto_t;
int main() {
ponto_t p = {1.0, 2.0};
return 0;
}
Destrinchando
- Observe como começamos dizendo que vamos criar um tipo novo:
typedef
. - Após isto, dizemos que este tipo é um
struct
- Depois damos um nome
ponto_t
.- Eu pessoalmente gosto de nomear structs com
_t
no fim - Eu também gosto de colocar um
_
antes dos nomes dos campos internos. Isto é estilo. Não é uma regra.
- Eu pessoalmente gosto de nomear structs com
typedef struct {
double _x;
double _y;
} ponto_t;
em C++
- A chamada é bem diferente mas com sentido
- Em breve vamos olhar para tudo com calma
class Ponto {
private:
double _x;
double _y;
public:
Ponto(double x, double y) {
_x = x;
_y = y;
}
};
int main() {
Ponto p = Ponto(2.0, 3.0);
return 0;
}
SOCORRO!!!!
- CLASS
- PUBLIC
- PRIVATE!
Visibilidade
- O
public
indica tudo que você tem acesso - O
private
você não tem - Por exemplo, o código abaixo vai falhar:
class Ponto {
private:
double _x;
double _y;
Ponto(double x, double y) {
_x = x;
_y = y;
}
};
int main() {
Ponto p = Ponto(2.0, 3.0);
return 0;
}
É impossível fora da Classe acessar campos private.
Construtores
- Funções que iniciam o
struct
- Chamadas de construtores
// ...
public:
Ponto(double x, double y) {
_x = x;
_y = y;
}
// ...
- Observe como a mesma apenas seta a memória!
- Preste atenção no passo a passo do C++ tutor acima.
Métodos
- Um método pode ser visto como uma função em C
- Porém a mesma pertence ao objeto. Falamos com o mesmo.
class Ponto {
private:
double _x;
double _y;
public:
Ponto(double x, double y) {
_x = x;
_y = y;
}
void imprime() {
std::cout << _x;
std::cout << _y;
}
};
int main() {
Ponto p = Ponto(2.0, 3.0);
p.imprime();
return 0;
}
Em sala de Aula
Vamos criar um TAD String
- Entender melhor como criar um TAD
- Operações além da impressão
- Substring
- Starts With (Começa com)
- Size
- O código inicial se encontra abaixo
Importância da Visibilidade
- Descomente as linhas que tentam acessar o
_size
do exemplo - Temos um erro de compilação!
- Nunca quebramos a coerência do estado!
std::string
- Na prática já temos um tipo
string
para fazer uso - Basta realizar
include <string>
como na aula anterior - O nosso exemplo foi apenas para motivar TADs
- Leia a documentação da
string
de C++ aqui
Notas Finais
- Estamos iniciando o assunto da matéria
- Lembre-se que:
- TADs → dados + operações
- TADs guardam estado
- Podemos usar um struct em C
- Em C++ usamos classes
Notas Finais
Esses TADs são iguais ou diferentes?
class Ponto {
private:
float _x;
float _y;
public:
Ponto(float x, float y) {
_x = x;
_y = y;
}
}
class Ponto {
private:
float _r;
float _theta;
public:
Ponto(float r, float theta) {
_r = r;
_theta = theta;
}
}
- Iguais (em conceito)
- Abstração do mesmo conceito da matemática
- Diferentes (em dados)!
- Tipo/TAD
- Elementos com propriedades semelhantes
- Clientes dependem do conceito geral
Notas Finais
- A implementação não deve ser conhecida
- A abstração deve prover os métodos que serão utilizados para manipular os dados
Próximas Aulas
- Usando alguns TADs mais complexos
- Criando TADs mais complexos
- Separando em módulos
Aonde queremos chegar Com TADs queremos que o resto do programa seja cliente. Apenas use as operações do mesmo.