Tipos Abstratos de Dados – TAD

Aprenda o que é um Tipo Abstrato de Dados (TAD). Entenda como as linguagens de programação utilizam um TAD para representar conceitos.

09/11/2023

Antes de aprender sobre os Tipos Abstratos de Dados, é recomendável que você já tenha lido o nosso artigo sobre variáveis.

Da maneira mais simples e direta possível, um Tipo Abstrato de Dados (TAD) é uma construção existente na programação de computadores que permite que você crie os seus próprios tipos de dados. Os seus próprios tipos de variáveis.

Bom! Mas essa explicação é muito superficial para alguém que está querendo aprender o significado de um TAD.

Então, vamos entender detalhadamente como isso funciona.


Os Tipos Primitivos de Dados

Todos que começam a aprender programação são ensinados sobre os tipos primitivos de dados e como eles são usados para criar variáveis.

byte – armazena valor inteiro, mas com no máximo 1 byte de informação.

short – armazena valor inteiro, mas com no máximo 2 bytes de informação.

int – armazena valor inteiro, mas com no máximo 4 bytes de informação.

long – armazena valor inteiro, mas com no máximo 8 bytes de informação.

float – armazena valor decimal, mas com no máximo 4 bytes de informação.

double – armazena valor decimal, mas com no máximo 8 bytes de informação.

boolean – armazena valor lógico de Verdadeiro e Falso (true, false).

char – armazena letras e símbolos, tais como, ‘a’, ‘b’, ‘c’, ‘@’ e ‘&’, mas com no máximo 2 bytes de informação.

Quando queremos representar uma idade, por exemplo, usamos o tipo int, mais conhecido como inteiro, pois ele permite que a variável armazene valores sem casas decimais. Perfeito para representar idades.

Outro exemplo: queremos representar o gênero de uma pessoa (masculino ou feminino). Poderíamos usar o tipo char, pois ele permite armazenar um único caractere. Usamos ‘f’ para representar o gênero feminino e o ‘m’ para o masculino.

Mais um exemplo: queremos representar o salário de um funcionário. Para este caso, o tipo mais adequado seria o double ou float, pois são os tipos de dados que permitem armazenar valores com casas decimais. Perfeito para representar valores monetários.

Enfim! Os tipos primitivos servem para representar em código de programação diversos conceitos do mundo real, tais como, idade, gênero, salário, dentre outros.


O problema dos Tipos Primitivos

Os tipos primitivos se tornam insuficientes quando precisamos representar conceitos mais complexos do mundo real.

Por exemplo: imagine que você precise representar uma fração como esta abaixo:

Qual seria o tipo primitivo mais adequado para representá-la?

E uma data, como esta abaixo:

E uma forma geométrica:

Mais complicado ainda! Precisamos representar um estudante:

Bem! Você já deve ter percebido que esses conceitos não podem ser representados com os tipos primitivos de dados. Eles possuem muitas informações para caber em apenas uma única variável!

Então, como representar esses conceitos mais complexos?


Começando a entender os Tipos Abstratos de Dados

A maior parte das “coisas” que existem no mundo é mais complexa que um simples número. Por esse motivo, precisam de mais de uma variável para representá-las.

Vamos ao exemplo da fração. Observe que ela é composta de duas partes: o numerador e o denominador:

Por isso, ela precisa de duas variáveis para representá-la corretamente. Podemos representar uma fração com duas variáveis inteiras. Observe o código abaixo:

1.int numerador;
2.int denominador;

Seguindo a mesma linha de raciocínio, a figura geométrica do triângulo abaixo é composta por 3 pontos. Cada ponto, é composto por outras duas informações: a coordenada X e a coordenada Y:

Por isso, ela precisa de 6 variáveis para representá-la corretamente. Podemos representar o triângulo com 6 variáveis inteiras. Observe o código abaixo:

1.int ponto1X;
2.int ponto1Y;
3.int ponto2X;
4.int ponto2Y;
5.int ponto3X;
6.int ponto3Y;

Da mesma forma, uma data poderia ser representada por 3 variáveis inteiras: uma para o dia, outra para o mês e a terceira para o ano:

1.int dia;
2.int mes;
3.int ano;

Por fim, para representar um estudante, podemos utilizar 4 variáveis:

  • uma do tipo String, para representar o seu nome;
  • uma do tipo int, para representar o a sua idade;
  • uma do tipo char, para representar o seu gênero (masculino ou feminino);
  • uma do tipo int, para representar a sua matrícula.

O seu código poderia ser algo como:

1.String nome;
2.int idade;
3.char genero;
4.int matricula;

Os TADs (Tipos Abstratos de Dados) nada mais são do que um agrupamento de outros dados usados para representar conceitos mais complexos do mundo real:

Esses outros dados podem ser tipos primitivos e/ou abstratos. Isso significa que um Tipo Abstrato de Dados pode ter dentro dele outros Tipos Abstratos de Dados.


Como criar um TAD?

Um Tipo Abstrato de Dados precisa encapsular as suas informações. Isso significa que as variáveis que representam as informações não podem ficar soltas, como se fossem declaradas de forma independente. Elas precisam de um escopo (um corpo) onde as informações possam ser guardadas.

Vamos retornar ao exemplo do conceito de uma data. Ao invés de declarar as suas 3 variáveis soltas:

1.int dia;
2.int mes;
3.int ano;

Precisamos colocá-las dentro de uma estrutura com um escopo. Essa estrutura pode ser representada como:

1.estrutura Data{
2. int dia;
3. int mes;
4. int ano;
5.}

A maioria das linguagens de programação usam o conceito de classes para definir um Tipo Abstrato de Dados. Elas usam a palavra “class” para definir o escopo (o corpo) onde as variáveis serão declaradas.

OBS: A linguagem de programação C usa a palavra “struct” no lugar de “class”.

Veja abaixo alguns exemplos de criação do TAD “Data” em várias linguagens de programação:

Java
C
C++
C#
Python
1.public class Data{
2. int dia;
3. int mes;
4. int ano;
5.}
1.struct Data{
2. int dia;
3. int mes;
4. int ano;
5.};
1.class Data{
2.public:
3. int dia;
4. int mes;
5. int ano;
6.};
1.public class Data{
2. public int dia;
3. public int mes;
4. public int ano;
5.}
1.class Data:
2. def __init__(self):
3. self.dia=0
4. self.mes=0
5. self.ano=0

Como criar uma variável de um TAD?

Uma vez que você criou o seu Tipo Abstrato de Dados, você agora pode declarar variáveis desse novo tipo, ao invés de usar tipos primitivos de dados.

Por exemplo: para o TAD “Data” que criamos, ao invés de declarar 3 variáveis do tipo int para representá-la…

1.int dia;
2.int mes;
3.int ano;

…criamos apenas uma única variável do tipo “Data”:

1.Data novaData;

Pois essa variável já contém dentro dela todas as 3 variáveis do tipo int.

É importante lembrar que cada linguagem de programação possui detalhes específicos na maneira de criar uma variável de um Tipo Abstrato. Veja alguns exemplos para o TAD “Data”:

Java
C
C++
C#
Python
1.Data novaData = new Data();
1.struct Data novaData;
1.Data novaData;
1.Data novaData = new Data();
1.novaData = Data()

O operador ‘.’ (ponto) para usar um TAD?

Uma vez criada a sua variável de um Tipo Abstrato. Podemos acessar todos os dados dentro dessa variável por meio do operador ‘.’ (ponto).

Retornemos ao exemplo da variável do tipo “Data”:

1.Data novaData;

Uma vez declarada a variável novaData, podemos usar o operador ‘.’ (ponto) para acessar e modificar os seus dados internos:

1.novaData.dia = 08;
2.novaData.mes = 02;
3.novaData.ano = 1988;

Da mesma forma, podemos usar o operador ‘.’ (ponto) para acessar esses dados para leitura. Para imprimi-los na tela, por exemplo:

1.print(novaData.dia);
2.print(novaData.mes);
3.print(novaData.ano);

A maioria das linguagens de programação usam esse operador ‘.’ (ponto) como um mecanismo de acesso aos elementos internos de um Tipo Abstrato de Dados.

Veja abaixo alguns exemplos de uso do operador ‘.’ (ponto) para modificação e leitura de dados em várias linguagens de programação diferentes:

Java
C
C++
C#
Python
1.Data novaData = new Data();
2.novaData.dia = 17;
3.System.out.println("Dia = "+novaData.dia);
1.struct Data novaData;
2.novaData.dia = 17;
3.printf("Dia = %d", novaData.dia);
1.Data novaData
2.novaData.dia = 17;
3.std::cout << "Dia = " << novaData.dia;
1.Data novaData = new Data();
2.novaData.dia = 17;
3.Console.WriteLine ("Dia = "+novaData.dia);
1.novaData = Data()
2.novaData.dia = 17
3.print("Dia = ", novaData.dia)

Contudo, é importante ressaltar que existem, em algumas linguagens, outros operadores de acesso aos elementos internos de um TAD. Por exemplo:

A linguagem C possui, além do operador ‘.’ (ponto):

  • o operador ‘->’ (seta), específico para acessar elementos de ponteiros.

A linguagem C++, além do operador ‘.’ (ponto) e ‘->’ (seta), também possui:

  • o operador ‘::’ (resolução de escopo).

Operações em um TAD

Além dos dados, um Tipo Abstrato de Dados também pode possuir operações (funções).

Na verdade, esse é o elemento mais importante de um TAD.

As operações (funções) dentro de um TAD, permitem que ela opere sobre os seus dados de uma maneira organizada.

Para exemplificar o que isso significa, vamos construir um TAD para representar um retângulo. Nesse caso, teremos 2 variáveis: uma do tipo int para representar a largura e outra também do tipo int para representa a altura:

1.estrutura Retangulo{
2. int altura;
3. int largura;
4.}

Agora vamos colocar duas operações (funções) dentro desse TAD:

  • uma para retornar o perímetro do retângulo (a soma de todos os lados).
  • outra para retornar a área do retângulo (a multiplicação da altura pela largura).

Portanto, o TAD fica da seguinte forma:

1.estrutura Retangulo{
2. int altura;
3. int largura;
4. // operações(funções)
5. int perimetro(){
6. return (altura*2)+(largura*2);
7. }
8. int area(){
9. return altura*largura;
10. }
11.}

Abaixo segue o código do TAD já com as operações (funções) incluídas em várias linguagens de programação:

Java
C
C++
C#
Python
1.public class Retangulo{
2. int altura;
3. int largura;
4. // funções(operações)
5. public int perimetro(){
6. return (altura*2)+(largura*2);
7. }
8. public int area(){
9. return altura*largura;
10. }
11.}
1.struct Retangulo{
2. int altura;
3. int largura;
4.};
5.// funções(operações)
6.int perimetro(struct Retangulo ret){
7. return (ret.altura*2)+(ret.largura*2);
8.}
9.int area(struct Retangulo ret){
10. return ret.altura*ret.largura;
11.}
1.class Retangulo{
2.public:
3. int altura;
4. int largura;
5. // funções(operações)
6. int perimetro(){
7. return (altura*2)+(largura*2);
8. }
9. int area(){
10. return altura*largura;
11. }
12.};
1.public class Retangulo{
2. public int altura;
3. public int largura;
4. // funções(operações)
5. public int perimetro(){
6. return (altura*2)+(largura*2);
7. }
8. public int area(){
9. return altura*largura;
10. }
11.}
1.class Retangulo:
2. def __init__(self):
3. self.altura=0
4. self.largura=0
5. # funções(operações)
6. def perimetro(self):
7. return (self.altura*2)+(self.largura*2)
8. def area(self):
9. return self.altura*self.largura

Observe que as funções operam exclusivamente sobre os dados do TAD. As operações (funções) são criadas dentro do TAD e só podem acessar os dados que existem dentro dele.

OBS: Algumas linguagens de programação não permitem criar operações (funções) dentro do corpo do TAD, como a linguagem C por exemplo. Nesses caso, as operações (funções) são criadas fora do corpo do TAD.

Veja abaixo exemplos (em várias linguagens de programação) do uso desse TAD já com as operações (funções) incluídas:

Java
C
C++
C#
Python
1.Retangulo ret = new Retangulo();
2.ret.altura = 10;
3.ret.largura = 5;
4.System.out.println("Perimetro = "+ret.perimetro());
5.System.out.println("Area = "+ret.area());
1.struct Retangulo ret;
2.ret.altura = 10;
3.ret.largura = 5;
4.printf("Perimetro = %d\n",perimetro(ret));
5.printf("Area = %d\n",area(ret));
1.Retangulo ret;
2.ret.altura = 10;
3.ret.largura = 5;
4.std::cout << "Perimetro = " << ret.perimetro();
5.std::cout << "Area = " << ret.area();
1.Retangulo ret = new Retangulo();
2.ret.altura = 10;
3.ret.largura = 5;
4.Console.WriteLine("Perimetro = "+ret.perimetro());
5.Console.WriteLine("Area = "+ret.area());
1.ret = Retangulo()
2.ret.altura = 10;
3.ret.largura = 5;
4.print("Perimetro = ",ret.perimetro())
5.print("Area = ",ret.area())
autor

David Santiago

Mestre em Sistemas e Computação. Graduado em Sistemas de Informação. Professor de Linguagem de Programação, Algoritmos, Estruturas de Dados e Desenvolvimento de Jogos Digitais.

Outros artigos