Académique Documents
Professionnel Documents
Culture Documents
Non-Strict Inheritance
AKA Inheritance More Powerful Abstraction Mechanism: a subclass is just like the superclass, except for an explicit list of changes:
Additional operations. Additional structure elements. Operations implemented differently, also called overridden operations.
Binding Time
Binding: linking between messages and methods
Compile Time Link Time Execution Time:
Program Init Procedure/function begin Statement Execution
Inclusion Polymorphism: The same entity may refer to objects of different classes, each of which has a different implementation of the same method Inclusion Polymorphism + Overriding = Binding Question
Static Binding (AKA Early Binding): the compiler uses the type of variables to do the binding at a compile (link) time Dynamic Binding (AKA Late Binding): the decision is made at run time based on the type of the actual values
Manager print++
Dynamic Type:
Static typing + Dynamic binding: the right combination of safety and power
Examples: Eiffel, C++, Java, Object-Pascal, TurboPascal, etc.
C++ Example
struct Base { virtual void f() { ... } void g() { ...} }; struct Derived: Base { virtual void f() { ...} // Override f() of Base void g() { ...} // Override g() of Base void h() { ...} } y; Base *px = &y; px->f(); // The right method px->g(); // The wrong method px->h(); // Compile time error! No guarantee that the method exists
Java Example
public class X { public String toString() { return "X"; } public final int addThree(int n) {return n+3; } public static int mul(int a, int b) {return a*b; } } public class Y extends X { public final String toString() { return "Y" + super.toString(); } { What's the binding of super.toString()?
Forms of Overriding
Replacement: The new implementation of an operation replaces the implementation of the operation in the base class.
The only kind of overriding in earlier versions of Eiffel.
Refinement: The new implementation of an operation refines the implementation of the operation in the base class. It reuses the code of the overridden method. Usually:
Overriding method calls inherited method Just like using:
super in Smalltalk, Java Inherited in Turbo-Pascal 7.0 Precursor in Eiffel
Kinds of Refinement
Alpha refinement: the overriding operation calls the overridden operation.
C++, Smalltalk, Java ...
Beta refinement: the overridden operation must call the overriding version explicitly.
Excludes replacement! If the implementation in the superclass does not execute an inner command, then the implementation in the subclass is not executed. Better guarantee of conformance. Simula, BETA.
Alpha refinement involves a forwarding of the message to the subobject. Mechanisms for forwarding to subobject:
Smalltalk and Objective-C: super pseudo-variable refers to largest contained subobject. Object and Turbo Pascal: Inherited keyword refers to the class in which the overridden method was defined. Eiffel: Precursor keyword. C++: Must use scope resolution operator explicitly class CheckedArray: public Array { ... explicit CheckedArray(int len): Array(len) {} ... };
Advantage: The working of the subclass bears more resemblance with that of the superclass. Disadvantages:
The designer of an overriding method must be intimately familiar with the workings of the overridden method. The inner keyword cannot be overridden.
Beta Refinement
struct Object { virtual bool print(void) { if (inner) return; cout << "an object"; return false; } };
Example: FramedWindow subclassOf: Window methods: after draw [self drawFrame] TitledFrameWindow subclassOf: FramedWindow methods: after draw [self drawTitle]
Main drawback:
Confusing semantics!
Class: Military ... methods: generic totalFuelSupply: fuelType [methodCombination: sum] totalFuelSupply: fuelType [ ... ] Class: Army subclassOf: Military methods: totalFuelSupply: fuelType [ ... ]