Upload
howard-edwards
View
217
Download
0
Tags:
Embed Size (px)
Citation preview
Type ConformanceContravariance, Covariance
& Closed behavior
CSC 422
Dr. Spiegel
Domains
Groups of classes Foundation, Architecture, Business,
Application
Foundation
The basics Useful across all businesses and
architectures (semantic,structural, fundamental) Date,Time, Angle, Money Stack, Queue, BinaryTree, Set Integer, Boolean, Char
Architecture
Classes valuable for one implementation architecture
Human-interface classes (Window, CommandButton)
Database-manipulation classes (Transaction, Backup)
Machine-communication classes (Port, RemoteMachine)
Business Classes
Useful for one industry or company Relationship classes
(AccountOwnership for bank, Patient Supervision for hospital nurse)
Role classes (Customer, Patient) Attribute classes (properties of
things--Balance, BodyTemperature)
Application
Classes valuable for one application
Event recognizer classes (event daemons, PatientTemperatureMonitor)
Event manager classes (carry out business policy--WarmHypothermicPatient)
Origin of classes for domains
Foundation -buy Architectural--buy from vendors of
hardware or software infrastructure--need tailoring for compatibility with foundation classes
Business--usually have to build; changing a bit with movement to components
Application--almost always have to build
Class versus type
Type is the abstract or external view of a class (purpose of the class, class invariant, attributes, operations, operations’ preconditions and postconditions, definitions and signatures)
Class is the implementation of a type--there may be several implementations, each with its own internal design
Subtypes & Subclasses
Subclass is distinct from subtype If S is a true subtype of T, then S must
conform to T (S can be provided where an object of type T is expected and correctness is preserved when accessor operation of the object is executed
If S is a subclass of T, doesn’t automatically follow that S is a subtype of T
Any class can be made a structural subclass of another, but it won’t necessarily make sense
Invariants, Preconditions and Postconditions
Invariants are class level --limit state space. For example, in a geometric library, a polygon must have 3 or more vertices.
For each of the subtypes of of Polygon, for operations to work, precondition must define vertices and relationships to each other
Postconditions must maintain preconditions + class invariant
You don’t want to end up with the area of a circle from the polygon class or its subtypes
Principle of Type Conformance
Helps avoid problems in class hierarchy
Type of each class should conform to the type of its superclass--this will allow us to effortlessly exploit polymorphism (can pass objects of a subclass in lieu of superclass)
Why is this desirable?
Contravariance and Covariance
Principle of contravariance Every operation’s precondition is no stronger than the
corresponding operation in its superclass (strength goes in opposite direction from class invariant)
Principle of Covariance Every operation’s postcondition is at least as strong as
the corresponding operation in the superclass (I.e., goes in same direction as class invariant. Operation postconditions get, if anything, stronger)
Especially pertinent when subclass overrides a superclass’s operation with an operation of its own
Covariant and Contravariant
Covariant change is when a type moves down the type hierarchy.
Contravariant change is when a type moves up the type hierarchy.
Examples
class Parent { public: virtual void test(const Mammal *cov,const Mammal *con);};
class Child : public Parent { public: void test(const Cat *cov,const Animal *con);};...Parent *p = new Child();p->test(new Dog(), new Mammal());
Examples (con’t)class Parent { public: virtual Mammal *test(){return new Cat();};};
class Child : public Parent { public: virtual Animal *test(){return new Bird();};...Parent *p = new Child();Mammal *result = p->test();
Examples (con’t) - Covariant
class Parent { public: virtual Parent *clone() {return new Parent();};};
class Child : public Parent { public: virtual Child *clone() {return new Child();};};
Idea
Hierarchies which obey the contravariance and covariance principles will “work” others will likely crash.
Do the examples obey the rules?
Closed Types
Example + is closed over the set of integers / is not closed over integers in
arithmetic It is closed in C++
Principle of Closed Behavior
Type conformance alone lets us design sound hierarchies, but it leads to sound design decisions only in read-only situations
When modifier operations are executed we also need the principle of closed behavior--requires that the behavior inherited by a subclass from a superclass should respect the invariant of a subclass.
In practice may mean avoiding inheritance of certain operations or overriding them, reclassify if object as another type if acceptable to application
Example
Class Polygon -- operation move applied to subclass triangle -- OK
Class Polygon -- operation addVertex -- operation applied to triangle would make it a rectangle or trapezoid!
Your design must therefore take into consideration the greatest restraint on target’s behavior (lowest class in hierarchy) or restrict polymorphism or check runtime class of target
Lightweight and Heavyweight Components
Lightweight components utilize classes or components outside of component
Heavy weight components encapsulate everything necessary to do the job
Difference is in degree of encumbrance Heavy weight components more
reusable but harder to understand (also may carry unused code)
Similarities and Differences among Components and Objects
components don’t have to be designed or implemented in object-oriented style
different definitions--in some, executables only; some exclude retention of state
different granularity than objects may be quite large most useful if same encapsulation and
cohesion principles followed as for objects