Transcript title

Object Oriented Languages
• Objectives:
– Introduction/Overview
– Class Fundamentals
• classes / instances
• slots and methods
Ed Sykes
[email protected]
– Inheritance
• interpretation of inheritance
• code sharing
• single inheritance
• multiple inheritance
• alternatives to multiple inheritance
1
Introduction / Overview
2 main approaches to OO programming languages:
– class-based
– prototype-based
2
Introduction / Overview
Class-based OO programming languages:
A class is a template for the instantiation of objects:
instance == object
• classes are static source code representations
• objects are dynamic entities which live during program
execution. Objects are distinct entities.
3
Introduction / Overview
• Objects exhibit 3 main properties:
– encapsulation
– inheritance
– polymorphism
4
Introduction / Overview
• Encapsulation
– hiding how things are done within the object
– this includes:
• information hiding
• method hiding
5
Introduction / Overview
• Encapsulation
eg., ATM:
properties:
– name/address/phone/account_type
– balance
functionality:
– withdraw()
– deposit()
– get_balance()
6
Introduction / Overview
• Inheritance
– “is a kind of” relation
7
Introduction / Overview
• Polymorphism:
– “many” “forms”
– same general interface, different implementation:
– 2 types of polymorphism:
• compile-time polymorphism
• run-time polymorphism (dynamic binding)
8
Introduction / Overview
• Polymorphism:
– run-time polymorphism (dynamic binding)
– closely related to inheritance
– e.g., load_vehicle(), drive_vehicle()
9
Object Oriented Languages
• Objectives:
– Introduction/Overview
– Class Fundamentals
• classes / instances
• slots and methods
– Inheritance
• interpretation of inheritance
• code sharing
• single inheritance
• multiple inheritance
• alternatives to multiple inheritance
10
Class Fundamentals
Objectives:
• class/instance difference
• classes as abstract data types
• information hiding (encapsulation)
• internal structure of classes
11
Class Fundamentals
Classes are central to OO programming languages
• mechanism for defining sets of objects
+
operations to manipulate them
Term “class” can be interpreted as:
1)
2)
3)
4)
a set of objects
a program structure or module
a factor-like entity which creates objects
a data type
12
Class Fundamentals
1) “class” as a set of objects:
A class defines properties or operations that are common to a
collection of objects.
Objects are manipulated by programs and exist at runtime only.
13
Class Fundamentals
2) “class” as a program structure or module:
- modules encapsulate types, data (variables), and operations.
- modules export some entities (operations)
- modules hide their internal details
- Objects are instances of modules
data
operations
Outside world
14
Class Fundamentals
3) “class” as a factory-like entity:
- Emphasizes dynamic nature of OO languages
- class is a device that can create objects
- opens the way to describe objects in a parametric fashion
 Dynamic unique way for instantiating objects
object
class
data
creates
operations
15
Class Fundamentals
4) “class” as a data type:
- classes in many OO languages are considered to be types
- operations defined over that type are part of the types definition
e.g.,
given a class ‘C’, and a variable v.
v : C;
// variable ‘v’ is of type ‘C’
16
Class Fundamentals
Instances:
- Can be bound, pointed to, and passed in and out of procedures
 first-class citizens
public class Customer{
private String _name;
private String _phone;
Class (definition)
...
public void setName(String Name)
public String getName()
...
Bobby Boogie
Sue MacDonald
(905) 234-2341
(416) 234-7642
Instances
(runtime entities)
17
Class Fundamentals
Typically, the instance creation process allows arguments:
e.g., constructors (default and overloaded):
public Customer(){
System.out.println("In default constructor");
}
public Customer(String name, String phone) {
this();
_name = name;
_phone = phone;
}
public Customer(String name, String phone, double discount){
this(name, phone);
this._discount = discount;
}
18
Class Fundamentals
Slots and Methods:
-2 types:
-
data slots
procedural slots (methods)
class
slots
method
method
19
Class Fundamentals
Slot access:
-Data slots represent variable or constant information
- 2 modes:
-
Read-only (e.g., constant)
Read-write mode (e.g., salary slot)
20
Class Fundamentals
Slot visibility
class
Externally visible slots
Slots visible only within class
21
Class Fundamentals
Slot visibility:
- C++ and Java:
- public
private
protected
- applies to data slots and method slots
public:
- can be referenced, accessed and updated anywhere in the program
private:
- is only visible within the class in which it is defined.
protected:
- can be referenced, accessed and updated within the class and within
all of the subclasses
22
Class Fundamentals
Slot visibility:
- Slots may be allocated in 2 different ways:
1) the slot is allocated in each instance of the class
(default)
2) the slot is allocated once and is shared by all
instances of a class (class variables or static
variables in C++, Smalltalk)
23
Class Fundamentals
Example:
public Customer(){
private static double minimum_labour = 55;
private String _name;
private String _phone;
// $55 per hour
public static void increment_labour_price(double increase){
minimum_labour += increase;
// $60.50 now.
}
}
Invoke by using class name or instance:
Customer.increment_labour_price(5.50);
24
Object Oriented Languages
• Objectives:
– Introduction/Overview
– Class Fundamentals
• classes / instances
• slots and methods
– Inheritance
• interpretation of inheritance
• code sharing
• single inheritance
• multiple inheritance
• alternatives to multiple inheritance
25
Inheritance
- The definition of a new class can rely upon the existence of another
definition.
- Core concept behind OO reusability
- Supports run-time polymorphism
3 views of inheritance:
1) Inheritance is a method for code sharing
2) Logical relationship between classes (specialization/generalization)
3) Type-based account (enables subtypes to be produced given a
definition of a supertype)
26
Inheritance
Definitions:
superclass: both the immediate superclass and all ancestors of
a given class
subclass: converse of superclass
direct subclass: Van is a direct subclass of Truck
indirect subclass: Van is an indirect subclass of Vehicle
superclass
subclass
27
Inheritance
C1: superclass
s11
s12
m11
m12
C2: subclass
m13
s21
s22
s23
m21
m22
28
Inheritance
Instantiated object of type C2
would appear like:
s11
s12
s21
s22
s23
m11
m12
m13
m21
m22
29
Inheritance
For single inheritance there is 1 root class from which
subclasses are derived.
e.g., an inheritance graph
root
C1
C2
C3
B
D
E
F
30
Inheritance
From C3, a class sees only a linear sequence of classes
between it and the root class
e.g., an inheritance chain
root
C1
C2
C3
31
Inheritance
• example:
• Car extends Vehicle:
• in Car, 
–inherited slots (instance variables)
–methods from the Vehicle class (potentially overriden)
32
Inheritance
public class Car extends Vehicle {
...
}
public class Sports_Car extends Car {
...
}
Each class inherits ALL
variables, and methods
from parent class.
33
Inheritance
public class Vehicle {
private String _vin;
private String _make;
private String _model;
private int _year;
private long _odometer;
}
public class Car extends Vehicle {
private float _max_speed;
private int _num_of_passengers;
private int _horse_power;
private float _engine_size;
private String _air_cond;
}
34
Inheritance
• super()
• used for calling parent class constructors
• 1st line in subclass constructor
public Sports_Car() {
super();
}
What method is called here?
public Sports_Car(String owner, String vin, String make,
String model, int year, long odo) {
super(owner,vin,make,model,year,odo);
}
35
what method is called here?
Inheritance
• super.method()
• Within a subclass' overriden method, invoke
parent's method.
public class Building {
...
public
void drawBuilding() { ... }
public
void calcArea() { ... }
}
public class House extends Building
...
public
void calcArea() {
super.calcArea();
...
}
}
// implementation for Building
{
// invoke Building’s calcArea() method
36
Inheritance
• Adding specific methods to the subclass
public class Building {
private int _rooms;
private int _floors;
private int _area;
public
void setRooms(int num) { ... }
public
int getRooms() { ... }
public
void setFloors(int num) { ... }
}
public class House extends Building {
private int _bedrooms;
private int _baths;
public
void setBedrooms(int num) { ... }
public
int getBedrooms() { ... }
public
void setBaths(int num) { ... }
}
37
Abstract Classes
• serves as a place holder in an inheritance graph
• defines those properties and behaviours required
by many other classes
Note:
1) no objects can be created of this class type. It is
merely used as a foundation for subclasses.
2) But you can create references to this class. This is the
principle way we achieve run-time polymorphism.
38
Abstract Classes
public abstract class Convert {
protected double _init;
// initial value
protected double _conv; // converted value
public Convert(double i) { _init = i; }
public double getconv() { return _conv; }
public double getinit()
{ return _init; }
public abstract void compute();
// abstract method
Abstract Method:
• implementation stub
• part of an abstract class
• must be defined in a concrete subclass
39
Abstract Classes
class l_to_g extends Convert {
public l_to_g(double i) { super(i); }
public void compute()
{ // definition of abstract method
_conv = _init / 3.7854;
}
public String toString() {
return (this.getinit() + " litres is " + this.getconv()
“ gallons” );
}
}
40
Abstract Classes
// Fahrenheit to Celsius
class f_to_c extends Convert {
public f_to_c(double i) { super(i); }
public void compute() { // definition of abstract method
_conv = (_init-32) / 1.8;
}
public String toString() {
return (this.getinit() + " Celsius is " +
this.getconv() );
}
}
41
Abstract Classes
public static void main(String[] args) {
Convert p;
// pointer to base class
l_to_g lgob = new l_to_g(5); // litres to gallons object
p = lgob;
p.compute();
System.out.println(p);
f_to_c fcob = new f_to_c(82);
p = fcob;
p.compute();
System.out.println(p);
}
}
would Convert p = new Convert();
work?
why?
42
Abstract Class Eg. in C++
class number
{
protected:
int val:
public:
void setval(int i) {val = i;}
virtual void show() = 0;
// declare show() to be a pure virtual function
};
class hextype : public number
{
public:
void show()
{cout << hex << val <<“\n”;
}
};
class dectype : public number
{
public:
void show()
{cout << val <<“\n”;
}
};
class octtype : public number
{
public:
void show()
{cout << oct << val <<“\n”;
}
};
main()
{
dectype d;
hextype h;
octtype o;
d.setval(20);
d.show();
// Output:
20 - decimal
h.setval(20);
h.show();
// Output:
14 - hexidecimal
o.setval(20);
43
o.show();
// Output:
24 - octal
}
Inheritance as Subtyping
One problem with inheritance is that it should be hidden from
its subtypes (its clients)
In other words:
- the way in which a class is derived should not matter to
users of that class.
- The effects of inheritance can be felt when redefining
subclasses
44
Inheritance as Subtyping
-Subtyping:
- consists of the rules by which objects of one type (class)
are determined to be acceptable in contexts that expect
another type (class) (e.g., downcasting)
- is important since the rules determine the legality of
programs
- should be based on the behaviour of objects
45
Inheritance as Subtyping
-Subtyping:
- if instances of class X meet the external interface of class
Y then X should be a subtype of Y.
Y
X
46
Inheritance as Subtyping
- The concept of a type hierarchy can be represented by
abstract classes (or interfaces)
- behavioural subtyping cannot be deduced without formal
semantic specification of behaviour.
- without these rules, subtypes can only be deduced on the
basis of external interfaces of a syntactic nature (e.g.,
method signatures)
47
Inheritance as Subtyping
- The programmer should be able to specify that the class is
not a subtype of a parent or that the class is a subtype of an
unrelated class (i.e., not its parent)
- The 1st case comes about when the behaviour of the objects
is incompatible with the interface of parent objects.
- The 2nd case arises when the class supports the external
interface of another class without sharing its
implementation
48
Multiple Inheritance
- Natural extension of single inheritance
- corresponds to the application domain in a natural fashion
Inheritance structure is a lattice or Directed Acyclic Graph:
Y
C
B
Searching is required since slots and
methods may not be defined locally
F
E
H
What are the paths from X to Y?
A
X
D
G
49
Multiple Inheritance
- problems with multiple inheritance:
- how to search the inheritance lattice?
- replication of inherited slots (“common roots” problem)
- meaning of the program can be different depending on search
algorithm
Y
C
B
A
X
F
E
H
D
G
50
Approaches to Multiple Inheritance
3 approaches to finding a slot in a multiple inheritance lattice:
- Tree Inheritance
- Graph Inheritance
- Linearized Inheritance
Given the lattice structure:
Z
Y1
Y2
X
51
Tree Inheritance
- We can transform a lattice into a tree:
-involves labeling nodes when conflicts arise
-thus, a class may inherit more than 1 copy of
a slot (or method) but under different names
renaming algorithm is required
Z
Each parent of each class will define a
completely separate set of inherited slots
Y1
Y2
X
Encapsulation is preserved:
i.e., the way in which a class is
derived should not be visible – only
the immediate superclass should be
visible to a class.
52
…but there are problems…
Tree Inheritance
- Problems:
- Tree inheritance radically alters the semantics of inheritance:
- e.g.,
Point
x y
move()
BoundedPoint
HistoryPoint
Want to create a BoundedHistoryPoint…
53
Tree Inheritance
- Problems:
Point
In some examples, where
exactly 1 instance of a
property makes sense tree
inheritance does not work
 it leads to duplication
x y
move()
HistoryPoint
BoundedPoint
x1 y1
move1()
x2 y2
move2()
BoundedHistoryPoint
x3 y3
x4 y4
move3()
move4()
54
Graph Inheritance
Method: Work with the lattice directly.
Search the inheritance graph somehow and resolve conflicts
in some way.
Problem: graph inheritance exposes the inheritance structure (i.e., each class has
knowledge about its set of ancestors):
A
S1
S2
B
- If S1 defines those slots in A for itself,
any side-effects are not seen in S2.
- However, if S1 merely inherits slots from
A, all side-effects will be seen in S2.
The structure of inheritance is exposed
to subclasses
 This violates the concept of encapsulation
55
Graph Inheritance
Solution:
- special-purpose methods are used to resolve conflicts
- e.g., redefine the inherited operation in the child class
- the child can invoke the operations defined by the parent and
then perform any local computation (e.g., super in Java)
A
However, the inheritance structure
is still exposed which leads to problems…
f()
S1
redefined f()
B
S2
56
Graph Inheritance
Problem: A programmer cannot change the use of inheritance within in
a class without potentially breaking some descendent class.
e.g.,
If operation f() is defined only by class Z, it will
be inherited by Y1 and Y2 and then by X. No problems
However, suppose the programmer changes Y2 so
that it no longer inherits from Z but supports the same
behaviour
 Class X will be in error: 2 different f() methods will
be inherited (one from Z via Y1, the other from class Y2)
Z
Z
f()
f()
Y2
Y1 f()
f()
f()
X

Y2
Y1 f()
f’()
f()
X f’()
57
Linearized Inheritance
- method:
1) flatten the inheritance structure into a linear chain without duplicates
2) search the chain in order to find slots (similar to single inheritance)
-The order in which the linearization algorithm
encounters superclasses in important
- Programmer can set the order
A
S1
x
-Suppose S1 and S2 define slot “x”:
-One or the other will be selected; the other will
be masked off by the inheritance algorithm
x
S2
Note: the choice between them is arbitrary unless
more information is given.
B
58
Linearized Inheritance
- problem:
- Inherited classes are not guaranteed communication with their direct ancestors.
- The linearization algorithm can insert unrelated classes between an inheriting
class and one of its direct ancestors.
A
S1
S2

B – S1 – S2 – A
B
Consequence: B cannot communicate directly with S2,
similarly, S1 cannot communicate with A
59
Linearized Inheritance
- inheritance involves search for slots (and methods)
- approach:
- Linearize the graph then remove duplicates from one end or other of the
resulting sequence
- Recall:
Implementation: Pre-order traversal:
- visit each node and put each node
into a list when we visit it
- once we have collected all the nodes,
we can remove all duplicates
Y
C
B
A
X
F
E
H
2 ways to remove duplicates:
- remove duplicates from the front
- remove them from the end.
D
G
60
Linearized Inheritance
- problems:
1) Linearization process inserts unrelated classes between related ones
 programmer is totally unaware… iteration over ancestors can generate
unexpected results.
2) Communication with the “real” parents is very hard to establish.
61
Implemented Multiple Inheritance
Techniques
- In C++ a new kind of superclass is used: virtual superclass
Compiler is instructed to use only 1 copy of the named superclass
Only 1 copy will appear in any of its subclasses
A
B
C
D
62
// This program will not compile
#include “iostream.h”
class base {
public:
int i;
};
class derived1 : public base {
public:
int j;
};
class derived2 : public base {
public:
int k;
};
class derived3 : public derived1, public derived2
public:
int sum;
};
{ // This causes two copies
// of base in derived3
63
main()
{
derived3 ob;
ob.i = 10;
// Which i ?
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k;
cout << ob.i << “ “;
cout << ob.j << “ “ << ob.k
cout << ob.sum;
}
// which i?
// which i ?
<< “ “;
64
Two ways to solve this problem:
1. Use the scope resolution operator.
e.g.,
given ob of type derived3,
ob.derived1::i = 10;
2. Using virtual base classes
65
// Virtual base classes
#include “iostream.h”
class base {
public:
int i;
};
class derived1 : virtual public base {
// derived1 inherits base as virtual
public:
int j;
};
class derived2 : virtual public base {
// derived2 inherits base as virtual
public:
int k;
};
class derived3 : public derived1, public derived2 { // only one copy of the base class though
public:
int sum;
};
main()
{
derived3 ob;
ob.i = 10;
// valid here now because there is only 1 copy of the base
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k;
// valid here
cout << ob.i << “ “ << ob.k << “ “;
// and here too
cout << ob.sum;
}
66
Alternatives to Multiple Inheritance
- Interfaces in Java
- Mixin classes
67
Interfaces
• Are:
– fully abstract classes:
– ALL methods are: abstract
– ALL variables are: public static final
• A class implements 1 or more interfaces
• A class can extend only 1 class
Java supports the principle of multiple inheritance by using
interfaces.
68
Interfaces
• E.g.,
Drivable:
• cars, boats, train, etc.,
(any 2D travelable vehicle/craft)
Flyable
• kite, plane, jet, etc.
(any 3D travelable object (ufo?))
69
Interfaces
public interface Drivable {
int MAX_DEGREE = 45;
void turnLeft(int deg);
void turnRight(int deg);
}
public interface Flyable {
int MAX_DEGREE = 80;
void turnLeft(int deg);
void turnRight(int deg);
void turnUp(int deg);
void turnDown(int deg);
}
recall:
all methods are
implicitly
public abstract
all variables are
implicitly
public static final
70
Interfaces
public class Sailboat extends Boat
implements Drivable
{
public void turnLeft(int deg) {
// my definition of turnLeft
}
public void turnRight(int deg) {
// my definition of turnRight
}
}
71
Mixin Classes
- Similar to abstract classes
- Are useful and highly flexible building blocks to
construct inheritance hierarchies
- alternative approach to multiple inheritance
72
Mixin Classes
class Point2D(xc: Int, yc: Int) {
val x = xc;
val y = yc;
override def toString() = "x = " + x + ", y = " + y;
}
class ColouredPoint2D(u: Int, v: Int, c: String) extends Point2D(u,v){
var color = c;
def setColour(newCol: String): Unit = colour = newCol;
override def toString() = super.toString() + ", col = " + colour;
}
Point2D
val x: Int;
val y: Int;
override def toString();
Our mixin class
ColouredPoint2D
val colour: String;
val setColour(c: String): Unit;
override def toString();
73
Mixin Classes
class Point3D(xc: Int, yc: Int, zc: Int) extends Point2D(xc, yc) {
val z = zc;
override def toString() = super.toString() + ", z = " + z;
}
class ColoredPoint3D(xc: Int, yc: Int, zc: Int, col: String)
extends Point3D(xc, yc, zc)
with ColoredPoint2D(xc, yc, col);
Our mixin class
Rule: A class can only be used as a mixin in the definition of another
class, if this other class extends a subclass of the superclass of the mixin.
Since ColoredPoint3D extends Point3D and
Point3D extends Point2D (the superclass of ColoredPoint2D),
the code is well-formed.
74
Mixin Classes
Point2D
val x: Int;
val y: Int;
override def toString();
Point3D
ColouredPoint2D
val x: Int;
val y: Int;
override def toString();
val colour: String;
val setColour(c: String): Unit;
override def toString();
“Mixed in”
ColouredPoint3D
75