Concepts in Object-Oriented Languages
Mitchell Chapter 10
History
– Object concept used in simulation
1960’s 1970’s 1980’s 1990’s
• Simula
• Smalltalk
– Object-oriented design, systems • C++
– Adapted Simula ideas to C
• Java
– Distributed programming, internet
2
Varieties of Object-Oriented Languages
• class-basedlanguages
– behavior of object determined by its class (in Mitchell
Chapter 10)
• object-based
– objects defined directly (can be done in OCaml)
• multi-methods
– method to execute chosen based on characteristics of the arguments
3
Objects
instance variables, also called member data
hidden functions also possible
– public operations
methods or member functions
can also have public variables in some languages
• Object-oriented program: – send messages to objects
• An object consists of – hidden data
hidden data
msg1
method1
…
…
msgn
methodn
4
Object-Oriented Languages
• An object-oriented language refers to (in this chapter) a programming language that has objects and the following four features (concepts):
– dynamic lookup
– encapsulation (abstraction) – inheritance
– subtyping
• Other topics
– Inheritance is not Subtyping
– A Comparison: Closures as Objects
– A Comparison: Function-Oriented Program Organization
5
Dynamic Lookup
– Dynamic lookup means that when a message is sent to an object, the function code (or method) to be executed is determined by the way that the object is implemented
– Not determined by a static property of the pointer or variable used to name the object.
– In a sense, the object “chooses” how to respond to a message.
– Different objects may respond to the same message in different ways.
6
Dynamic Lookup • Inobject-orientedprogramming,
objectàmessage (arguments)
code depends on object and message
• Inconventionalprogramming, operation (operands)
meaning of operation is always the same
Fundamental difference between abstract data types and objects
7
Example
• Add two numbers x à add (y) different add if x is integer, complex depends on the implementation of x
• Conventional programming add (x, y) function add has fixed meaning, or
different meanings depending on types (overloading), not on implementation
Very important distinction:
Overloading is resolved at compile time.
Dynamic lookup is resolved at run time.
(Dynamic lookup can be thought of as a run-time form of overloading.)
8
Encapsulation
• Builderofaconcepthasdetailedview
• Userofaconcepthas“abstract”view
• Encapsulationseparatesthesetwoviews
– Implementation code: operate on representation
– Client code: operate by applying fixed set of operations provided by implementer of abstraction
9
Comparison with Abstract Data Types
type t
val create : unit -> t val update :
t -> int -> int -> int -> unit val add : t -> t -> t
end
module type MATRIX =
module Matrix : MATRIX = sig struct
class matrix
… (representation)
update(i,j,x) = …set(i,j) of *this* matrix add(m) = …add m to *this* matrix
end
add(x,y)
vs. x à add(y) 10
type t = …
let create (…) : t = …
let update (m:t) (i:int) (j:int) (x:int) =
… set m(i,j) to x …
let add (m1:t) (m2:t) = …
end
Comparison with Abstract Data Types
type t
val create : unit -> t val update :
If add were defined for
complex numbers or integers, …, then one
module type MATRIX =
module Matrix : MATRIX = sig struct
type t = …
let create (…) : t = …
t -> int -> int -> int -> unit
val add : t -> t -> t end
argument—the matrix
The operation appears
let update (m:t) (i:int) (j:int) (x:int) =
to have only one
… set m(i,j) to x …
end Both x and y must be matrices.
y that is added to the matrix x that is receiving the message add(y)
class matrix
… (represen
d
e
n hides the
t
a
f
in
it
t
io
n
)
io
other (hole in scope)
update(i,j,x) = …set(i,j) of *this* matrix
or static overloading
add(m) = …add m to *this* matrix
add(x,y)
vs. x à add(y) 11
end
required
let add (m1:t) (m2:t) = …
Comparison with Abstract Data Types
• Encapsulationviaabstractdatatypes
• SimilaritieswithObjects(SharedAdvantages)
– Both combine functions and data
– Both distinguish between a public interface and a private
implementation
• DisadvantageasComparedtoObject-Oriented Programming
– Not extensible in the same way (see the next example)
12
Abstraction Example
module type INT_QUEUE = sig
type t
val mk_Queue : unit -> t val is_empty : t -> bool val add : int -> t -> t
val first : t -> int
val rest : t -> t
val length : t -> int
end
13
Abstraction Example: Regular Queue
exception Empty
module IntQueue : INT_QUEUE =
struct
type t = int list
let mk_Queue () : t = []
let is_empty (q:t) = match q with | [] -> true
| _::_ -> false
let add (x:int) (q:t) : t = q @ [x]
let first (q:t) : int = match q with | [] -> raise Empty | x::_ -> x
let rest (q:t) : t = match q with | [] -> raise Empty | _::l -> l
let rec length (q:t) : int = match q with | [] -> 0
| _::l -> 1 + length l
end
14
Abstraction Example: Priority Queues
module IntPQueue : INT_QUEUE = struct
type t = int list
let mk_Queue () : t = []
let is_empty (q:t) = match q with | [] -> true
| _::_ -> false
let rec add (x:int) (q:t) : t = match q with | [] -> [x]
| y::l -> if x > y then x::y::l
else y::add x l
let first (q:t) : int = match q with | [] -> raise Empty | x::_ -> x
let rest (q:t) : t = match q with | [] -> raise Empty | _::l -> l
let rec length (q:t) : int = match q with | [] -> 0
| _::l -> 1 + length l
end
15
Comparison with Object-Oriented
• Abstract data types guarantee invariants of data structure
– Client code does not have access to the internal representation
of data
• Limited “reuse”
– Both Queue and PQueue have the same interface
• same number of operations, same names of operations, same types of operations
– Both have same implementation except for “add”
– Cannot apply Queue code to PQueue data, even though
signatures are identical
– Cannot form list of Queues and PQueues
• Implementations can be reused in object-oriented programming
– In queue example, 5 functions have same implementation, can use inheritance to define one from the other.
• Data abstraction is an important part of OOP, the main innovation is that it occurs in an extensible form
16
Example
Consider a hospital system with several wait queues
– The billing department’s queue is first-come, first-serve
– The emergency room’s queue is a priority queue, based on severity of injury or illness.
– It would be useful to treat them uniformly, for example, to calculate the total number of people currently waiting.
– Can’t apply PQueue length to a Queue or vice versa
17
Subtyping and Inheritance
• Interface
– The external view of an object
• Subtyping
– Relation between interfaces
• Implementation
– The internal representation of an object
• Inheritance
– Relation between implementations
18
Subtyping in General
• Inmosttypedlanguages(withoutsubtyping),the application of a function f to an argument x requires some relation between the type of f and the type of x.
– Common case: f is a function of type AàB and x is an expression of type A. In the implementation of the type checker, find a type AàB for f, find a type C for x, and check for equality: A = C.
• Inlanguageswithsubtyping,subtypingisarelationon types based on substitutivity: if C is a subtype of A (written C <: A), then any expression of type C may be used without type error in any context that requires an expression of type A.
– Subtyping case: Find a type AàB for f, find a type C for x, and check that C <: A.
19
Subtyping in General
• Inmosttypedlanguages(withoutsubtyping),the application of a function f to an argument x requires some relation between the type of f and the type of x.
– Common case: f is a function of type AàB and x is an C can be used in any
expression of type A. In the implementation of the type context that requires
checker, find a type AàB for f, find a type C for x, and check
for equality: A = C.
types based on substitutivity: if C is a subtype of A
and C is nat (natural
• Inlanguageswithsubtyping,subtypingisarelationon
(written C <: A), then any expression of type C may be used without type error in any context that requires an expression of type A.
– Subtyping case: Find a type AàB for f, find a type C for x, and check that C <: A.
an expression of type
A. Example: A is int
numbers which
include 0 and positive
integers).
20
Advantages
• Permits uniform operations over various types of data
– Makes it possible, for example, to have heterogeneous data structures that contain data that belong to different subtypes of some common type
– Example:
• A queue containing various bank accounts to be balanced. The “balance” operation is on bank accounts, which has subtypes such as saving, chequing, investment, etc.
• A queue of type bank_account can contain all types of accounts.
• In object-oriented languages:
– allows functionality to be added for subclasses without modifying the general parts of a system defined in the general class.
21
Object Interfaces – The messages understood by an object
• Example:point
– x-coord : returns x-coordinate of a point – y-coord : returns y-coordinate of a point – move : method for changing location
• Theinterfaceofanobjectisitstype.
• Interface
22
Subtyping
• If interface B contains all of interface A, then B objects can
also be used as A objects. Point
x-coord y-coord move
• Coloured_point interface contains Point – Coloured_point is a subtype of Point
Coloured_point x-coord
y-coord
color
move change_colour
23
Inheritance
• Implementation mechanism
• New objects may be defined by reusing implementations of
other objects
• Advantage: saves the effort of duplicating (or reading duplicated) code
– When one class is implemented by inheriting from another, changes to one affect the other
– This has significant impact on code maintenance and modification
• Only need to change in one place
• Must be aware of what classes are affected by the change (all those that inherit the code)
24
class Point private
float x, y public
point move (float dx, float dy); class Coloured_point
private float x, y colour c
public
point move (float dx, float dy); point change_colour (colour newc);
• Subtyping
– Coloured points can be
used in place of points
– Property used by client program
• Inheritance
– Coloured points can be implemented by reusing Point implementation
– Property used by implementer of classes
Example
25
OO Program Structure
• Grouptogetherrelevantdataandfunctions • Class
– Defines behavior of all objects that are instances of the class
• Subtyping
– Place similar data in related classes
• Inheritance
– Avoid re-implementing functions that are already defined
26
Real World OCaml
Chapters 11 and 12
Five Fundamental Properties of OO Programming
In Mitchell, Chapter 10, 4 features/concepts are described. Real World OCaml includes a fifth. Quoting:
• Abstraction
The details of the implementation are hidden in the object, and
the external interface is just the set of publicly accessible methods.
• Dynamic lookup
When a message is sent to an object, the method to be executed is determined by the implementation of the object, not by some static property of the program. In other words, different objects may react to the same message in different ways.
• Subtyping
If an object a has all the functionality of an object b, then we may use a in any context where b is expected.
28
Five Fundamental Properties of OO Programming
• Inheritance
The definition of one kind of object can be reused to produce a new kind of object. This new definition can override some behavior, but also share code with its parent.
• Open recursion
An object’s methods can invoke another method in the same object using a special variable (often called self or this). When objects are created from classes, these calls use dynamic lookup, allowing a method defined in one class to invoke methods defined in another class that inherits from the first.
new
29
Five Fundamental Properties of OO Programming
• Inheritance
The definition of one kind of object can be reused to produce a new kind of object. This new definition can override some behavior, but also share code with its parent.
• Open recursion
An object’s methods can invoke another method in the same
OCaml allows
programming with
object using a special variable (often called self or this). When objects without
new
objects are created from classes, these calls use dynamic lookup,
in another class that inherits from the first.
classes. It also
allowing a method defined in one class to invoke methods defined
includes classes, which are required for
inheritance.
“Almost every notable modern programming language has been influenced by OOP, and you’ll have run across these terms if you’ve ever used C++, Java, C#, Ruby, Python, or JavaScript.”
30