42
ceg860 (Prasad) L112Inh 1 Inheritance Reusability Reusability ; Extendibility Extendibility ; Type Type Safety Safety (Minimize Repetition, Accommodate Variation in a Reliable way)

Ceg860 (Prasad)L112Inh1 Inheritance Reusability Extendibility Type Safety Reusability ; Extendibility ; Type Safety (Minimize Repetition, Accommodate Variation

Embed Size (px)

Citation preview

ceg860 (Prasad) L112Inh 1

Inheritance

Reusability Reusability ; Extendibility Extendibility ; Type Safety Type Safety

(Minimize Repetition, Accommodate Variation

in a Reliable way)

ceg860 (Prasad) L112Inh 2

Example : Rectangle is ais a Polygon.

• Polygon ( (Direct) Ancestor ) Methods: translate, rotate, perimeter, etc Fields: listOfVertices, etc

• Rectangle inherits frominherits from Polygon. Methods: translate, rotate, etc Fields: listOfVertices, etc

• Rectangle ( (Direct) Descendant ) Changes Method (for Efficiency only) : perimeter Adds Field: diagonal

ceg860 (Prasad) L112Inh 3

• Invariant Inheritance Rule– The invariant of a class applies to all its

descendants. That is, the class invariant of all ancestors applies to a class.

• Constructors– A constructor establishes the class invariant.– So, a parent’s constructor cannot serve as the

child’s constructor, in general. That is, constructors are not inherited as constructors.

– However, a parent’s constructor is accessible in the child class.

ceg860 (Prasad) L112Inh 4

Example: OrderedList is ais a List. • List

– Methods: empty(), isEmpty(), insert(_), head(), tail().

• OrderedList – New constructor: order(List)– “Inherited” Methods : empty(), isEmpty(),

insert(_), head(), tail()� Modified Semantics

• head() : Returns the smallest element,• tail() : Deletes all occurrences of the smallest element.

ceg860 (Prasad) L112Inh 5

Implementations

• Invariant 1 The array representation is sorted in the non-decreasing order.

– Code shared : empty(), isEmpty(), head()

– Redefined : tail(), insert(_)

• Invariant 2 true

– Code shared : empty(), isEmpty(), insert(_)– Redefined : head(), tail()

ceg860 (Prasad) L112Inh 6

• Behavioral specification ADT OrderedList is not a subtypesubtype of

ADT List.• List: length(tail(L)) + 1 = length(L)• OrderedList: length(tail(L)) + 1 <= length(L)

• Implementation – Class OrderedList is a subclasssubclass of class List.

• Code sharing.

• Notion of Substituitivity– Java uses message signatures.– Eiffel encourages behavioral view.

ceg860 (Prasad) L112Inh 7

OrderedList is not a subtype of List.

List li = new List();

li.insert(5);li.insert(5);li.insert(5);li.tail();li.tail();

// assert:// ! li.isEmpty()

List li = new OrderedList(); li.insert(5);li.insert(5);li.insert(5);li.tail();li.tail();

// exception:// NullPointer

ceg860 (Prasad) L112Inh 8

Polymorphism

Polygon p; Rectangle r; Triangle t;

p := r; p := t;

r := p;

• Polymorphic entity

(reference type)• Descendants

• Polymorphic assignment

• type of rhs conformsconforms to type of lhs

• Illegal assignment

ceg860 (Prasad) L112Inh 9

Polymorphic Assignment p := t;

p

t

1. No transmutation of an object.

2. No change in (run-time) type of the object.

3. No change in (compile-time) type of the entities.

4. Only reference reattachment.

5. Class (type) of t is a descendant of class(type) of p.

ceg860 (Prasad) L112Inh 10

Typing for Inheritance

• Goal– Guarantee at compile-time that no incorrect

run-time type combination can occur.

• Feature Call rule– In x.f, where type of x is based on C, feature f must be defined in one of the ancestors of C.

• legal : p.rotate(), r.rotate(),

p.perimeter(), r.perimeter(), etc

• illegal: p.diagonal

ceg860 (Prasad) L112Inh 11

• Conformance A type U conformsconforms to type T if and only if

the class of U is a descendant of the class of T.

• Type Conformance Rule An attachment of target x and source y (in an

assignment x := y; or in the use of y as an actual argument to a routine call where x is the formal argument) is only valid if the type of y conforms to the type of x.

• Illegal: t := r; p := t; t:= p; • Illegal: p:= r; p.diagonal;

ceg860 (Prasad) L112Inh 12

Static and Dynamic Type Dynamic type

An object only has a dynamic type that never changes during the object’s lifetime. (RTTI)

At any time during the execution, a reference/entity has a dynamic type which is the type of the object it is attached to.

Static typeOnly an entity has a static type, the type

with which it was declared.

ceg860 (Prasad) L112Inh 13

Static-dynamic type consistency

An entity declared of type T may at run-time only become attached to instances of class T.

Instances of class T include direct instances of class T and instances of the descendants of class T.

ceg860 (Prasad) L112Inh 14

• Statically typed language (E.g., Ada)

static-type(entity) = dynamic-type(object)– All type checking done at compile-time

– Efficient but inflexible.

– OOPL Cases: Java’s primitive types, Eiffel’s expanded types, etc.

• Dynamically typed language (E.g., Scheme) Entity type-less; objects carry type-tags.– All type checking done at run-time (inefficient).

– Flexible but inefficient.

– OOPL E.g.: Smalltalk.

P

ceg860 (Prasad) L112Inh 15

• Strongly typed OOPLs (E.g., Eiffel, Java, C++)

dynamic-type(object)

conforms to conforms to

static-type(entity)

– Flexible

Supports heterogeneous data structures (through dynamic binding)

– Reliable

Provides compile-time checks to ensure that there are no undetected type

violations at run-time.

ceg860 (Prasad) L112Inh 16

Type Casting : Assignment Attempt

p := r; … ; r := (Rectangle) p;

• Applications External : Testing objects received over the network,

or retrieved from persistent storage. Internal : Manipulating heterogeneous data. Others : Using general purpose utility classes

(e.g., java.util.Vector)

p

r

ceg860 (Prasad) L112Inh 17

Dynamic Binding• Operations defined for all polygons need not be

implemented identically for all variants. p.perimeter()• Then the dynamic form (type) of the object

attached to p determines which version of the operation will apply at run-time.

• “Automatic dispatch” minimizes explicit run-time type tests.

• Semantics preserving Re-definitions The precondition and postcondition of a routine

applies to any redefinition. Furthermore, the original version may be used in the redefinition.

ceg860 (Prasad) L112Inh 18

Dynamic Binding and Efficiency

• Estimated Overhead : 15% - 30%

• The overhead of dynamic binding is small: an index computationan index computation and an array accessan array access.

• The overhead is constantconstant for both single inheritance and multiple inheritance.

• In non-statically typed languages, this grows with the depth of class hierarchy.

• In-lining and static binding can be used to optimize calls in certain situations.

ceg860 (Prasad) L112Inh 19

C++ Approach : What not to do!

• C++ uses static binding as the default.• Inappropriate because it is an optimization only

when it has the same semantics as dynamic binding; otherwise, it is an error.

• C++ requires programmers to select static or dynamic binding for each method.

• Efficiency concerns must be left to the compiler.• This choice goes against Open-Closed principle.

Rule of thumb• Give prominence to correctness over efficiency by

declaring all methods virtual.

ceg860 (Prasad) L112Inh 20

C# Approach

• Overriding by using signature match not robust for code evolution

class Parent {…}class Child : Parent { public virtual void aMethod(){…}}// illegal in C#class Parent {…public virtual void aMethod(){…}

}

ceg860 (Prasad) L112Inh 21

(cont’d)

class Parent {…

public virtual void aMethod(){…}

}• To override

class Child : Parent {

public virtual override void aMethod(){…}

} • To achieve independence

class Child : Parent {

public virtual new void aMethod(){…}

}

ceg860 (Prasad) L112Inh 22

The meaning of Inheritance : Q is ais a P.

• Module Extension Facility (Subclass)• Enables Q to Reuse Code from P,

modifying/adding methods and fields.

• Openness : Customization by clients.

• Type Specialization (Subtype)• Substituitivity: An instance of Q is usable in all

contexts where an instance of P is expected.

• Values : Instances of Q included in instances of P.

• Operations: Every operation applicable to a P’s instance is also applicable to a Q’s instance.

ceg860 (Prasad) L112Inh 23

Quick Recap of Applications of Inheritance

• Code Reuse– applicable to reference types and expanded types.

class Point { … move(int x, int y) { …}; }class ColoredPoint extends Point { …}{ ColoredPoint cp; … cp.move(4,5); … }

• Polymorphism– applicable to reference types (no method redefinition).

{ Point p = new ColoredPoint(); p.move(4,5);}

• Polymorphism and Dynamic binding– applicable to reference types with method redefinition.

{ Polygon p = new Rectangle(4, 5); p.perimeter();}

ceg860 (Prasad) L112Inh 24

Inter-Class Relationships“A CarOwner is ais a Person and has ahas a Car.”

• Composition (Client Relation) (“has ahas a”)

• Inheritance (Subclass Relation) (“is ais a”) class CarOwner extends Person { Car c; ... }

• The difficulty in choosing between the two relations stems from the fact that when the “is” when the “is” view is legitimate, one can always take the “has” view is legitimate, one can always take the “has” view instead.view instead.

class CarOwner { Car c; Person p; ... }

ceg860 (Prasad) L112Inh 25

Person fields

CarOwner fields

CarOwner fields

Subclass instance ; Client field

Car

Car

ceg860 (Prasad) L112Inh 26

Choosing between Client and Inheritance

• If every instance of P initially has a component of type Q, but that component may need to be replaced at run-time by an object of a different type, make P client of Q.

• (P has a Q.) (Person has a car.)

• If there is a need for entities of type Q to denote objects of type P, or for more polymorphic structures containing objects of type Q of which some may be of type P, make P heir of Q.

• (P is a Q.) (CarOwner is a person.)

ceg860 (Prasad) L112Inh 27

Coupling : Inheritance vs Composition

class P extends Q {} Inheritance exposes a class to the details of its

ancestors’ implementation. So, changes to a class usually requires a recompilation of its descendants, and may sometimes even require modification to the subclass code.

class P { Q q; ... }

Composition usually requires objects to access their components solely through their interfaces, thereby respecting encapsulation.

ceg860 (Prasad) L112Inh 28

public Updates

class P extends Q {}• A public method in Q is applicable to instances of P.• If a new public method is added to Q, it is

automatically available on instances of P.

class P { Q q; ... } • The public methods applicable to instances of P are the

ones explicitly coded in P (unless q is public).• If a new public method is added to Q, it is not

automatically available on instances of P ( via p.q) (unless q is public).

ceg860 (Prasad) L112Inh 29

Delegation and Composition • In delegation, two objects are involved in handling

a message: the receiver object dispatches (delegates) the message to a component object that implements it.

• Delegation is a technique for making composition as powerful for reuse as inheritance. Inheritance can be simulated using delegation by letting the receiver pass a self-reference to the component.

• In general, delegation is dynamic and flexible; inheritance is static and efficient.

ceg860 (Prasad) L112Inh 30

Interface Inheritance

• An object/class has type T if it implements (that is, responds to) the set of messages defined in interface T.

• An object O2 can be substituted for another object O1 if O2 implements the same interface as O1. (Signature-based Subtyping)

• An interface decouples a client from a supplier, facilitating changing of a supplier or reusing a client. (Polymorphism, Dynamic Binding)

ceg860 (Prasad) L112Inh 31

Software ICs (Brad Cox)

Socket (Client)

Compatible IC (Supplier)

Incompatible IC (Supplier)

ceg860 (Prasad) L112Inh 32

• Standardize interfaces and functions for client/supplier interchangeability.– Syntax

• Number of pins, Location of pins, etc

– Static Semantics • “Functionality” of pins : Data, Address, Power supply, etc

– Dynamic Semantics• Voltage/Current/Power spec., Protocols, etc

• “Software Maintenance” – Repair (debugging)– Evolution (new functionality)

ceg860 (Prasad) L112Inh 33

Example : OOP Style vs Procedural Style

Client• Determine the number of elements in a collection.

Suppliers• Collections : Vector, String, List, Set, Array, etc

Procedual Style• A client is responsible for invoking appropriate

supplier function for determining the size.

OOP Style• Suppliers are responsible for conforming to the

standard interface required for exporting the size functionality to a client.

ceg860 (Prasad) L112Inh 34

Client in Scheme

(define (size C) (cond ( (vector? C) (vector-length C) ) ( (pair? C) (length C) ) ( (string? C) (string-length C) ) ( else “size not supported”) )))

(size (vector 1 2 (+ 1 2)))(size ‘(one “two” 3))

ceg860 (Prasad) L112Inh 35

Suppliers and Client in Javainterface Collection { int size(); }

class myVector extends Vector implements Collection {

}class myString extends String

implements Collection { public int size() { return length();}}class myArray implements Collection { int[] array; public int size() {return

array.length;}}

Collection c = new myVector(); c.size();

ceg860 (Prasad) L112Inh 36

Dynamic Binding : Revisited

• Decentralized Software Architectures– Classes manage their own implementations and

do not meddle in each other’s affairs.

(cf. procedural paradigm for dealing with variants.)

• Representation Independence– A client may request an operation, and the

run-time system automatically finds the appropriate implementation.

– Frameworks

ceg860 (Prasad) L112Inh 37

Forms of Inheritance

• Specialization (subtype)– Square is is Rectangle.

• Specification (interface)– Rocket is is

java.lang.Runnable.– Scribble is

MouseMotionListener;

• Combination (multiple

inheritance)– TA is is Teacher, Student.

• Extension (Generalization)– ColoredPoint is is Point.

• Facility Inheritance– Component isis

java.io.Serializable.– Point is is

java.lang..Object. • Construction (C++ private

inheritance)– Set is pvt. List.– Color is pvt. Number.– Stack is pvt. Vector.

(Subclass that is not a Subtype.)

• Limitation– Stack isis Deque.– BoundedStack isis Stack.

ceg860 (Prasad) L112Inh 38

Access Control in C++

• Keywords: public, protected, private

• If a subclass inherits privately, it cannot be

considered a subtype of the original class.

• Constant Members • Immutable fields, which cannot be assigned.

• Friend functions can read/write private

and protected fields within an object.

ceg860 (Prasad) L112Inh 39

Interpretation of private

• Statically typed languages such as C++, Java, etc control visibility on the class-level. That is, an instance of a class can access the private fields of another instance of the same class.

• Dynamically typed languages such as Smalltalk, etc. control visibility on the object-level. No object can access private fields of another object.

ceg860 (Prasad) L112Inh 40

Constant Member and

Friend Function

class E { private: const int i; public: E( int ); int rd( E& e ) { return e.i; }}

E::E(int x) : i(x) { }

Class-level visibility

class Complex { private: double r,i; public: Complex (double a,

double b) { r=a; i=b; } Complex operator +

(Complex & c) { return Complex ( r + c.r, i + c.i ); }}

ceg860 (Prasad) L112Inh 41

Access specifiers control access, not “visibility”.

int i; class A { private: int i; } class B : public A { void f() {i++;} }

Error: A::i is private.

Global i invisible in B.

Access control does not guarantee security.

class Sneaky { private: int safe; public: Sneaky() {safe=10;} int& sorry() {return safe;} }

Sneaky x; x.sorry() = 17;

ceg860 (Prasad) L112Inh 42

Interaction between Overloading and Overriding

To match the message with a method, C++ searches the ancestor classes of an object. The class that defines the message name is further searched to “match” the entire signature. Even if a better match is inheritable, it will not be considered. (Cf. Java)

class A { public: void test(double d){}}class B : public A { public: void test(int i) {}}

Error: B b; b.test(2.5);

Correct: void B::test(double d)

{ A::test(d); }