Inheritance and Substitution (Budd chapter 8, 10) 1
2 Plan 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
Abstract idea of Inheritance 3 We motivated the idea of inheritance with a hierarchy of categories:
4 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 accessible within the child class.
5 Private, Public and Protected 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. default: package access Note: Java interprets protected to also mean accessible within same package
Inheritance is both Extension and Contraction Because the behavior of a child class may be 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. This interplay is ultimately the source of a great deal of the power of OOP. 6
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-a engine sounds wrong, and therefore inheritance is not natural. but a car has-a engine.
Reuse of Code, Reuse of Concept 8 Why do we use inheritance? 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.
9 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
Trees vs Forests 10 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. Huge tree Smalltalk, Java and Delphi Pascal do this. Every object is guarantee to have a minimum level of functionality. 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.
An Argument for Substitution 11 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. (They can also define new functionality). Thus, an instance of a child class can mimic the behavior of the parent class. Thus, an instance of a child class should be indistinguishable from an instance of a parent class if substituted in a similar situation. Principle of substitution Principle of Substitution: if class B is a subclass of class A, then it should be possible to substitute instances of class B for instances of class A in any situation with no observable effect. Isthisa validargument?
Subclass vs Subtype 12 This is not always a valid argument 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 form subtypes that are not subclasses.
Syntax for Overriding 13 Some languages, such as C++, require that the programmer indicate in the parent class that overriding is a potential (virtual methods) Other languages, such as Object Pascal, require a modifier in the child class that overriding has taken place (override) Other languages (C#, Delphi) require indications in both parent and child. Some languages (Smalltalk) do not require any indication in either parent class or child class.
14 Interfaces and Abstract Classes An interface is similar to a class, but does not provide any implementation. A child class must override 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 An interface is like an abstract class in which all methods are abstract.
Forms of Inheritance 15 The 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. Specialization Specification Construction Generalization or Extension Limitation Variance
16 Specialization Inheritance By far the most common form of inheritance is for specialization. A good example is the Java hierarchy of Graphical components in the AWT: Component Label Button TextComponent CheckBox ScrollBar Each child class overrides a method inherited from the parent in order to specialize the class in some way.
17 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 (a variety of specialization inheritance). Example: Java abstract classes
18 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, then we say the child class is using 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 substituability, but nevertheless sometimes found in practice.
19 Inheritance for Generalization or Extension If a child class generalizes or extends the parent class by providing more functionality, but does not override any method. It is called inheritance for generalization. The child class doesn't change anything inherited from the parent, it simply adds new features.
20 Inheritance for Limitation If 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. For example, you have an existing List data type that allows items to be inserted at either end, and you override methods allowing insertion at one end in order to create a Stack. Generally not a good idea, since it breaks the idea of substitution. But again, it is sometimes found in practice.
21 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 Tablet Better solution, abstract out common parts to new parent class, and use subclassing for specialization.
22 Inheritance for Combination Subclass that represents a combination of features from two or more parent classes Example: teaching assistant has characteristics of both teacher and student Inheritance from two or more parent classes is known as multiple inheritance More complex than single inheritance
23 Benefits of Inheritance Software Reuse (avoids rewrite code) Code Sharing (many users: software-ic, many classes) Improved Reliability (the more the code is used ) Consistency of Interface (when 2 classes inherit an interface) Rapid Prototyping Polymorphism Information Hiding
24 Cost of Inheritance Execution speed Program size Message Passing Overhead Program Complexity (overuse: yo-yo problem) This does not mean you should not use inheritance, but rather than you must understand the benefits, and weigh the benefits against the costs.
25 Subclasses and Subtypes To assert that one class is a subclass of another is to simply say it was built using inheritance. It is a statement concerning how it was constructed. To assert that one class is a subtype of another is to say that it preserves the purpose of the original. It is a statement concerning meaning. The distinction between subtype and subclass is important because of their relationship to substitution.
26 What is a type? What do we mean when we use the term type in describing a programming language? A set of values. (The type int, for example, describes - 2147483648 to 2147483647) A set of operations. (We can do arithmetic on ints, not on booleans). A set of properties. (If we divide 8 by 5 we are not surprized when the result is 1, and not 1.6). What about when we consider classes as a system for defining types?
27 The Problem of Defining Types Consider how we might define a Stack ADT: interface Stack { } public void push (Object value); public Object top (); public void pop (); Notice how the interface itself says nothing about the LIFO property, which is the key defining feature of a stack
28 The Definition of Subtype A subtype preserves the meaning (purpose, or intent) of the parent. Problem, meaning is extremely difficult to define. Think about how to define the LIFO characteristics of the stack.
29 The Substitution Paradox There is a curious paradox that lies at the heart of most strongly typed object-oriented programming languages. Substitution is permitted, based on subclasses. That is, a variable declared as the parent type is allowed to hold a value from a child type. Yet from a semantic point of view, substitution only makes sense if the expression value is a subtype of the target variable. Ifsubstitution only makes sense for subtypes and not for all subclasses, why do programming languages based the validity of assignment on subclasses?
The Undecidability of the Subtype Relationship 30 It is trivial to determine if one class is a subclass of another. It is extremely difficult to define meaning (think of the Stack ADT), and even if you can it is almost always impossible to determine if one class preserves the meaning of another. There is no procedure that can determine, in general, if two programs have equivalent behavior
31 Is This a Problem? What does it take to create a subclass that is not a subtype? The new classmustoverride at least one method from the parent It must preserve the type signatures But itmust violate some important property of the parent Is this common? Not likely. But it shows you where to look for possible problems.