Search code examples
ooptheorydefinitionabstract-data-type

Abstract Data Type vs. non Abstract Data Types (in Java)


I have read a lot about abstract data types (ADTs) and I'm askig myself if there are non-abstract/ concrete datatypes?

There is already a question on SO about ADTs, but this question doesn't cover "non-abstract" data types.

The definition of ADT only mentions what operations are to be performed but not how these operations will be implemented

reference

So a ADT is hiding the concrete implementation from the user and "only" offers a bunch of permissible operations/ methods; e.g., the Stack in Java (reference). Only methods like pop(), push(), empty() are visible and the concrete implementation is hidden.

Following this argumentation leads me to the question, if there is a "non-abstract" data type?

Even a primitive data type like java.lang.Integer has well defined operations, like +, -, ... and according to wikipedia it is a ADT.

For example, integers are an ADT, defined as the values …, −2, −1, 0, 1, 2, …, and by the operations of addition, subtraction, multiplication, and division, together with greater than, less than, etc.,

reference


Solution

  • The java.lang.Integer is not a primitive type. It is an ADT that wraps the primitve java type int. The same holds for the other Java primitive types and the corresponding wrappers.

    You don't need OOP support in a language to have ADTs. If you don't have support, you establish conventions for the ADT in the code you write (i.e. you only use it as previoulsy defined by the operations and possible values of the ADT)

    That's why ADT's predate the class and object concepts present in OOP languages.They existed before. Statements like class just introduced direct support in the languages, allowing compilers to check what you are doing with the ADTs.

    Primitive types are just values that can be stored in memory, without any other associated code. They don't know about themselves or their operations. And their internal representation is known by external actors, unlike the ADTs. Just like the possible operations. These are manipulations to the values done externally, from the outside.

    Primitive types carry with them, although you don't necessary see it, implementation details relating the CPU or virtual machine architecture. Because they map to CPU available register sizes and instructions that the CPU executes directly. Hence the maximum integer value limits, for example.

    If I am allowed to say this, the hardware knows your primitive types.

    So your non-abstract data types are the primitive types of a language, if those types aren't themselves ADT's too. If they happen to be ADTs, you probably have to create them (not just declare them; there will be code setting up things in memory, not only the storage in a certain address), so they have an identity, and they usually offer methods invoked through that identity, that is, they know about themselves.

    Because in some languages everything is an object, like in Python, the builtin types (the ones that are readily available with no need to define classes) are sometimes called primitive too, despite being no primitive at all by the above definition.

    Edit:

    As mentioned by jaco0646, there is more about concrete/abstract words in OOP.

    An ADT is already an abstraction. It represents a category of similar objects you can instantiate from.

    But an ADT can be even more abstract, and is referred as such (as opposed to concrete data types) if you declare it with no intention of instantiating objects from it. Usually you do this because other "concrete" ADTs (the ones you instantiate) inherit from the "abstract" ADT. This allows the sharing and extension of behaviour between several different ADTs. For example you can define an API like that, and make one or more different ADTs offer (and respect) that API to their users, just by inheritance.

    Abstract ADTs maybe defined by you or be available in language types or libraries.

    For example a Python builtin list object is also a collections.abc.Iterable.

    In Python you can use multiple inheritance to add functionality like that. Although there are other ways.

    In Java you can't, but you have interfaces instead, and can declare a class to implement one or more interfaces, besides possibly extending another class.

    So an ADT definition whose purpose is to be directly instantiated, is a concrete ADT. Otherwise it is abstract.

    A closely related notion is that of an abstract method in a class. It is a method you don't fill with code, because it is meant to be filled by children classes that should implement it, respecting its signature (name and parameters).

    So depending on your language you will find possible different (or similar) ways of implementing this concepts.