Previous Page Next Page

Note: This text was taken from the Smalltalk/V Vwin 2.0 Tutorial and Programming Handbook and was adapted to [incr Tcl]. Thanks to the copyright owners Digitalk, ParcPlace, Cincom to free this document.

Chapter 6
INHERITANCE

This chapter presents [incr Tcl]'s class concept and the concept of inheritance. You'll see inheritance through an example of animal classification. And finally, you'll be introduced to the [incr Tcl] concept of polymorphism.

The Class Hierarchy

In your application [incr Tcl] classes can be arranged in a hierarchy. Each class has an immediate superclass and possibly one or more subclasses, with one or more classes at the top of the hierarchies. You're already familiar with this same system in biology, which arranges living organisms in classes, based on characteristics common to each class. Classes higher in the hierarchy represent more general characteristics, while classes lower in the hierarchy represent more specific characteristics. For example, fish and tree are more abstract than halibut and maple.

In this and later chapters, you will see how you can develop generic problem solutions using abstract classes, and then develop more application-specific solutions which "specialize" the general solution by adding a small amount of code in subclasses.

Inheritance

Inheritance is the [incr Tcl] capability that allows you to re-use software by specializing already existing general solutions. To see this, define a new class hierarchy of animals.

Figure 6.2
Animal Hierarchy

You will be using these same classes again in the following chapters to illustrate collections, graphics and window applications. The class Animal is a subclass of class Object. In turn, classes Bird and Mammal are subclasses of class Animal. Finally, classes Parrot and Penguin are subclasses of class Bird, and classes Dog and Whale are subclasses of class Mammal.

Whenever you define a new class, you also declare its instance variables. The following shows in parentheses the instance variables defined for each class in the animal hierarchy:

Animal (name, knowledge, habitat, topSpeed, color, picture)
Bird (flying)
Parrot (vocabulary)
Penguin ( )
Mammal ( )
Dog (barksAlot)
Whale ( )

Inheritance of Instance Variables

An object inherits all the instance variables: defined in its superclasses in addition to containing the ones defined in its own class. For example, parrots, penguins, dogs and whales each contain the following instance variables:

Parrot
(name, knowledge, habitat, topSpeed, color, picture, flying, vocabulary)
Penguin
(name, knowledge, habitat, topSpeed, color, picture, flying)
Dog
(name, knowledge, habitat, topSpeed, color, picture, barksAlot)
Whale
(name, knowledge, habitat, topSpeed, color, picture)

In this chapter, we'll use the instance variables name, vocabulary and barksAlot. (You'll see the others used in subsequent chapters.) The instance variable name contains a string representing the animal's name, vocabulary contains a string of all words known by a parrot, and barksAlot contains either 1 or 0, depending upon how much a dog barks.

To add the animal classes to your [incr Tcl] environment, start tkcon or wish and copy and paste the following expressions:

package require Itcl

itcl::class Animal {
variable name
variable knowledge
variable habitat
variable topSpeed
variable color
variable picture

method answer: {aString}
method name: {aString}
method talk {}
method habitat: {aHabitat}
method learn:action: {aString aBlock}
method reset {}
method reactTo: {aWord}
}

itcl::class Bird {
inherit Animal
variable flying
}

itcl::class Parrot {
inherit Bird
variable vocabulary

method talk {}
method vocabulary: {aString}
}

itcl::class Penguin {
inherit Bird
}

itcl::class Mammal {
inherit Animal
}

itcl::class Dog {
inherit Mammal
variable barksAlot

method bark {}
method beNoisy {}
method beQuiet {}
method talk {}
}

itcl::class Whale {
inherit Mammal
}

The Methods of the Animal Classes

The methods you have just included for class Animal are answer:, name:, and talk. The code for these methods follows:

itcl::body Animal::answer: {aString} {
# "Display a message for the receiver animal
# on the Transcript window, consisting
# of the animal's class name and name preceding
# aString."
puts "[$this info class] $name: $aString"}

itcl::body Animal::name: {aString} {
# "Change the receiver animal's name to aString."
set name $aString}

itcl::body Animal::talk {} {
# "Display a message that the receiver can't talk."
$this answer: "I can't talk"}

Similarly, the methods for class Parrot are:

itcl::body Parrot::talk {} {
# "Display a message containing the receiver
# parrot's vocabulary."
$this answer: $vocabulary}

itcl::body Parrot::vocabulary: {aString} {
# "Change the receiver parrot's vocabulary
# to aString."
set vocabulary $aString}

And finally, the methods for class Dog are:

itcl::body Dog::bark {} {
# "Have the receiver dog bark by ringing the bell
# and displaying a bark message."
puts -nonewline "\a" ;# Terminal bell
if {$barksAlot} {
$this answer: "Bow Wow, Bow Wow, Bow Wow!!"
} else {
$this answer: "Woof"
}}

itcl::body Dog::beNoisy {} {
# "Change the status of the receiver dog to noisy."
set barksAlot 1
$this answer: "I'll bark a lot"}

itcl::body Dog::beQuiet {} {
# "Change the status of the receiver dog to quiet."
set barksAlot 0
$this answer: "I won't bark much"}

itcl::body Dog::talk {} {
# "Have the receiver dog talk by barking unless
# barksAlot is nil, in which case the superclass
# can decide how to talk."
if {[info exists barksAlot]} {
$this bark
} else {
chain ;# super talk
}}

We didn't define any methods for classes Penguin and Whale. However, these classes inherit the methods of class Animal, so we can create Whale and Penguin objects and send messages to them, as we do later in this chapter.

Inheritance of Methods

Like instance variables, methods are also inherited. When a message is sent to an object, [incr Tcl] looks for the corresponding method defined in the object's class. If it finds the method, [incr Tcl] performs it. If it doesn't find the method, however, [incr Tcl] repeats the procedure in the object's superclass. This process continues all the way to top class. If no method is found in any superclass, a window pops up to display the error.

For example, look at the name: method defined in class Animal. Since this method is not defined in any of Animal's subclasses, the name: method in class Animal is evaluated whenever a name: message is sent to instances of classes Dog, Parrot, Penguin, or Whale.

As another example, look at the talk method in the animal classes. Classes Penguin and Whale inherit talk from class Animal, whereas classes Dog and Parrot re-implement their own versions of talk.

The method inheritance of the animal hierarchy is shown in Figure 6.3.

Figure 6.3
Animal Hierarchy Method Inheritance

The Special command "chain"

Occasionally, you may want to override a method and use a method higher in the superclass chain. Generally, you'd do this whenever the specialized processing done by a method doesn't apply in a particular case. You would instead use the more general processing of a method with the same name which appears higher in the superclass chain.

For example, look at the method talk for class Dog. A dog doesn't know how to talk if its instance variable barksAlot is undefined (has the value ""). In this case, it uses the following message to request the superclass's talk method:

chain

The special command chain represents the same object as the special variable $this talk--the receiver in the method in which it appears. The difference is that when chain is used, [incr Tcl] starts to look for the method not in the receiver object's class, but instead in the superclass of the class containing the method in which chain appears. In the example talk method, the search begins in Mammal, the superclass of class Dog. There is no talk method in class Mammal, but there is one in class Animal, so that one is used.

Creating Animal Objects

Evaluate the following expressions to create and assign to global variables five animal objects: two dogs, a penguin, a parrot and a whale (the animals "talk" to the console window, so first reframe your windows to not overlap the console):

# "creating animals"
Dog Snoopy
Snoopy name: "Snoopy"
Snoopy beQuiet
Dog Lassie
Lassie name: "Lassie"
Lassie beNoisy
Penguin Wally
Wally name: "Wally"
Parrot Polly
Polly name: "Polly"
Polly vocabulary: "Polly want a Cracker"
Whale Moby
Moby name: "Moby"

Polymorphism

Polymorphism is a unique characteristic of object-oriented programming whereby different objects respond to the same message with their own unique behavior. For example, evaluate the following messages to see how the various animals respond to the talk message:

# "let's hear them talk"
Lassie talk
Snoopy talk
Wally talk
Polly talk; Polly talk; Polly talk
Polly vocabulary: "Screeech@#!? Don''t bother me!"
Polly talk
Moby talk
Snoopy beNoisy; Snoopy talk
Lassie beQuiet; Lassie talk

What You've Now Learned

After completing this tutorial, you should now be familiar with:

As always, you can review any of these topics by repeating the sections of the tutorial.

Previous Page Next Page
Back