370 likes | 666 Views
Polymorphism. Principles of Object-Oriented Software Development (Chapter 9). Objectives. Present a more systematic treatment of the concept of subtyping Examine more general notions of polymorphism Introduce methods for formal analysis of types, polymorphism and inheritance. Inheritance.
E N D
Polymorphism Principles of Object-Oriented Software Development (Chapter 9)
Objectives • Present a more systematic treatment of the concept of subtyping • Examine more general notions of polymorphism • Introduce methods for formal analysis of types, polymorphism and inheritance
Inheritance • Uses • During analysis: a technique for discovering taxonomies • During object design: an opportunity reusing code from existing classes • Inheritance during object design • Implementation inheritance • When the subclass and superclass relationship does not represent a taxonomy • Specification inheritance • When the subclass is also a subtype of the superclass • When is it safe to do inheritance?
Liskov Substitution Principle • General principle: • If an object of type S can be substituted in all places where an object of type T is expected, then S is a subtype of T • Object-oriented interpretation: • A class S, which inherits from a superclass T, is considered a subtype of T if S can be substituted in all places where T is expected. • Advantage: new subclasses of T can be written without modifying the methods of T. • Specification inheritance follows the Liskov substitution principle. • How can we formally define this substitution principle?
Outline • The subtype relation • Flavors of polymorphism • Type abstraction
Abstract inheritance • In knowledge representation, inheritance hierarchies are used to represent “is-a” relationships • Abstract inheritance: creating declarative relationships • Declarative taxonomic hierarchies represent predicate logic assertions • These relationships may be non-monotonic • Monotonicity: all properties of the ancestor are preserved by the descendants • Knowledge representation is non-monotonic • “is-not” relationships in addition to “is-a” relationships • Example:
The subtype relation • Subtypes satisfy the monotinicity property • Types can be represented as sets • Union of basic data types and compound types (records, variants, functions) • More formally: • Subtypes correspond to subsets • Subtypes should be compatible with supertypes • Subtype can be used anywhere supertype is used – conformance or substitutability property • Several refinement relationships preserve this property
Subtype Refinement Relations • Sub-range inclusion • Functions • Records • Variants (contravariance)
Sub-range Inclusion • If n n’ and m m’ then the subrange n’..m’ is a subtype of n..m • Example: • 3..5 2..6
Functions • If is a subtype of and is a subtype of then The function is a subtype of the function (Function notation: means function taking parameter of type and return value of type ) Subtype can have looser parameter type and/or tighter return type • Examples: float float is not a subtype of float int int float is not a subtype of float int int int is a not subtype of float int float char is a subtype of float int double int is a subtype of float int
Contravariance Rule for Function Subtyping • Function subtypes can have looser parameter type and/or tighter return type • Intuitively, for a subtype function to be used in place of its supertype: • It must be able to support at least the same set of values as the input parameters of the supertype, and, • It must return no value more than what its supertype returns • A subtype function is a refinement of its supertype, relaxing the restrictions for its calling function, while strengthening its obligations to the calling function.
Records • If type i is a subtype of i, for all i = 1..m, then The record defined by a1:1,…,an:n is a subtype of the record defined by a1:1,…,am:m Note that n could be greater than m the subtype can introduce additional fields not in the supertype • Example: {age:int, speed:int, fuel:int} {age:int, speed:int} • Locations that use the supertype are not aware of the new fields so they are never used in those contexts.
Variants • Variants are also known as unions in C, C++ • If type i is a subtype of i, for all i = 1..m, then A variant [a1: 1 … am:m] is a subtype of [a1:1 … an:n], m n Subtypes of a variant are created by removing one or more of the available variant fields
Objects as Records • An easy way to understand when a subclass is also a subtype of its superclass is to treat objects as records (whose fields can be data or functions). • As a heuristic, methods and attributes of the superclass can be overridden as long as the replacement methods and attributes are subtypes of the originals. • Exception cases: data hiding, generics, self-references
Object Subtyping Examples • type any = { } • type entity = { age : int } • type vehicle = { age : int, speed : int } • type machine = { age : int, fuel : string } • type car = { age : int, speed : int, fuel : string }
Type Conformance • S provides at least the operations of T • for each operation in T, the corresponding operation in S has the same number of arguments • the type of the result of operations of S conform to those of the operations of T • the types of arguments of operations of T conform to those of the operations of S
Outline • The subtype relation • Flavors of polymorphism • Inclusion • Parametric • Overloading • Type abstraction
The Nature of Types • Typing – protection against errors • Static typing – type-checking at compile time • Strong typing – all expressions are type consistent • Untyped languages – flexibility • bitstrings, sets, -calculus • Exceptions to monomorphic typing: • overloading, coercion, subranging, value-sharing (nil)
Polymorphism • The ability to process objects differently depending on their data type • Polymorphic function • A function that can evaluate to and be applied to values of different types. • Polymorphic datatype • A datatype that contains elements of different types. • Polymorphism is not restricted to object types only.
Flavors of polymorphism Inclusion (inheritance) Universal Parametric (generics) Polymorphism Overloading (intersection) Ad-hoc Coercion • Inclusion polymorphism – to model inheritance • Parametric polymorphism – supports generics (templates) • Intersection types – overloading done systematically • Coercion – typecasting
Inheritance – Incremental Modification • Inclusion polymorphism can be understood by regarding inheritance as a means to define the properties of a subtype incrementally, by adding information • Thus, we can characterize inheritance as R = P + M • Result = Parent + Modifier Example: R = {a1,a2} + {a2,a3} = {a1,a2,a3} • Independent attributes: M disjoint from P • Overlapping attributes: M overrules P • 3 types of attributes: • Redefined attributes – redefined by M • Virtual attributes – must be defined in M • Recursive attributes – defined in P
Outline • The subtype relation • Flavors of polymorphism • Type abstraction • Subtype calculus • Intersection types • Bounded polymorphism • Existential types – hiding • Self-reference
Type Abstraction • Purpose: to define the valid typing for the various forms of polymorphism, by expressing them in a syntactic way, using type expressions • Based on lambda calculus • Lambda terms • Variables • Abstraction • Application
More on Lambda Calculus • Laws • Beta conversion (parameter passing) • Extensionality in application • Extensionality in abstraction
More on Lambda Calculus • Substitution
Type Calculi • Subtype calculus – models subtypes • Intersection type calculus – models overloading • Calculus for bounded polymorphism – models generics • Existential type calculus – models data hiding • Recursive type calculus – models inheritance
Simple Type Calculus for Subtypes • Elements • Type assignment • Refinement A type can be a basic type or a function An expression e can be a variable, a typed function abstraction, or application The expression e has type , assuming that type assignments in are valid
Example applications • Determining subtypes • Since Int is a subtype of Double, D is a subtype of S • It can be shown that C++ does not fully support subtyping by providing a type expression that is valid in this calculus but its corresponding C++ program gets a typechecking error
Intersection Type Calculus • Elements • Type assignment • Refinement
Example Application • This gives us a way to express a limited form of overloading by enumerating all possible types • Defining + as an overloaded operator:
Calculus for Bounded Polymorphism • Elements • Type assignment • Refinement
Example Applications • Parametrized types • Specifying semantics for C++ templates
Existential Type Calculus • Extend from calculus for bounded polymorphism • Elements • Type assignment • Refinement
Existential Types and Data Hiding • Existential types enable modeling of abstract data types and hiding by means of packages and type abstraction • Hiding – expressed as existential types • Packages – expressing abstract data types
Calculus for Recursive Types • Extend from calculus for bounded polymorphism • Elements • Type assignment • Refinement
Self-References and Inheritance • Calculus employing recursive types • Recursive type – defined with itself as one of the components • Can be used to characterize the semantics of inheritance more precisely • Object semantics determined by unrolling the recursive type • Express the semantics of dynamic binding
Summary • Subtype refinement relations determine what types are substitutable • There are many flavors of polymorphism of which inclusion polymorphism due to inheritance is one • Semantics of different flavors of polymorphism can be specified using type calculi derived from lambda calculus • Consistency of a programming language’s type system can be analyzed using these calculi