Inheritance is a Smalltalk trait that enables a class to have the same behavior as another class and then change that behavior to provide unique behavior. Inheritance is especially important in that it give the Smalltalk language reusability and extensibility. An example of inheritance is when someone has a program and they want that program to perform more that one function. Inheritance allows the user to extend the existing program to do a required function. The following diagram shows an example of inheritance
Inheritance involves superclasses and subclasses. These classes are similiar in heirarchy to the idea of class, genus, and family classification in the animal kingdom. The heirarchy of inheritance is unlimited. This means that subclasses can have subclasses that can also have subclasses. The Person class in the figure shown below has instance variables called name, address, and phoneNumber. The subclass Customer has the same instance variables. The class Person supports the messages name, address, phoneNumber, name:, address:, and phoneNumber:. The subclass Customer also supports these messages. This is an excellent example of how a class inherits the methods and variables from its superclass.
In inheritance, the subclass always takes on the behavior of the superclasses above it. This behavior can be methods and variables. The following sections will be covered in this chapter. They are inheritance of methods, inheritance of variables, abstract classes, and super vs. self.
Inheritance of Methods
Adding
MethodsaddPerson Creates a new instance of Person and adds it to the collection
In the above figure, the Customer class definition would also like to
manage customer orders. Therefore, the class definiton would add
:customer
Orders,customerOrders:, and addCustomerOrder:. The
customer
class definition can now support all of the messages or methods in
Person and the three new messages.
Overriding Methods
Overriding an inherited method is another tool users have in providing unique
behaviors to a class. If an object receives a message that does have a method
for that message in the class definition, the object works its way up the
heirachy until it finds a method with that name. Inherited methods cannot be
deleted, but there are times when the method of the superclass does not
reflect the needs of the subclass. In this case, the subclass provides a
method by the same name with no code in the method. This process simply
replaces the behavior of the superclass behavior with no behavior.
The figure shown above depicts how Smalltalk works up the heirarchy when
looking for the methods for a message.
Sending Methods to
Instances
In the hierarchy, the instance methods of a subclass inherit the methods of its
superclass. The instance method of a class can receive a message to look for a method
that is not supported by that class. The instance method
looks at itself to see if the method exists within itself. If not, the
instance method
looks at the superclass of the class and proceeds to the parent of its
superclass. Once the method is found, it is then inherited into the instance
of the subclass. This process explains how the instance method of a class can inherit
the method of its superclass.
Inheritance of
Variables
The hierarchy of the Smalltalk language is designed such that the subclasses
inherit the variables of its superclass. Subclasses can also add variables of
its own. Class and instance variables are added to the class by placing them in the
class definition. Classes inherit instance variables differently than they
inherit class variables.
Instance
Variables
Instance variables are defined in the class definition. The instance
methods are found in a class and its subclasses. Data for instance is held in
a data area created by Smalltalk.
The variable Customer has instance variables name, address,
phoneNumber, and customerOrders. These variables include those
instance variables inherited from Person. Each instance has its own
copy of an instance variable, therefore making the instance variable private
to its own instance. Therefore, the variable name must start with a lowercase
letter.
Class
Variables
Class variables are defined in the class definition. The class
methods are found in the class and its subclasses. The local class heirarchy has its own
copy of a class variable. The local class and all its subclasses refer to that
one variable, therefore making the class variable a shared variable.
Sending the addPerson message to Person creates a new instance
of the Person class and add it to the list of all instances.
Persons, a class variable will point to this list of instances. The
code to perform this function is shown below.
addPerson
"Add a new person and store it in the collection.
Return the new instance."
^self persons add: self new
The message self allows the receiving
object to get the contents of the class variable Persons by sending the
addPerson message to itself.
The above figure shows that the instance of Set pointing to
Persons now contains a new instance of Person. The figure shows
how an instance inherits the behavior of its superclass. The instance Set can also take on
a new instance Customer by inheriting the behavior from the superclass
Person.
Class variables allow common sharing of information across a range of
subclasses. All shared variable names start with a capital letter.
Class Instance
Variables
Class instance variables are defined in the class definition. The
class instance methods are found in the defining class and its subclasses.
Each class and its subclasses have a copy of this variable, therefore making
the class instance variable private to the class. Sample code for
accessing data from persons in the instance method is as follows:
persons
"Return the contents of persons. Make sure this
variable is initialized."
persons isNil ifTrue: [persons := Set new].
^persons
Class instance variables allow inheritance of class behavior across the range of
subclasses, but each subclass manages its own class state. It is important to
note that class instance variables are isntance variables that define the
state of the class rather that the instance of the state of the class.
Abstract
Classes
Abstract classes provide behavior across a set of subclasses, but it
will never have its own instances. There are two types of method that
abstract classes provide. The first type provides a complete method
that a subclass inherits. The second type provides a method interface that is
common to all subclasses but contains no code. The figure shown below indicates the
abstract classes as a shaded block.
The abstract classes: Collection, SequenceableCollection,
AdditiveSequenceableCollection, and ArrayedCollection provide a
common set of messages to their subclasses. Each sublcass provides its own
code to override the skeleton method. This skeleton method is defined as the common
protocol to all the subclasses but does not provide a common implementation.
Super vs. Self
The use of super causes the method search to begin with the superclass
of the receiving object. Super is a unique way for the class to add behavior
to the inherited methods and not just replace them. When super is encountered
in the running of the program, Smalltalk looks for a matching method in the
superclass of the receiver.
Super is also used to create instance
variables for every new instance. This is done by providing an
initialize method for each class. An example of creating a new instance
of a class is
Private Class Methods
new
^super new initialize
Self causes the method search to begin with
the receiving object itself. When self is encountered in the running
of the program, Smalltalk looks for a matching method in the receiver.
An example of the use of the self command is self.calculate
which means to send the calculate message to self.
Summary
We have discussed the following in this chapter: