But first, a question as an answer to a question: Why does it matter?
Am not trying to discourage the discussion, but we need a little bit of context. Are you trying to perhaps apply some of the things you learned about this categorization on Java classes and it's breaking apart? That's what am figuring.
This is merely explaining the abstract difference between the words "abstraction" and "combination". Nothing to say here, but it doesn't answer my question.
It actually does indeed answer your question. But let's move through.
A good abstraction allows a single algorithm to work on more than one encapsulation (combination) of primitives. Any good abstraction requires its assumption to be assessed by the programmer or the compiler.
An example would be map:(A -> B) over sequences (or their iterators). You can map an infinite sequence to another infinite language for example in lazy evaluated languages (eg. Haskell.)
I'm sorry but I'm not sure I understand.
Do you mean to say that abstraction is a mechanism allowing a single logic work on multiple types of data? This definition of abstraction seems a little too narrow. The definition I (the book) gave was "[the] means [...] by which compound elements can be named and manipulated as units".
Naming compound elements is exactly typing.
Manipulating types comes in one of two shapes that I am familiar with: constructing parameterized types or passing instances of this type to functions.
This is where my head explodes. I can understand the distinction between the abstract concepts, but it doesn't tell me, for instance, if the class mechanism of Java is a mean of combination or a mean of abstraction. After all, isn't combination done for abstraction purposes? And, isn't abstraction achieved (almost) exclusively through combination of other elements?
It really isn't hard to see that a class is a means of {combining data} into an abstraction. It's obvious why it's a combination. Let's get past that. It's an abstraction in that it provides a contract for multiple methods on all the class'es and its subclasses' instances.
How'd you implement a Java class language feature into, say, C.
One way to do that is to create a constructor function that returns a void pointer.
You will keep the instance variables in a struct. A pointer to this struct (the void pointer) would be passed around into the "class methods".
You will also need to keep a struct somewhere to describe the class itself, keeping a class name, and more necessarily pointers to all the methods that can be called on instances.
Inheritance is implemented by making the parent class a field in the struct of the subclass. Constructor of the subclass calls the base classes constructor for the field's initiation.
Of course there's an essential part of the puzzle missing which is compile time type checking. No need to go there now.
Under this light, is a Java class really a combination or an abstraction?
I have to say that it's a combination of a combination and an abstraction at the same time.
Let's compare it to a regular struct. A struct is a simple combination of data. You may pass a reference to a struct to an algorithm.
To sum up:
The answer is most probably "a little bit of both", then my question is: How valid is the above 3 point categorization?
I find this meddled type of thinking extremely wrong. To understand thing in light of another theory, you have to see in what ways you can express one concept interms of the other. I believe it very easy to express "classes" in terms of combination of data and abstraction of contracts that can be passed to methods calls. What is there really other than that into classes?
Here's why I think your view is a little narrow: C#, Java, C++ and Haskell are all statically typed. It's not uncommon for static typing to reduce the problem to a simple type check.
Although it's a big deal to productivity and gets really into the aesthetics and art of the programming, the static/dynamic debate doesn't have to do anything with combination/abstraction or lack thereof. They're both equally under the same light. That's probably why it's possible to implement dynamic typing so easily into a statically checked language. What are dynamic objects but hash objects? Check the implementations,
they really are just hash maps. In that sense, there's no dynamic program that can't be easily implemented as a statically typed program (a bad one at it though). More so, it's very hard to program in dynamic languages with an inherent sense of types even though it's not statically checked. The contract in dynamic languages becomes specific to each method signature in each object.
===
May need review, lots of last second editting