Class-Based LanguagesAbadi, M. & Cardelli, L. (1996). A Theory of Objects. New York, Springer. Chapter 2: "Class-Based Languages."CPSC 701.01 Object Theory |
Table of Contents | |
2.2 Method Lookup | ||
Method Suites
|
The naive storage
model
(called embedding) above is not the standard model
used:
|
|
Inheritance
|
When an class has a superclass, method lookup involves
searching the
direct class's method suite, then chaining to the direct parent's
method
suite, to its parent's method suite, etc.
Method suites are organized in a
|
|
self
|
The self reference is always to the object that originated the call (the object that the method would be contained in under the embedded model). | |
intended
illusion
|
Almost all OO languages give the illusion that that
methods
are embedded.
But:
|
2.3 Subclasses and Inheritance | ||
example
|
Extending the previous example
with
a subclass (reCell stands for "restorable cell")::
subclass reCell of cell isThe cell class is extended:
|
|
Inheritance
|
Inheritance is sharing the fields (and initial value)
and the
code
of the methods.
Informally, when we say reCell inherits from cell,
we
mean reCell is a subclass of cell, but reCell
may
override all methods and inherit nothing.
|
|
self
|
self refers to the originating object, so:
|
|
super
|
super refers to the immediate parent class.
|
|
Method
Suits
Revisited
|
|
|
Statically
Typed
Languages
|
In dynamically typed languages, a full method search
has to
be done each time.
In statically typed languages, the type is known at compile time, so the method suite can be collapsed: |
|
Multiple
Inheritance
|
No problem! Except:
|
2.5 Type Information, Lost and Found | ||
Type Info Lost...
|
Subsumption hides type information
|
|
...and Found
|
But reCell::backup is not redundant. It can be
accessed
when g() calls set():
|
|
Back Door
|
Most languages provide a way to get the type information, for
example:
|
|
Problems
|
|
2.6 Covariance, Contravariance, and Invariance | ||
AxB is covariant
|
AxB is read "A cross B" and is the type of the pair
<a,b>
where a:A and b:B.
AxB <: A'xB' provided that A<:A' and B<:B' Argument for the covariance of Ax B
|
|
co/contravariant
|
A->B is a function with argument of type A and result of
type B.
A->B is contravariant in its left argument (the parameter) and covariant in its right argument (the result). A->B <: A'->B' provided that A' <: A and B <: B' Argument for the co/contravariance of A->B
|
|
A#B is invariant
|
A#B is a pair where where the components may be
updated.
A#B is invariant on both arguments (neither covariant nor contravariant). Argument for the invariance of A#B
|
|
Method
arguments are
contravariant
|
Method arguments are directly analogous to the left argument
of A->B.
|
|
Method
return types
are covariant
|
Method return types are directly analogous to
the right
argument of A->B.
|
|
Attributes are
invariant
|
Publicly accessible (updateable) non-method attributes are
invariant
by analogy to A#B.
|
|
Controversy
|
There has been a lot of controversy about the arguments of
methods
and results of methods being covariant or contravariant.
|
2.7 Method Specialization | ||
Method
specialization on override
|
Parameters are generalized (contravariantly), result types are specialized (covariantly) as per section 2.6. | |
Method
specialization on inheritance
|
When a method is inherited from a class c to a subclass c', self
is silently specialized (covariantly!) from InstanceTypeOf(c) to
InstanceTypeOf(c').
We can think of methods as functions with a hidden first parameter that carries the self reference.
|
|
Hmmm...
|
The rules derived for method specialization by inheritance are opposite those for overriding. Why? |
2.8 Self Type Specialization | ||
Motivation
|
It often arises that the return type of a
method should
vary in the subclass.
Consider a method that recursively returns its own type: class c is class c' of c isOn inheritance, m() returns InstanceTypeOf(c), as we expect. But m() may return self, which would be better (and legally) typed as InstanceTypeOf(c'). (But this is not the case in general, because m() may construct a c and return that, which is not a c'.) |
|
Self as a
return type
|
We therefore invent a type Self, which is the type of the
self reference.
We can recode c: class c isAnd we have a more precise typing on inheritance. |
|
Self as an
argument type |
Self can't normally be used as an argument type because that would be a covariant argument. |
|
up |
forward |
||
Rob
Kremer
Last Modified Aug 15, 2005 |
Graduate Course in Software Engineering |