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 Inheritance and Substitution (Budd chapter 8, 10) 3 Abstract idea of Inheritance 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 • We motivated the idea of inheritance with a hierarchy of categories: • 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 6 • 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. 1 7 The is-a Rule 8 Reuse of Code, Reuse of Concept Why do we use inheritance? 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. 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 10 Trees vs Forests Languages use a variety of different syntax to indicate inheritance: 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. 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 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. 11 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. (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. • Is this a valid argument? 12 Subclass vs Subtype • 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. 2 Syntax for Overriding 13 14 Interfaces and Abstract Classes • 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. • 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. 15 16 Forms of Inheritance Specialization Inheritance 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. • 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 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 Label Button TextComponent CheckBox ScrollBar • Each child class overrides a method inherited from the parent in order to specialize the class in some way. •Variance 17 18 Specification Inheritance Inheritance for Construction • 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). • 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. – Example: Java abstract classes 3 19 20 Inheritance for Generalization or Extension Inheritance for Limitation • 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. • 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 22 Inheritance for Variance Inheritance for Combination • 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. • 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 24 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 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. 4 25 Subclasses and Subtypes 26 What is a type? • 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. • 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 28 The Definition of Subtype • Consider how we might define a Stack ADT: • 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. 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 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. • If substitution 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 5 31 Is This a Problem? • What does it take to create a subclass that is not a subtype? – The new class must override at least one method from the parent – It must preserve the type signatures – But it must violate some important property of the parent • Is this common? Not likely. But it shows you where to look for possible problems. 6