CPS 343/543 Lecture notes: Message passing,
dynamic binding, and reflection
Coverage: [EOPL] Chapter 5 (pp. 169-171), [PLP], Chapter 9,
§§9.4-9.7 (pp. 497-514), and
[PLPP] Chapter 10, §10.4 (pp. 431-434)
Most central motif of OOP
A program is a collection of autonomous objects,
maintaining their own state and behavior, which collaborate and communicate by
passing messages to each other to solve a problem (so called
anthropomorphic programming model [PLP] p. 491)
C++ programs are not such: some OO code, some imperative code and
as a result are difficult to understand, maintain, and extend.
OOP = objects interacting through dynamically bound messages, and inheritance.
What is an object?
(recall closures)
- occupy space
- can be addressed only using a defined interface
- can be thought of as an abstraction of a computer
History of OOP
- Simula-67 was the origin of the ideas of object-oriented programming
- though the ideas blossomed through Smalltalk
- object-oriented LISP: LOOPS, FLAVORS [PLP] p. 518
Pure OOP
OOP = everything is an object + dynamic binding
Ada, Eiffel, and C++, (and Java to an extent) are wannabe
OO languages.
- these languages have imperative and object-oriented features
- in pure OO languages everything is an object, including classes,
primitives, operators, and so on
Basic characteristics of class definitions
- private variables
- member functions
- friends are bad
Message to method binding
A question of whether a message should bind to
- a method in the class to which
the reference variable pointing to the
receiver was declared to be an instance of (static binding), or
- a method in the class to which the receiver is
an instance of at run-time (dynamic binding).
Dynamic binding
- in the context of OOP typically refers to the binding of methods
to messages
- methods varying dynamically entails much of the power of the OO approach
- main source of power in an OO language
- search for method (code body) to bind to a message starts from the class
to which the receiver currently (i.e., at run-time) is an instance of, and
and proceeds up the class inheritance hierarchy from there (static binding
initiates the search from the class to which the reference variable pointing
to the receiver was declared to be an instance of)
- if no method found anywhere, a run-time error (method not found) is
reported and this is typically the only error in a Smalltalk program
ever detected and reported
- example:
Mammal m;
Cow c;
if (user input)
m = new Cow;
// if static binding used, run method in class Mammal bound to run message here
// if dynamic binding used, run method in class Cow bound to run message here
m.run
else
c = new Cow;
c.run
Why dynamic binding?
- `to allow software systems to be more easily extended during
both development and maintenance' [COPL] p. 461
- allows dynamic polymorphism, consider sorting (written in a general way)
- obviates need for abstract classes (e.g., Fruit class, peel method)
- while other forms of dynamism in languages tend to be compromise
efficiency in the run-time system, dynamic binding involves little overhead
Dynamic vs. static binding
- advantages of each?
- disadvantages of each?
Message to method binding in languages
- Smalltalk
- dynamic by default
- by sending a message to super we can initiate the
search (for the method to bind to the message) in the parent class of
the class to which the sender belongs (i.e., like sending a message
to self with a different entry point for the search (not quite static
binding))
- Java and Eiffel
- dynamic by default
- in Java, preface method with final qualifier to prevent any
subclass from overriding it
- in Eiffel, preface method with frozen
qualifier to prevent any subclass from overriding it
- C++
- static by default (why?)
- preface method with virtual qualifier
for dynamic binding; the search for the method to bind to the message
starts in the class which defines the method
prefaced with the virtual qualifier and proceeds
down the inheritance hierarchy from there to the class to which
the receiver object belongs
- Objective-C, Modula-3, Python, and Ruby use dynamic binding for all
methods
- Simula, C# and Ada 95 use static binding by default and support
dynamic binding as an option
Dynamic binding ambiguity
Do not confuse dynamic binding
of messages to methods with
dynamic allocation and deallocations of objects.
- Smalltalk: manual dynamic allocation, automatic deallocation
- Java: manual dynamic allocation, automatic deallocation
- C++: manual dynamic allocation, manual deallocation
Polymorphism in object-orientation
both serve different purposes and have different implementations [PLP] p. 507
- subtype polymorphism (through inheritance, dynamic binding,
and dynamic method dispatch):
`the ability to use a derived class in a context that expects its
base class' [PLP] p. 498
- explicit parametric polymorphism (also referred to as
generics) supports abstraction over
unrelated types
Generics
`In a nutshell, generics exist for the purpose of abstracting over unrelated
types, something that inheritance does not support (NB: the type
inference system of ML and related languages does suffice to abstract
over unrelated types; ML does not require generics. On the other hand,
while ML provides Euclid-like module types, it does not provide inheritance,
and thus cannot be considered an object-oriented language.)' [PLP] p. 507
- in Java, `single copy of the code can generally be shared
by every instance of a generic' [PLP] p. 507
- in C++ achieved by the compiler generating `multiple copies of the
polymorphic code, one specialized for each needed concrete type' [PLP]
p. 507
Abstract classes
- a abstract method has no body (definition)
- sometimes
called a pure virtual method, especially in the context of C++
- provides a hook for dynamic binding
- any class which has an abstract method is an abstract class
- an interface
is a class with no fields or concrete methods (i.e., only
abstract methods)
Reflection
- the process of reasoning about and/or acting upon oneself
- a way to inspect or modify a program while it is running
- two aspects
- introspection
(or read-only reflection): the ability
for a program to observe and therefore reason about its own state
- intercession: the ability for a program to modify its
own execution state or alter its own interpretation or meaning
- Java supports read-only reflection (e.g.,
which methods does this class have?)
References
| [COPL] |
R.W. Sebesta.
Concepts of Programming Languages.
Addison-Wesley, Boston, MA, Sixth edition, 2003. |
| [EOPL] |
D.P. Friedman, M. Wand, and C.T. Haynes.
Essentials of Programming Languages.
MIT Press, Second edition, 2001. |
| [PLP] |
M.L. Scott.
Programming Language Pragmatics.
Morgan Kaufmann, Amsterdam, Second edition, 2006.
|
| [PLPP] |
K.C. Louden.
Programming Languages: Principles and Practice.
Brooks/Cole, Pacific Grove, CA, Second edition, 2002.
|
|