Polymorphism

Douglas Edric Stanley

2007.06.14

I’ll be working with Wolf Ka this week on a new choreography he’s preparing; it’s got a lot of promise, I’m quite happy with what it’s turning into. Anyway, I mention this because he asked me a question that I didn’t really have an answer to: how do you jump from sketch to sketch during a performance when running Processing, i.e. how to build a program-switcher if you will. This is essential for performances where you really want to have controllable chapters or sets or call-them-what-you-will to keep the performance moving.

When he first asked me about it, I made a quick look on the Processing forum but couldn’t find anything to sink my teeth into (let me know if I missed anything). So today we finally took the time to actually investigate the matter, and it turned out to be a pretty easy solve: polymorphism. I knew this method of programming from other languages, but not in Java which I’m only now really getting used to. And so far, at least syntax-wise, I find Java to (thankfully) be clear even enough to show students how it works, which we did this afternoon to my utter delight — and gosh golly, they seemed to get it.

If you don’t know what Polymorphism is, Daniel Shiffman has a great link to a very short page that perfectly explains the concept to anyone who knows a bit already about object-oriented programming: How My Dog Learned Polymorphism.

But if you don’t want to read even that, here’s my take: Polymorphism allows you to make code that calls an object without knowing exactly which object will be called, at least not when you write the code. It allows you to solve that problem later, while the actual code is running. In the case of Wolf’s project, the advantage is pretty clear: he needs the main draw() method to constantly call the draw() method of one of his objects, only he wants the object he calls to change from time to time, depending on the needs of the performance. Early in the performance he wants to tell object no.1 to draw itself, then later object no.2, then object no.3, and you get the point. All at 60 frames per second, which is why you need the program to do it all by itself.

Now, you could do it the ugly way, like this:

int which_sketch = 0;

void draw() {

   switch(which_sketch) {

      case 0:
         doDatThang();
         break;
      case 1:
         doDatUdderThang();
         break;
      case 2:
         goFreakOut();
         break;
      default:
         letItAllHangOut();
         break;

  }

}

So that’s the wrong way. Why is it wrong? Well, it’s okay actually to do it that way, but it’s not good for switching from one program to the next. If you do it this way, you really need to control the flow of your entire code which makes it very sloppy if you want to change anything (which you will). The other problem is that the global variables of doDatThang() are probably going to get mixed up with the global variables of doDatUdderThang(), which is bad. Why don’t you just let the computer do all the work for you, and encapsulate all your variables for one part, or another part, of your program? Then let the computer do all the initialization of your variables for you, and finally let it get rid of those variables whenever you’re ready to move on to the next part of your program. I.e. polymorphism.

There are two ways to do this cleanly in object-oriented programming: through what is called « inheritance », or through what is called « interfacing ». The former is easier so I’ll only talk about it here, but the latter is just as cool so check it out if you’re looking to solve a similar problem. But to understand the later, you need to understand the former, so start at the beginning.

I don’t have the patience to explain everything here, but the idea is basically that you create a non-descript Object that knows two basic methods: void setup() and void draw() (I could have called it startup() and goDoIt(), but I like Processing’s terminology, so I’ll stick with that). Then, once you’ve created that vanilla-flavored Object, you tell all your little sub-programs to all inherit the functions of your vanilla-flavored object. The code looks a little like this:

class Animation {

   void setup() {
   }

   void draw() {
   }

}

class Opening extends Animation {

   void setup() {
     background(255);
   }

   void draw() {
     // do stuff here
   }

}

class Middle extends Animation {

   void draw() {
      background(random(255));
   }

}

class Ending extends Animation {

   void setup() {
      background(0); // take inspiration from the Sopranos
   }

   void draw() {
      // draw stuff here
   }

}

We now have three classes, all of them extensions of the class Animation. And all of them either inherit the method draw() or directly override the version of Animation with their own. Which means that we can call any of these classes and be sure that something will be drawn, all without error.

But the cool thing about Java is that we can create objects out of the Beginning, the Middle, or the Ending, but program them all as if they’re just another type of Animation, letting the program actually decide what type of Animation it will be at run-time.

Animation myAnimation;

void setup() {

   myAnimation = new Opening();

}

void draw() {

   myAnimation.draw();

}

void mousePressed() {

   int random_choice = (int)random(3);

   switch(random_choice) {

      case 0:
         myAnimation = new Opening();
         break;

      case 1:
         myAnimation = new Middle();
         break;

      case 2:
         myAnimation = new Ending();
         break;

   }

}

The cool thing there is that you just have to tell the program that you’ll be using one of three Objects, all of them containing at least one setup() and one draw(), only you’ll let the computer decide while the program is running which object will actually be the one to run.

The Java trick is to actually declare myAnimation as an Object of the class Animation, whereas in reality it is an Object of the class Beginning, Middle, or Ending. This is the polymorphism part. You are telling it that you don’t know which object you are going to be running at any one time in your program, but that at least all three of the different parts will adhere to the two methods available in Animation, namely setup() and draw().

The final nice thing about this trick is that the new Middle(); or new Ending(); takes care of creating and destroying all the variables for you. No need to get rid of all the variables you created with the first object, and no need to worry about global variables stepping on each other.

Well, re-reading all that, I realize it’s a bit dry. Also, be careful, it’s pseudo-code, as I don’t have Processing in front of my from this terminal (my computer just died). You’ll just have to trust me that I’ll make a full-scale class out of it later on. At least the main details are there, and I’m always willing to accept walks-in to explain it to you on-site, only then you’ll have to come to lovely Aix-en-Provence and I’m just about to leave for my summer vacation ;-)