Jump to content

LittleDogs, Polymorphism, and Frameworks

From EDM2
Revision as of 22:18, 24 July 2012 by Martini (talk | contribs) (Created page with "by Roger Sessions The three pillars of object-ori­ ented programming are en­capsulation, inheritance, and polymorphism. Encapsulation and inheritance are well understood ...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

by Roger Sessions

The three pillars of object-ori­ ented programming are en­capsulation, inheritance, and polymorphism. Encapsulation and inheritance are well understood by most object-oriented program­ mers. However, many object-oriented programmers, even some with years of experience, are confused about poly­ morphism. Many do not even agree as to the meaning of the word.

What is especially interesting about this general state of confusion is that, of these three pillars, polymor­ phism is by far the most important. Encapsulation is nice, but hardly a major advance in the state of the art. Inheritance allows new functionality to be added to existing classes, but this is rarely useful in real life. Polymorphism, on the other hand, is the enabling tech­ nology for frameworks. Frameworks are one of the most important advances in code reusability since the invention of procedures.

Whoever coined the word "polymorphism" made a bad choice. The reason most pro­ grammers do not understand polymorphism is because the word itself is so intimidating. It's easy to relate to encapsu­ lation and inheritance, terms for which we have intuitive feelings. But who can relate to polymorphism?

In this column, let's explore the concept of poly­morphism. We could choose any number of object-orient­ed programming languages for the discussion, because all support this concept, but let's use IBM's SOM technology with the C language bindings.

SOM is IBM's foundational object­ oriented strategy. It has long been asso­ ciated with OS/2, but is now becoming available on other IBM platforms such as MVS and AS400. I like SOM because it is language neutral. I can do my actu­ al programming in many different languages. SOM has other advantages, which I will discuss in future columns. Everything you need to know about polymorphism can be summa­rized in four words. If you can remem­ber these four words, you will under­ stand polymorphism:

 LittleDogs go woof woof

Let's see what this means. The word polymorphism comes from two Greek words, polys, meaning many, and morpho, meaning form. It's often used as an adjective, such as polymor­ phic method. It means that a class can have many forms of a given method, and the object run time can decide which will be used in a given situation. Orfali, Harkey, and Edwards, in their new book The Essential Distributed Objects Survival Guide, say "Polymor­ phism is a high-brow way of saying that the same method can do dif­ferent things, depending on the class that implements it." Let's look at a very simple SOM class.

Listing 1 shows a definition of a dog. Our dog is derived from SOMObject, because in SOM all objects are derived, directly or indirectly, from SOMObject. Our dog has two associated methods, print and bark. A release order is included to ensure upward binary compatibility. An oidl callstyle is used to avoid pass­ ing around an environment variable, which is a good pro­gramming style, but superflu­ous to this discussion.


Listing 1. Dog Definition

 code
 code


Listing 2 shows the dog's implementation. Most of the lines were generated by the SOM precompiler. Two lines were added inside the print method and one line inside the bark method. The imple­mentation of the bark method includes a standard SOM print statement and an invocation of the bark method. When invoking a SOM method in C, we pass the target object as the first parameter. The target object of the bark method is the same as the target object of the print method, thus we just pass through sam­ Self as the target parameter.

Listing 2. Dog Implementation

 code
 code


Notice that the invocation of the bark method inside print uses the form:

 bark(somSelf)

instead of the form in which the code is actually written:

 barkCsomSelf)


The underscore in front of the method name shows how, in the SOM C bind­ings, we invoke a method rather than a procedure. When the print method is invoked, and it in turn invokes bark, what code will be called? The most logical guess would be the bark method that is imple­mented in the same file. This guess appears to be validated by the client pro­gram (Listing 3). The program in Listing 3 instantiates a dog named Snoopie and asks him to print himself. The output that this program generates is:

 My noise is generic dog noise

It's crystal clear that dog's print invokes dog's bark. The output is as expected, and no other candidate bark method exists. Now let's slightly complicate the sit­uation. Listing 4 defines bigDog. big­ Dog is derived from dog. It adds no new methods, but overrides one of the dog methods: bark. Overriding means that it redefines what it means to bark for bigDog.

Listing 4. bigDog Definition

 code
 code


The bigDog implementation of bark is shown in Listing 5. You can see from the print statement that bigDogs bark quite differently than dogs.

Listing 5. bigDog Implementation

 code
 code

Listing 6 defines yet another dog, a littleDog, also derived from dog, and also redefining the bark method. Its implementation is shown in Listing 7.

Listing 6. littleDog Definition

 code
 code


Listing 7. littleDog Implementation

 code
 code

Now we have three versions of bark, one for dog, littleDog, and bigDog. How will the system sort this out? In Listing 8 a client program that instantiates Snoopie (a dog), Toto (alittleDog), and Lassie (a big­ Dog) is shown. It invokes print on each of these ob­jects.

Listing 8. littleDog and bigDog client

 code
 code


Looking back on Listing 2, inside the implementation of dog's print we see a simple invo­ cation of bark. No visible branch code exists. The invocation of bark is unconditional and unequivocal.

So what output do we expect from the program in Listing 8? With stan­dard C procedural calls, we would expect the same version of bark to be invoked in each case. The most likely output from this program would be:

 My noise is generic dog noise 
 My noise is generic dog noise 
 My noise is generic dog noise