Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
עזאם מרעי
המחלקה למדעי המחשב
גוריון-אוניברסיטת בן
Inheritance and Substitution
Roadmap
In this chapter we will start to investigate the
concepts of inheritance and substitution:
The intuitive and practical meanings of inheritance
The syntax used to describe inheritance and
substitution
Some of the various forms of inheritance
The benefits and costs of inheritance
2
Abstract idea of Inheritance
We motivated the idea of inheritance with a hierarchy
of categories: Material Object
Living Thing
Mammal
Human Being
Dentist
Ken
Artist
Beth
Shopkeeper
Celia
Cat Dog Platypus
Reptile
Non-Living Thing
Rock
Air
3
Practical Meaning of Inheritance
Data members in the parent are part of
the child
Behavior defined in the parent are part of
the child
Note that private aspects of the parent are
part of the child, but are not always
accessible within the child class
4
Private, Public and Protected
There are now three levels of visibility modifiers:
Private: accessible only within the class definition
(but memory is still found in the child class, just not
accessible)
Public: accessible anywhere
Protected: accessible within the class definition or
within the definition of child classes
Note: Java interprets protected to mean accessible
also within the same package
5
Controlling Access to
Members of a Class in Java
6
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
The following table shows the access to members permitted by
each modifier:
Inheritance is Both
Extension and Contraction
Because the behavior of a child class is strictly
larger than the behavior of the parent,
the child is an extension of the parent (larger)
Because the child can override behavior to make it
fit a specialized situation,
the child is a contraction of the parent (smaller)
This interplay between inheritance and overriding,
extension and contraction, is what allows object-
oriented systems to take very general tools and
specialize them for specific projects
7
The is-a Rule
Our idealization of inheritance is captured in a simple rule-of-thumb:
Try forming the English sentences “An A is-a B”. If it “sounds right” to your ear, then A can be made a subclass of B
A dog is-a mammal, and therefore a dog inherits from mammal
A car is-an engine sounds wrong, and therefore inheritance is not natural
But a car has-an engine
8
Examples9
A Bird is an Animal
A Cat is a Mammal
An Apple Pie is a Pie
A TextWindow is a Window
A Ball is a GraphicalObject
An IntegerArray is an Array
A Bird is a Mammal
An Apple Pie is an Apple
An Engine is a Car
A Ball is a Wall
An IntegerArray is an Integer
Reuse of Code, Reuse of Concept
Why do we use inheritance? Basically there are two major motivations:
Reuse of code. Methods defined in the parent can be made available to the child without rewriting. Makes it easy to create new abstractions.
Reuse of concept. Methods described in the parent can be redefined and overridden in the child. Although no code is shared between parent and child, the concept embodied in the definition is shared.
An example of the latter:
All graphical objects know how to draw
10
Syntax for Inheritance
Languages use a variety of different syntax to indicate inheritance:
class Wall : public GraphicalObject -- C++
class Wall extends GraphicalObject -- Java
class Wall : GraphicalObject -- C#
(defclass Wall (GraphicalObject) () ) -- CLOS
type Wall = object (GraphicalObject) -- Object Pascal
class Wall < GraphicalObject -- Ruby
11
Trees vs. Forests
There are two common views of class hierarchies:
All classes are part of a single large class
hierarchy. Thus, there is one class that is the
original ancestor of all other classes.
Smalltalk, Java and Delphi Pascal do this.
Classes are only placed in hierarchies if they have
a relationship - results in a forest of many small
hierarchies, but no single ancestor.
C++, Objective-C, and Apple Object Pascal do this.
12
A portion of the Little Smalltalk
Hierarchy
13
An Argument for Substitution
Consider the following argument:
Instances of the subclass must possess all data
members associated with the parent class
Instances of the subclass must implement, through
inheritance at least (if not explicitly overridden) all
functionality defined for the parent class
Thus, an instance of a child class can mimic the
behavior of the parent class
It therefore seems reasonable that a variable declared
as a parent, should be able to hold a value generated
from the child class
14
Subclass vs. Subtype
Of course, the problem with this argument is that a child class can override a method and make arbitrary changes
It is therefore useful to define two separate concepts:
To say that A is a subclass of B merely asserts that A is formed using inheritance
To say that A is a subtype of B asserts that A preserves the meaning of all the operations in B
It is possible to form subclasses that are not subtypes; and (in some languages at least) form subtypes that are not subclasses
15
Subclass, Subtype, and
Substitutability
• The term subtype is used to describe the relationship between
types that explicitly recognizes the principle of substitution.
• A type B is considered to be a subtype of A if an instances
of B can legally be assigned to a variable declared as of
type A.
• The term subclass refers to inheritance mechanism
• made by extends, :,
Substitution and Strong Typing17
Statically typed languages place much more emphasis on the principle of substitution than do dynamically typed languages
The reason for this is that statically typed languages tend to characterize objects by their class, whereas dynamically typed languages tend to characterize objects by their behavior
For example, a polymorphic function in a statically typed language can ensure a certain level of functionality only by insisting that all arguments be subclasses of a given class
Since in a dynamically typed language arguments are not typed at all, the same requirement would be simply that an argument must be able to respond to a certain set of messages
Syntax for OverridingSome languages, such as C++, require that the programmer indicate in the parent class
that overriding is a potential:
class GraphicalObject { public:
virtual void draw(); // can be overridden };
Other languages, such as Object Pascal, require a modifier in the child class that
overriding has taken place:
type Ball = object (GraphicalObject) ... procedure draw; override; (* overriding has taken place *)
end
Still other languages (C#, Delphi) require indications in both parent and child.
And some languages (Smalltalk, Java) do not require any indication in either parent
class or child class
18
Interfaces and Abstract Classes
An interface is similar to a class, but does not provide any
implementation. A child class must implements all methods.
A middle ground is an abstract class. Here some methods are
defined, and some (abstract methods) are undefined. A child class
must fill in the definition for abstract methods:
abstract class Window { ... abstract public void paint (); // child class must redefine ...
}
An interface is like an abstract class in which all methods are
abstract
19
Substitution exampleWe would like to create a program for playing various media files.
First, we create an abstract class of a media file.
public abstract class MediaFile {
private String location;
private String name;
public MediaFile(String location, String name){
this.location = location;
this.name = name;
}
public String getLocation(){ return location; }
public String getName(){ return name; }
public abstract void play();
public abstract void pause();
public abstract void stop();
}
Substitution example (cont.)We would like to create a program for playing various media files.
Next, we create concrete classes of media files. For example, a WAV file.
public class AudioWavFile extends MediaFile {
private java.applet.AudioClip clip;
public AudioWavFile(String location, String name){
super(location,name);
}
public void play(){
try {
clip = java.applet.Applet.newAudioClip(
new java.net.URL("file://"+getLocation()+getName()));
clip.play();
} catch (Exception e) {//handle exception... }
}
public void stop(){ //implementation of stop... }
public void pause(){ //implementation of pause... }
{
Substitution example (cont.)We would like to create a program for playing various media files.
Then we can substitute WAV file for media file.
public static void main(String args[]){
Vector mediaFiles = new Vector();
AudioWavFile wavFile =
new AudioWavFile("e:/test/","test.wav");
MediaFile mFile;
mFile = wavFile;
mediaFiles.add(mFile);
//we can add more files to mediaFiles Vector...
mediaFiles.get(0).play();
...
}
Pure Virtual
23
In C++ the idea of an abstract method is termed a pure virtual method, and is indicated using the assignment operator:
A class can have both abstract (or pure virtual) methods and non-abstract methods
A class in which all methods were declared as abstract (or pure virtual) would correspond to the Java idea of an interface
class Window { public:
... virtual void paint () = 0; // assignment makes it pure virtual
... }
Simulating Abstract Methods24
Abstract methods can be simulated even when the language does not provide explicit support for the concept
In Smalltalk, for example, programmers frequently define a method so as to generate an error if it is invoked, with the expectation that it will be overwritten in child classes:
This is not exactly the same as a true abstract method, since it does not preclude the creation of instances of the class
Nevertheless, if an instance is created and this method invoked the program will quickly fail, and hence such errors are easily detected
Forms of InheritanceThe choices between inheritance and overriding, subclass and subtypes, mean that inheritance can be used in a variety of different ways and for different purposes
Many of these types of inheritance are given their own special names. We will describe some of these specialized forms of inheritance:
Generalization or Extension
Specialization
Specification
Construction
Limitation
Variance
25
Specialization Inheritance
The subclass always satisfies the specification
of its superclass; i.e. the subclass is a subtype
„In many cases properties are only added by the
subclass; inherited methods may / may not be
overridden
By far the most common form of inheritance is for
specialization
The substitution principle holds true
26
Specialization Inheritance
A good example is the Java hierarchy of Graphical components:
Component
Label
Button
TextComponent
TextArea
TextField
CheckBox
ScrollBar
Each child class overrides a method inherited from the parent in order to specialize the class in some way
27
Specification Inheritance This is primarily concept
reuse
An abstract superclass defines methods that should be implemented by subclasses; often the subclass doesn’t override any inherited methods
With subclassing for specification, subclasses are realizations of the superclass’s abstract specification
The substitution principle is preserved
28
Specification Inheritance
If the parent class is abstract, we often say that it
is providing a specification for the child class, and
therefore it is specification inheritance
Example:
Java Event Listeners: ActionListener,
MouseListener, and so on are interfaces that specify
behavior, but must be subclasses
A class that implements an interface is always
fulfilling this form of inheritance
29
Inheritance for Construction
If the parent class is used as a source for
behavior, but the child class has no is-a
relationship to the parent
This is code reuse, simply to allow a new
subclass to be implemented quickly
Then we say the child class is using inheritance
for construction
30
Inheritance for Construction
An example might be subclassing the idea of a
Set from an existing List class
Generally not a good idea, since it can break the
principle of substitutability,
But nevertheless sometimes found in practice
More often in dynamically typed languages, such
as Smalltalk
31
Example 1
32
public class List ... { …
}
public class Set extends List{
public void clear() {…}
public boolean isEmpty() {…}
public void add(E e) {…}
public E remove(E e) {…}}
Example 2
33
public interface Stack {
public void push(Object o);
public Object pop();
…
}
class StackImpl extends Vector implements Stack {
…
public void push(Object o){…}
public Object pop() {…}
…
}
Is a stack a vector?
In any case, what’s
wrong with class Stack?
Inheritance for Construction
In Java, a subclass can’t
drop methods inherited
from its superclass
In C++, it is possible to
create a subclass such that
it can reuse its superclass
for implementation
purposes only
34
Inheritance for
Generalization or Extension
When a subclass extends the behavior of the parent class to create a more general kind of object
Consider a graphics display system in which a class Window has been defined for displaying on a simple black-and-white background
You could create a subtype ColoredWindow that lets the background color be something other than white by adding an additional field to store the color and overriding the inherited window display code that specifies the background be drawn in that color
Subclassing for generalization is often applicable when we build on a base of existing classes that we do not wish to modify, or cannot modify
As a rule, subclassing for generalization should be avoided in favor of inverting the type hierarchy and using subclassing for specialization
35
Example36
public class Hashtable {
public int size() {…}
public boolean isEmpty() {…}
public Enumeration keys() {…}
public Enumeration elements() {…}}
public class Properties ... extends Hashtable {
public Object setProperty(String key, String value) {}
public void load(InputStream inStream) throws IOException {}
public void save(OutputStream out, String header) {} }
Inheritance for LimitationIf a child class overrides a method inherited
from the parent in a way that makes it
unusable (for example, issues an error
message), then we call it inheritance for
limitation.
Generally not a good idea, since it breaks
the idea of substitution
Subclassing for limitation clearly
contravenes the principle of substitution,
and should be avoided
But again, it is sometimes found in
practice
37
Inheritance for Variance
Two or more classes that seem to be related,
but its not clear who should be the parent and who should be the child
Example: Mouse and TouchPad and Joystick
One of the classes is then arbitrarily selected to be the parent, with the common code being inherited by the others and device-specific code being overridden
Better solution: abstract out common parts to new parent class, and use subclassing for specialization
38
Subclassing for combination
It is sometimes useful to be
able to define a new class
by inheriting properties
from many superclasses;
this is known as multiple
inheritance
Multiple inheritance brings
with it complexity and is
only supported by a subset
of OOPLs
C++, Python
39
Summary of Forms of Inheritance
Specialization. The child class is a special case of the parent class; in other
words, the child class is a subtype of the parent class.
Specification. The parent class defines behavior that is implemented in the
child class but not in the parent class.
Construction. The child class makes use of the behavior provided by the parent
class, but is not a subtype of the parent class.
Generalization. The child class modifies or overrides some of the methods of
the parent class.
Extension. The child class adds new functionality to the parent class, but does
not change any inherited behavior.
Limitation. The child class restricts the use of some of the behavior inherited
from the parent class.
Variance. The child class and parent class are variants of each other, and the
class-subclass relationship is arbitrary.
Combination. The child class inherits features from more than one parent class.
This is multiple inheritance and will be the subject of a later chapter.
40
Benefits of Inheritance
Software Reuse
Code Sharing
Consistency of Interface
Software Components
Rapid Prototyping
Polymorphism
Information Hiding
41
Cost of Inheritance
Program size
Execution speed
Program Complexity
Message Passing Overhead
This does not mean you should not use inheritance,
But rather than you must understand the benefits, and
weigh the benefits against the costs
42
Chapter Summary
In this chapter we have begun the exploration of inheritance,
A topic we will continue through the next several chapters
Topics we have addressed have included the following:
The meaning of inheritance
The syntax used to describe inheritance and overriding
The idea of substitution of a child class for a parent
The various forms of inheritance
The cost and benefits of inheritance
43