multiple inheritance or something like it

I’ve always felt slightly offended by the people who write off multiple inheritance in one fell swoop as being something akin to the fight against guns – it’s always misused, and there is no real useful purpose, so we might as well get rid of it in its entirety. There is a slight truth to the statement, as it applies to both guns and MI (the misuse, for example), but the conclusion is oh. so. wrong.

The real problem with MI isn’t so much the mechanism or the misuse but the semantics of such a relationship. When I have a subclass that extends a superclass (to use Stroustrup’s terms for the classes, of course), that subclass is really just the superclass with a few more things tacked on or semantics slightly changed. The syntax, or interaction, or interface (not in the Java sense, but as in the public face of a class) does not change, and this is what allows you to treat the subclass as an instance of the superclass syntactically. Of course, the subclass might not act anything like the superclass, since you are free (in most languages) to override functions in strange and exciting ways, like making toString() pop out the CD tray or something. However, it at least looks and smells like the superclass, however it tastes.

Multiple inheritance, on the other hand, basically states that “This subclass is both things”, which leads to slight areas of friction. For example, what if both things are already a little bit related? Who owns what? What if there is some duplicated functionality that has a different semantic in both superclasses? Which trumps which, and how does that appear to the end user?

When Stroustrup added MI to C++, I don’t imagine that he had these questions in mind (on this abstract of a level). In terms of the mechanism of MI, you are given the tools to manage such areas of overlap, and you can handle things like the (evil-maniac voice) dreadful diamond of doom, which is where you have two parent classes that both extend the same base class, making a diamond shape (virtual inheritance solves this problem). Unfortunately, this still doesn’t answer the semantic issue, but this all fits into the Stroustrup design philosophy, which is to give you the ability to do about everything and trust that you know what the hell you are doing.

So, in C++, we work around the inherent ability to do silly things in MI by not doing them. It is the same thing that keeps us from writing our own List implementation in Java in which the method that adds an element both adds an element and starts a nuclear war with Russia. After all, it should be obvious that a method named “add” adds something, instead of a method named something like “blowUpThosePinkoCommieBastards()” (or whatever you would name such a method).

There is a special type of inheritance, named by the Lisp folk about two decades ago, which requires a suitably powerful generics mechanism. This type is called a mixin, and it is characterized by a templated (in C++ parlay) class that extends/is a subclass of its template parameter. This looks like this (in C++):

template <typename T>
class Mixin : T
{ ... } ;

What this allows you to do is add functionality, usually as a new method and commonly exemplified as timestamping or adding serial numbers or something of the like. For example, we could make a TimeStamp mixin as the following:

template <typename T>
class TimeStampMixin : T
{
private:
    long timestamp;
public:
    TimeStampMixin() : timestamp = /*something that gets now() */ {}
     long getTimeStamp() { return timestamp; }
} ;

Now we can add this timestamp to any existing class, say a string:

TimeStampMixin<string> tstamped("a string");
cout << tstamped << ", timestamp: " << tstamped.getTimeStamp();

The idea here is that the normal semantics of MI, of a subclass being all its parents at the same time, is somewhat relaxed. The mixins are not themselves full-fledged classes (in Java, we would make these classes abstract, as you would never want to instantiate just a TimeStampMixin), and all we are really doing is adding a few pieces of functionality to the subclass. This is somewhat backwards of what inheritance is (where the subclass adds functionality to the base), but it ends up being very useful in parts.

Mixins or MI in Java?

You can almost have mixins in Java. At first glance, you’d say something like, “Yeah, Java generics, I can do the same thing!” Only problem is type erasure. Since the generic types are erased at runtime (to enable forwards compatibility in Java 1.5 [or 5.0 or whatever they call it]), if you try to do something similar to the timestamp example, you will get an error. You cannot have a genericized class extend its supplied generic type parameter.

The authors of Java also nixed MI en toto, under the same arguments as presented at the beginning (too powerful / misused / bad semantics), which makes it difficult to solve a whole class of problems:

Let’s say, for example, you want to add functionality to a whole bunch of classes. You want to steer away from code-gen, since it has its own can o’ worms, and it makes whatever you write a second-class citizen of the world of your language. What you’d like to do is what mixins enables you to do, which is to just add functionality to existing classes. Only problem is that you can’t actually change the code for these classes (e.g. they are in the standard Java libraries), and you really don’t want to copy/paste code for the next week of your life.

What do you do? To make this a bit more concrete, put it into the context of my project. I want to make Java’s collections observable. It would also be nice to have a more generic way to make any object observable. Of course, Java or I cannot read your mind, so you need to specify in some way which methods are mutators and need to send off those events. As a programmer, I’m willing to subclass each of the collections and rewrite the modification methods to call the original and then send the events. What I’m not willing to do, however, is copy and paste the event methods into each class.

You see, each class needs some extra interface that they implement, say ObservableCollection<E>. This interface has some public methods for registering and unregistering for events. It’s trivial enough to make each of these new collections implement this interface, but the problem is that the functionality is identical for each method. There are a number of ways to solve this, most of which are not possible, and the rest of which I don’t have too much regard:

  1. Mixins – not possible, in the strictest sense, in Java. There are a number of workarounds that people have proposed, but these generally either a) cannot add methods to the public interface of the class (i.e. make a subclass at all) and just allow you to add internally visible functionality, or b) have some really ugly proxying that occurs at runtime, and thus both has to plow through Java’s nasty reflection API and suffer the penalties of fighting against the language. There are languages/preprocessors that add special syntax for Mixins, but it would be much preferable to have this done in a nice, Java-esque way. The problem is that the only way to get this ends up generally in the area of modifying and producing JVM bytecode.
  2. Multiple Inheritance – not possible, by design (thanks, guys). There are a few options that are basically less-featureful versions of MI or limitations placed upon it:
    1. MI of abstract classes – you can extend as many abstract classes as you like, and thus can combine functionality this way.
    2. Interfaces can define behavior – basically 2.1, just with a different name. Since this would violate the given semantics of “interface” in Java, I’m not a fan of this idea at all.
    3. Restrictions on the generated class structures – no diamond patterns, nothing that would cause collisions. Whatever would float the Java designer monkeys’ collective boat.
  3. Modifying the base classes – languages like Ruby and Objective C (and plenty others, I’m sure) allow you to modify a class after it has been declared. Languages like Java and C++ explicitly disallow this for non-functional semantic reasons and for implementation reasons. First, as a designer of a class, I should have complete control over what I create. Second, as the compiler, I need to know the entirety of a class to figure out what I should do. This is the curse of more statically typed languages, although you can certainly imagine a more forgiving system (such as the idea of Smalltalk, where we send “messages” to objects, and kinda hope things work in the right way, instead of being strongly coupled to functions in the class of the object, as in C++). However, you can also imagine how awful compiling C++ would be if you both wanted to keep the strong type checking and be able to split class declarations across multiple files (as the mechanism effectively would work). Also, being able to do this to classes after they have been compiled is a much larger and more difficult thing, as this would first require a officially specified and enforced C++ object model (which, in turn, could give us better reflection features in C++). In short, it is a pipe dream to say the least.
    Anywhoo, in Java, this would mean that I could modify the base classes of the collections (which would be easier if they all had a common base class) and modify the behavior there. This would be more in sync with the semantics of inheritance, but it would probably be met with uproar among the contractualists out there (Eiffelists, perhaps).
  4. Centralized eventing service – some static, global service that users call all of the nice “hey, let me know when this object changes” methods on. The methods no longer are on the observable object, and the object can just pass its “hey, this changed” info on to that static service. This is a bit closer to the Decorator pattern, with all the syntax that comes along with it. It is probably the least invasive solution to the problem, and might even be the way that I go. The benefit is that you can make objects observable by just implementing some kind of Observable interface (not the default Java one, of course), and these objects then notify the central service when something has changed. There are issues with this that I’m still working through (and will probably become the next post here).

There is no good way to do this, short of YAJT (Yet Another Java Tool) that tries to make up for the bazillion shortcomings of the language. Another one of the 10,000 frameworks written to do things that Java should be able to do anyways (who wants to write method interceptors in Java themselves, from scratch? Not I.). I’m kinda hoping that before the end of this to have written YAJF (YAJ Framework), a small YAJF, that lets you easily make your objects observable. I would love to write something akin to:

public class Setting implements Observable {
[...]
    @Setter(1, String.class)
    public String setSettingValue(String newval) {
        [...]
    }
}

…and just have the framework come in and do all the plumbing work for you. In this case, the Setter annotation would tell the framework that the information to send out is in the first parameter, and that it is a String. You could imagine even leaving this out in most cases where setters all do the obvious thing (the first parameter is the new value, the return value is the old parameter) and have the eventing just figure stuff out.

Right now I can’t do that, or anything like it, and it frustrates me to no end. More to come, as always.

View Comments to “multiple inheritance or something like it”

  1. [...] This server essentially matches up observable objects with listeners (from the previous post in this series, this is an attempt to get rid of the copy/paste coding that Java forces on the programmer). [...]

blog comments powered by Disqus