“Is A” vs. “Represents A”
We’ve all had the distinction between “Is A” and “Has A” in object oriented programming drilled into us. “Is A” relationships call for inheritance. “Has A” relationships call for delegation. Some theorists will even bother to distinguish between “Is A” and “Is a Role Played By“. However, recently I’ve been wondering about the distinction between real “Is A” and “Represents A” relationships, and I wonder if it may help explain some otherwise confusing points.
The issue is simply this. Very few classes really are the things they represent. A Shape
object is not a shape. A Person
object is not a person. They are abstractions that represent the real things. No one would confuse Person p = new Person("Milli Vanilli")
with a real singer. Hmm, maybe not such a good example…
Anyway, when we use objects to refer to things inside the computer it’s a lot trickier. A Thread
object is not a thread, but it’s so close that the distinction is often lost, unless the speaker is being very careful. Maybe it even is a thread when green threads are in play? I’m not sure. Is a Java Class
object a class? I’m honestly not sure. An instance of java.lang.Object
is in fact a real object, but is it the object it represents or is it some other object?
To make matters worse, some objects really are the thing they represent. In particular data structure classes really are what they say they are. A LinkedList
is a linked list. A Hashtable
is a hash table. Sometimes we call these things “abstract data types”, but in many ways they are the most concrete objects we have. People and shapes and cars are only represented inside the computer memory. They could never really live there, but a hash table or a linked list can’t live anywhere else. But is a List<Car>
a list of cars or is it a list of representations of cars? Or both? A paper list of the cars in an auto dealer’s lot doesn’t really contain the cars either so maybe it’s OK to say that a List<Car>
is a list of cars even though a Car
isn’t a car.
Does this matter in any way or is this all just sophistic posturing? I’m not sure of that either. I suspect most working programmers manage to get by pretty well without thinking too hard about it or being overly precise in their language simply by letting context resolve any ambiguities.
However, I’m a little more concerned about students coming to the subject for the first time. I do know that when I was learning OOP, the distinctions really confused me. If anything the distinction between representation and reality was worse than the distinction between classes and instances of classes. That at least was obvious to me based on what I read in any OO text. (The class is the cookie cutter; the object is the cookie. OK. Got it.)
However many texts didn’t bother to explain the difference between representation and reality, and that threw me. The difference between a Thread
and a thread was a particular problem. Applet
vs. applet was another one, and one I’m still not 100% sure I know the answer to. I suspect the authors thought the difference was so obvious they didn’t feel it needed mentioning. More likely they hadn’t even seriously considered it themselves. After all much of the time the difference is obvious. When what’s modeled is a physical object like a person or a car or even an abstract quantity like Gross Domestic Product or annual sales the distinction is apparent.
However, when we start modeling things inside the computer like threads, processes, applets, heaps, and so forth the distinction is no longer nearly as apparent. It behooves us to be very careful when speaking of such things.
January 24th, 2025 at 4:14 pm
Is-A vs Has-A was created by someone who didn’t understand the problem. They were too focused on the minutiae that they couldn’t see the bigger picture.
When to use inheritance? When you want the subclass to be a drop-in substitute for the base class, but with additional or modified capabilities.
When to do not use inheritance? When you aren’t in that situation.
When to use interfaces? When you want a drop in substitute, but the classes don’t share any common code.
The problem is easy when you FOCUS ON THE PROBLEM YOU ARE TRYING TO SOLVE instead of the dogma and philosophy.
January 25th, 2025 at 7:00 am
Yes, subclasses should be drop in replacements for base classes. That’s a pretty fundamental part of OO. Interfaces, however, don’t necessarily improve on abstract base classes even if subclasses don’t share any common code (which is rare). The purpose of interfaces (that is the Java
interface
keyword, not the more generic interface that ever class in every language has) is solely to add types to classes that already have a supertype. Interfaces tend to be much overused in Java with very negative consequences for maintainability and reliability.