Transcript chapter5

CSSE501 Object-Oriented
Development
Chapter 5: Messages, Instances
and Initialization
 This chapter examines OOP run-time
features:
 Object Creation and Initialization
(constructors)
 Message Passing Syntax
 Accessing the Receiver from within a
method
 Memory Management or Garbage
Collection
Constructors
 A constructor is a function that is implicitly invoked
when a new object is created. The constructor performs
whatever actions are necessary in order to initialize the
object



In C++, Java, C# a constructor is a function with the same name
as the class.
In Python constructors are all named __init__
In Delphi, Objective-C, constructors have special syntax, but can
be named anything. (Naming your constructors create is a
common convention)
class PlayingCard { // a Java constructor
public PlayingCard (int s, int r) {
suit = s;
rank = r;
faceUp = true;
}
...
}
Overloaded Constructors

Constructors are often overloaded, meaning there are a
number of functions with the same name. They are
differentiated by the type signature, and the arguments used
in the function call or declaration:
//C++ example
class Student
{
private:
int idNum;
string name;
double gradePointAverage;
public:
Student();
Student(int);
Student(int, string);
Student(int, string, double);
……
};
Student::Student()
{
idNum = 9999;
name = “J. Smith”;
gradePointAverage = 0.0;
}
Student::Student(int id)
{
idNum = id;
}
……
Student::Student(int id, string nm, double grade)
{
idNum = id;
name = nm;
gradePointAverage = grade;
}
//Java Example
class DigitalCounter {
private int counter;
private int minimum;
private int maximum;
public DigitalCounter() {counter = 0; minimum = 0; maximum = 9;}
public DigitalCounter(int counter, int minimum, int maximum) {
this.counter = counter;
this.minimum = minimum;
this.maximum = maximum;
}
//return the current counter value
public int getCounter() { return counter; }
public int getMinimum() { return minimum; }
public int getMaximum() { return maximum; }
public void setCounter(int counter) { this.counter = counter;}
public void setMinimum(int minimum) {this.minimum = minimum;}
public void setMaximum(int maximum) {this.maximum = maximum;}
}
public void increaseCounter() {
if (counter == maximum) counter = minimum;
else counter = counter +1;
}
Instances
 Now, we could use constructors to create instances of
classes
 C++
Student oneStudent;
Student twoStudent(7766, “Anna Moore”, 3.74);
Instances

Java
//a digital counter DC1 with minimum 0, maximum 9, and
//current counter value 0
DigitalCounter DC1 = new DigitalCounter();
//a digital counter DC2 with minimum 0, maximum 59, and
//current counter value 5
DigitalCounter DC2 = new DigitalCounter(5, 0, 59);
Object Creation
 In most programming languages objects must
be created dynamically, usually using the new
operator:
PlayingCard aCard; // simply names a new variable
aCard = new PlayingCard(Diamond, 3); // creates the
new object
 The declaration simply names a variable, the
new operator is needed to create the new
object value
Messages are not Function Calls
 Recall from chapter 1 that we noted
the following differences between a
message and a function (or
procedure) call
 A message is always given to some
object, called the receiver
 The action performed in response is
determined by the receiver, different
receivers can do different actions in
response to the same message
Message Passing Syntax
 Although the syntax may differ in
different languages, all messages have
three identifiable parts:
aGame.displayCard (aCard, 42, 27);
 The message receiver: aGame
 The message selector: displayCard
 An optional list of arguments: aCard, 42,
27
Statically Types and Dynamically
Typed Languages
 A distinction we will see throughout the
term is between the following:
 A statically typed language requires the
programmer to declare a type for each variable.
The validity of a message passing expression
will be checked at compile time, based on the
declared type of the receiver (e.g., Java, C++,
C#, Pascal).
 A dynamically typed language associates types
with values, not with variables. A variable is just
a name. The legality of a message cannot be
determined until run-time (E.g., Smalltalk,
CLOS, Python).
The Receiver Variable
 Inside a method, the receiver can be accessed
by means of a pseudo-variable
 Called this in Java, C++, C#
 Called self in Smalltalk, Objective-C, Object Pascal
 Called current in Eiffel
function PlayingCard.color : colors;
begin
if (self.suit = Heart) or (self.suit = Diamond)
then color := Red
else color := Black;
end
Implicit Use of This
 Within a method a message expression or a
data access with no explicit receiver is
implicitly assumed to refer to this:
class PlayingCard {
... public void flip () { setFaceUp( ! faceUp ); }
...
}
Is assumed to be equivalent to:
class PlayingCard {
... public void flip () { this.setFaceUp( ! this.faceUp); }
...
}
Memory Recovery
 Because in most languages objects are
dynamically allocated, they must be
recovered at run-time. There are two broad
approaches to this:
 Force the programmer to explicitly say when a
value is no longer being used (e.g., C++, Delphi
Pascal):
delete aCard; // C++ example
 Use a garbage collection system that will
automatically determine when values are no
longer being used, and recover the memory
(e.g., Java, C#, Smalltalk, CLOS).
Memory Errors
 Garbage collection systems impose a run-time
overhead, but prevent a number of potential memory
errors:
 Running out of memory because the programmer
forgot to free values
 Using a memory value after it has been recovered
PlayingCard * aCard = new PlayingCard(Spade,
delete aCard;
cout << aCard.rank();
 Free the same value twice
PlayingCard * aCard = new PlayingCard(Spade, 1);
delete aCard;
delete aCard; // delete already deleted value