Reminder: The midterm will be in class, on Monday May 20. The
midterm is intended mainly as practice for the final exam, which will be
on Monday June 10, from 7pm to 10pm.
Updatable variables and assignment commands are the essence of imperative programming. There are two basic reasons for using variables: (1) to remember intermediate results (2) to keep track of things changing in the outside world.
The second use of updatable variables is much more fundamental.
If you think of a software module as simulating something in the
real world, e.g. a database system simulates the population of UCSD
students, then it is very natural to update variables as events
happen in the real world, e.g. a student adds a class.
In object-oriented programming, an object is a generalization of a variable
as used to model something in the outside world that can change.
Is using updatable variables to remember intermediate results really necessary? The answer is no, because using nestedfunction fact (n: integer): integer;
var temp: integer;
begin
if n = 0 then temp := 1
else
begin
temp := n-1;
temp := fact(temp);
temp := n*temp
end;
return temp
end;
Temporary variables are inessential.function fact (n: integer): integer;
begin
return ifthenelse( n=0, 1, n*fact(n-1) )
end;
If you think of a software module as simulating something in the real world, e.g. a database system simulates the population of UCSD students, then it is very natural to update variables as events happen in the real world, e.g. a student adds a class.
In object-oriented programming, an object is a generalization of a variable as used to model an entity in the outside world.
Definition: An object is a variable with implementation-independence.
The idea of "representation-independence" is a special case of "implementation-independence", which is an idea that can apply to types, to variables, constants, functions, procedures, and more.
In modeling a real-world entity, what is important is that the model should behave like the entity being modelled, not the details of how the model is implemented.
An object contains data, called its state or private variables, and it has operations that can update its private variables called methods. Methods are sometimes called member functions.
A class is a type of objects. We say that an object is an instance of a class. The operations of an object typically have side-effects, so they are not pure functions.
Objects are thought of as active individuals rather than passive values. Invoking an operation of an object is called sending a message.
Therefore, instead of writing x := plus(x,y) we write send
x "add y" for example. This calls the add method of
the object named x. Every method has an unwritten (implicit) first
argument, which is the object itself.
Individual objects can be declared in the same way as variables:class financial-history =
begin
state cash, receipts, expenses
method init = cash := 0; receipts := []; expenses := [];
method receive (amount) = receipts := amount :: receipts; cash := cash + amount;
method spend (amount) = expenses := amount :: expenses; cash := cash - amount;
method cash? () = return cash;
end;
A class introduces a collection of operations which are imperative. Methods modify objects which have an internal, updatable state.var myaccount: financial-history;
In contrast, an ADT introduces a new type. Any operation on a value of the new type must take the value as an input parameter. With a pure ADT, there are no operations that modify values of the type. Instead, some operations can generate fresh, new values of the type.
Errors are very likely with unlimited direct updating of composite variables.
Consider what happens with the following procedure
if the user gives an address with less than 5 lines:
Classes are typically not pure, because objects can be updated, i.e. modified. However programming with objects is still safer than programming with regular composite types, because updating can only be done through predefined methods.const length = 5;
type address = array [1..length] of string;procedure update (a: address);
var j: integer := 1; s: string;
begin
while (j <= length) and not eof(input) do
begin
readln(s);
a[j] := s;
j := j+1
end
end;