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

  • View
    216

  • Download
    0

Embed Size (px)

Text of Ceg860 (Prasad)L112Inh1 Inheritance Reusability Extendibility Type Safety Reusability ;...

  • Inheritance Reusability ; Extendibility ; Type Safety

    (Minimize Repetition, Accommodate Variation in a Reliable way)

    L112Inh

  • Example : Rectangle is a Polygon.Polygon ( (Direct) Ancestor )Methods: translate, rotate, perimeter, etcFields: listOfVertices, etcRectangle inherits from Polygon.Methods: translate, rotate, etcFields: listOfVertices, etcRectangle ( (Direct) Descendant )Changes Method (for Efficiency only) : perimeterAdds Field: diagonal

    L112Inh

  • Invariant Inheritance RuleThe invariant of a class applies to all its descendants. That is, the class invariant of all ancestors applies to a class.ConstructorsA constructor establishes the class invariant.So, a parents constructor cannot serve as the childs constructor, in general. That is, constructors are not inherited as constructors. However, a parents constructor is accessible in the child class.

    L112Inh

  • Example: OrderedList is a List. List Methods: empty(), isEmpty(), insert(_), head(), tail(). OrderedList New constructor: order(List)Inherited Methods : empty(), isEmpty(), insert(_), head(), tail()Modified Semanticshead() : Returns the smallest element,tail() : Deletes all occurrences of the smallest element.

    L112Inh

  • 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()

    L112Inh

  • Behavioral specification ADT OrderedList is not a subtype of ADT List.List: length(tail(L)) + 1 = length(L)OrderedList: length(tail(L)) + 1
  • 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

    L112Inh

  • Polymorphism Polygon p; Rectangle r; Triangle t;

    p := r; p := t;

    r := p;Polymorphic entity (reference type)Descendants

    Polymorphic assignmenttype of rhs conforms to type of lhs

    Illegal assignment

    L112Inh

  • Polymorphic Assignment p := t;pt1. 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.

    L112Inh

  • Typing for InheritanceGoalGuarantee at compile-time that no incorrect run-time type combination can occur. Feature Call ruleIn 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(), etcillegal: p.diagonal

    L112Inh

  • Conformance A type U conforms 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;

    L112Inh

  • Static and Dynamic Type Dynamic typeAn object only has a dynamic type that never changes during the objects 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.

    L112Inh

  • Static-dynamic type consistencyAn 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.

    L112Inh

  • Statically typed language (E.g., Ada) static-type(entity) = dynamic-type(object) All type checking done at compile-timeEfficient but inflexible. OOPL Cases: Javas primitive types, Eiffels 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

    L112Inh

  • Strongly typed OOPLs (E.g., Eiffel, Java, C++) dynamic-type(object) 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.

    L112Inh

  • Type Casting : Assignment Attempt p := r; ; r := (Rectangle) p;ApplicationsExternal : 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)pr

    L112Inh

  • Dynamic BindingOperations 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.

    L112Inh

  • Dynamic Binding and EfficiencyEstimated Overhead : 15% - 30%The overhead of dynamic binding is small: an index computation and an array access.The overhead is constant 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.

    L112Inh

  • 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 thumbGive prominence to correctness over efficiency by declaring all methods virtual.

    L112Inh

  • C# ApproachOverriding by using signature match not robust for code evolutionclass Parent {}class Child : Parent { public virtual void aMethod(){}}// illegal in C#class Parent {public virtual void aMethod(){}}

    L112Inh

  • (contd)class Parent {public virtual void aMethod(){}}To overrideclass Child : Parent { public virtual override void aMethod(){}} To achieve independenceclass Child : Parent { public virtual new void aMethod(){}}

    L112Inh

  • The meaning of Inheritance : Q is 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 Ps instance is also applicable to a Qs instance.

    L112Inh

  • Quick Recap of Applications of InheritanceCode Reuseapplicable to reference types and expanded types.class Point { move(int x, int y) { }; }class ColoredPoint extends Point { }{ ColoredPoint cp; cp.move(4,5); }Polymorphismapplicable to reference types (no method redefinition).{ Point p = new ColoredPoint(); p.move(4,5);}Polymorphism and Dynamic bindingapplicable to reference types with method redefinition.{ Polygon p = new Rectangle(4, 5); p.perimeter();}

    L112Inh

  • Inter-Class RelationshipsA CarOwner is a Person and has a Car.Composition (Client Relation) (has a) Inheritance (Subclass Relation) (is a) class CarOwner extends Person { Car c; ... }

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

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

    L112Inh

  • Subclass instance ; Client fieldPerson fieldsCarCar

    L112Inh

  • Choosing between Client and InheritanceIf 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.)

    L112Inh

  • Coupling : Inheritance vs Compositionclass 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.

    L112Inh

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