Abstract Data Types – ADT
Learn what an Abstract Data Types (ADT) is. Understand how programming languages use an ADT to represent various real-world concepts.
11/09/2023
Before learning about Abstract Data Types, it is recommended that you have already read our article on variables.
In the simplest and most direct way possible, an Abstract Data Type (ADT) is an existing construction in computer programming that allows you to create your own data types. Your own types of variables.
But this explanation is very superficial for someone who is looking to learn the meaning of a ADT.
So, let’s understand in detail how it works.
The Primitive Data Types
Everyone who begins to learn programming is taught about primitive data types and how they are used to create variables.
byte – stores integer value, but with a maximum of 1 byte of information.
short – stores integer value, but with a maximum of 2 bytes of information.
int – stores integer value, but with a maximum of 4 bytes of information.
long – stores integer value, but with a maximum of 8 bytes of information.
float – stores decimal value, but with a maximum of 4 bytes of information.
double – stores decimal value, but with a maximum of 8 bytes of information.
boolean – stores logical value of True or False
char – stores letters and symbols, such as ‘a’, ‘b’, ‘c’, ‘@” and ‘&’, but with a maximum of 2 bytes of information.
When we want to represent an age, for example, we use the type int, better known as an integer, because it allows the variable to store values without decimal places. Perfect for representing ages.
Another example: we want to represent a person’s gender (male or female). We could use the char type, as it allows you to store a single character. We use ‘f’ to represent the female gender and the ‘m’ for the male.
Another example: we want to represent an employee’s salary. For this case, the most suitable type would be double or float, as it is the data types that allow you to store values with decimal places. Perfect for representing monetary values.
Anyway! The primitive types serve to represent in programming code several concepts of the real world, such as age, gender, salary, among others.
The problem of Primitive Data Types
Primitive types become insufficient when we need to represent more complex concepts in the real world.
For example: imagine that you need to represent a fraction like the one below:
What would be the most suitable primitive type to represent it?
And a date, like the one below:
And a geometric shape:
Even more complicated! We need to represent a student:
You may have noticed that these concepts cannot be represented with primitive data types. They have a lot of information to fit in just one variable!
So, how to represent these more complex concepts?
Starting to understand Abstract Data Types
Most of the “things” that exist in the world are more complex than a simple number. For this reason, they need more than one variable to represent them.
Let’s go to the fraction example. Note that it is made up of two parts: the numerator and the denominator:
Therefore, it needs two variables to represent it correctly. We can represent a fraction with two integer variables. Observe the code below:
1.int numerator;
2.int denominator;
Following the same line of reasoning, the geometric figure of the triangle below is composed of 3 points. Each point is composed of two other pieces of information: the X coordinate and the Y coordinate:
Therefore, it needs 6 variables to represent it correctly. We can represent the triangle with 6 integer variables. Observe the code below:
1.int point1X;
2.int point1Y;
3.int point2X;
4.int point2Y;
5.int point3X;
6.int point3Y;
Likewise, a date could be represented by 3 integer variables: one for the day, another for the month and the third for the year:
1.int day;
2.int month;
3.int year;
Finally, to represent a student, we can use 4 variables:
- one of type String, to represent your name;
- one of type int, to represent your age;
- one of type char, to represent your gender (male or female);
- one of type int, to represent your registration.
Your code could look something like:
1.String name;
2.int age;
3.char gender;
4.int registration;
ADTs (Abstract Data Types) are nothing more than a grouping of other data used to represent more complex real-world concepts:
This other data can be primitive and/or abstract types. This means that an Abstract Data Type can have other Abstract Data Types within it.
How to create a ADT?
An Abstract Data Type needs to encapsulate your information. This means that the variables that represent the information cannot be spread out, as if they were declared independently. They need a scope (a body) where information can be kept.
Let’s return to the example of a date concept. Instead of declaring its 3 variables independently:
1.int day;
2.int month;
3.int year;
We need to place them within a structure with a scope. This structure can be represented as:
1.structure Date{
2. int day;
3. int month;
4. int year;
5.}
Most programming languages use the concept of classes to define an Abstract Data Type. They use the word “class” to define the scope (the body) where the variables will be declared.
NOTE: The C programming language uses the word “struct” instead of “class”.
See below some examples of creating the ADT “Date” in some programming languages:
1.public class Data{
2. int day;
3. int month;
4. int year;
5.}
1.struct Data{
2. int day;
3. int month;
4. int year;
5.};
1.class Data{
2.public:
3. int day;
4. int month;
5. int year;
6.};
1.public class Data{
2. public int day;
3. public int month;
4. public int year;
5.}
1.class Data:
2. def __init__(self):
3. self.day=0
4. self.month=0
5. self.year=0
How to create a variable from a ADT?
Once you’ve created your Abstract Data Type, you can now declare variables of that new type, instead of using primitive data types.
For example: for the ADT “Date” we created, instead of declaring 3 variables of type int to represent it…
1.int day;
2.int month;
3.int year;
…we created only a single variable of type “Date”:
1.Data date1;
Because this variable already contains within it all 3 variables of type int.
It is important to remember that each programming language has specific details on how to create an Abstract Type variable. See some examples for the ADT “Date”:
1.Data date1 = new Data();
1.struct Data date1;
1.Data date1;
1.Data date1 = new Data();
1.date1 = Data()
The operator ‘.’ (dot) to use a ADT?
Once you have created your Abstract Type variable. We can access all data within this variable through the operator ‘.’ (dot).
Let us return to the example of the variable of type “Date”:
1.Data date1;
Once the date01 variable is declared, we can use the ‘.’ (dot) to access and modify your internal data:
1.date1.day = 08;
2.date1.month = 02;
3.date1.year = 1988;
In the same way, we can use the ‘.’ (dot) to access this data for reading. To print them on the screen, for example:
1.print(date1.day);
2.print(date1.month);
3.print(date1.year);
Most programming languages use this ‘.’ (dot) as a mechanism for accessing the internal elements of an Abstract Data Type.
Below are some examples of using the ‘.’ (dot) for modifying and reading data in several different programming languages:
1.Date date1 = new Date();
2.date1.day = 17;
3.System.out.println("Day = "+date1.day);
1.struct Date date1;
2.date1.day = 17;
3.printf("Day = %d", date1.day);
1.Date date1
2.date1.day = 17;
3.std::cout << "Day = " << date1.day;
1.Date date1 = new Date();
2.date1.day = 17;
3.Console.WriteLine ("Day = "+date1.day);
1.date1 = Date()
2.date1.day = 17
3.print("Day = ", date1.day)
However, it is important to note that, in some programming languages, there are other operators of access to the internal elements of a TAD. For example:
The C language has, besides the operator ‘.’ (dot):
- the operator ‘->’ (arrow), specific to access pointer elements.
The C ++ language, in addition to the operator ‘.’ (dot) and ‘->’ (arrow), also have:
- the operator ‘::’ (scope resolution).
Operations on a ADT
In addition to the data, an Abstract Data Type can also have operations (functions).
In fact, this is the most important element of a ADT.
The operations (functions) within a ADT, allow it to operate on your data in an organized manner.
To exemplify what this means, let’s build a ADT to represent a rectangle. In this case, we will have 2 variables: one of type int to represent the width and the other also of type int to represent the height:
1.structure Rectangle{
2. int height;
3. int width;
4.}
Now let’s put two operations (functions) inside this TAD:
- one to return the perimeter of the rectangle (the sum of all sides).
- another to return the rectangle area (multiplying height by width).
Therefore, the TAD is as follows:
1.structure Rectangle{
2. int height;
3. int width;
4. // operations(functions)
5. int perimeter(){
6. return (height*2)+(width*2);
7. }
8. int area(){
9. return height*width;
10. }
11.}
Below is the ADT code with the operations (functions) included in several programming languages:
1.public class Rectangle{
2. int height;
3. int width;
4. // functions(operations)
5. public int perimeter(){
6. return (height*2)+(width*2);
7. }
8. public int area(){
9. return height*width;
10. }
11.}
1.struct Rectangle{
2. int height;
3. int width;
4.};
5.// functions(operations)
6.int perimeter(struct Rectangle ret){
7. return (ret.height*2)+(ret.width*2);
8.}
9.int area(struct Rectangle ret){
10. return ret.height*ret.width;
11.}
1.class Rectangle{
2.public:
3. int height;
4. int width;
5. // functions(operations)
6. int perimeter(){
7. return (height*2)+(width*2);
8. }
9. int area(){
10. return height*width;
11. }
12.};
1.public class Rectangle{
2. public int height;
3. public int width;
4. // functions(operations)
5. public int perimeter(){
6. return (height*2)+(width*2);
7. }
8. public int area(){
9. return height*width;
10. }
11.}
1.class Rectangle:
2. def __init__(self):
3. self.height=0
4. self.width=0
5. # functions(operations)
6. def perimeter(self):
7. return (self.height*2)+(self.width*2)
8. def area(self):
9. return self.height*self.width
Note that the functions operate exclusively on the ADT data. Operations (functions) are created within the ADT and can only access data that exists within it.
NOTE: Some programming languages do not allow creating operations (functions) within the body of the ADT, such as the C language for example. In these cases, operations (functions) are created outside the body of the ADT.
See examples below (in several programming languages) of using this ADT with the operations (functions) already included:
1.Rectangle ret = new Rectangle();
2.ret.height = 10;
3.ret.width = 5;
4.System.out.println("Perimeter = "+ret.perimeter());
5.System.out.println("Area = "+ret.area());
1.struct Rectangle ret;
2.ret.height = 10;
3.ret.width = 5;
4.printf("Perimeter = %d\n",perimeter(ret));
5.printf("Area = %d\n",area(ret));
1.Rectangle ret;
2.ret.height = 10;
3.ret.width = 5;
4.std::cout << "Perimeter = " << ret.perimeter();
5.std::cout << "Area = " << ret.area();
1.Rectangle ret = new Rectangle();
2.ret.height = 10;
3.ret.width = 5;
4.Console.WriteLine("Perimeter = "+ret.perimeter());
5.Console.WriteLine("Area = "+ret.area());
1.ret = Rectangle()
2.ret.height = 10;
3.ret.width = 5;
4.print("Perimeter = ",ret.perimeter())
5.print("Area = ",ret.area())
David Santiago
Master in Systems and Computing. Graduated in Information Systems. Professor of Programming Language, Algorithms, Data Structures and Development of Digital Games.