\chapter{Classes and objects}
\label{lec-oo}
\section{Object-oriented programming}

Python is an \myidx{object-oriented programming language} , which
means that it provides features that support \myidx{object-oriented
programming} (\myidx{OOP}).
Object-oriented programming has its roots in the 1960s, but it wasn't
until the mid 1990s that it became the main
\myidx{programming~paradigm} used in the creation of new software. It
was developed as a way to handle the rapidly increasing size and
complexity of software systems, and to make it easier to modify these
large and complex systems over time. 
Up to this point we have been writing programs using a
\myidx{procedural~programming} paradigm. In procedural programming
the focus is on writing functions or \emph{procedures} which operate
on data. In object-oriented programming the focus is on the creation
of \myidx{objects} which contain both data and functionality
together. This lecture is just a very brief introduction to
object-oriented programming and many of the issues are skipped over or
touched on only very lightly. If you want to know more about
object-oriented programming (and it is the dominant form of
programming today), then you should do COMP160 in semester 2.

\section{User-defined compound types}
A class in essence defines a new \myidx{data type} . We have been
using several of Python's built-in types throughout this book
(Integers, Reals, Strings, Lists, Dictionaries etc), but we can also
define new types if we wish to. Defining a new type in Python is very
easy:

\begin{minipage}{\textwidth}
\begin{python}
class CLASSNAME:
   <statement 1>
   <statement 2>
   ...
   <statement n>
\end{python}
\end{minipage}
Class definitions can appear anywhere in a program, but they are
usually near the beginning (after the \pythoninline{import}
statements). The syntax rules for a class definition are the same as
for other compound statements. There is a header which begins with the
keyword, \pythoninline{class}, followed by the name of the class, and
ending with a colon. In most cases, the statements inside a class
definition should be function definitions. Functions defined inside a
class have a special name --- they are called \myidx{methods} of the
class. Although not required by Python, \pythoninline{<statement 1>}
should be a docstring describing the class and
\pythoninline{<statement 2>} should be an \myidx{initialization} method. 
The \pythoninline{\_\_init\_\_} method is a special method that is called
just after a
variable of the class type is \myidx{constructed} or
\myidx{instantiated}. Variables of the class type are also called
\myidx{instances} or \myidx{objects} of that type.

We are
now ready to create our own user-defined type: the \pythoninline{Point}.
Consider the concept of a mathematical point. In two dimensions, a
point is two numbers (coordinates) that are treated collectively as a
single object. In mathematical notation, points are often written in
parentheses with a comma separating the coordinates. For example, $(0,
0)$ represents the origin, and $(x, y)$ represents the point $x$ units to
the right and $y$ units up from the origin.
A natural way to represent a point in Python is with two numeric
values. The question, then, is how to group these two values into a
compound object. The quick and dirty solution is to use a list or
tuple, and for some applications that might be the best choice.
An alternative is to define a new user-defined compound type, also
called a \myidx{class} . This approach involves a bit more effort,
but it has advantages that will become apparent soon.

Here's a simple definition of \pythoninline{Point} which we can
put into a file called \pythoninline{Point.py}:

\begin{minipage}{\textwidth}
\begin{python}
class Point:
    """A class to represent a two-dimensional point"""
    def __init__(self):
        self.x = 0
        self.y = 0 
\end{python}
\end{minipage}

\section{The \pythoninline{\_\_init\_\_} Method and
  \pythoninline{self}}
You will see from the class definition above the special method called
\pythoninline{\_\_init\_\_}. This method is called when a
\pythoninline{Point} object is instantiated.
To instantiate a \pythoninline{Point} object, we call a function
named (you guessed it) \pythoninline{Point}:

\begin{minipage}{\textwidth}
\begin{pythonInteractive}
>>> type(Point)
<type 'classobj'>
>>> p = Point()
>>> type(p)
<type 'instance'>
\end{pythonInteractive}
\end{minipage}
The function \pythoninline{Point()} is called the class
\myidx{constructor}.
The variable \pythoninline{p} is assigned a reference to a new
\pythoninline{Point} object. When calling the function
\pythoninline{Point()}, Python performs some magic behind the
scenes and calls the \pythoninline{\_\_init\_\_} method from
within the class constructor. 

The \pythoninline{\_\_init\_\_} method has a parameter called
\pythoninline{self}. Every class method must have one parameter and
that parameter should be called \pythoninline{self}. The
\pythoninline{self} parameter is a reference to the object on which
the method is being called (more on this below).

\section{Attributes}

The \pythoninline{\_\_init\_\_} method above contains the definition of
two object variables \pythoninline{x} and \pythoninline{y}. Object
variables are also called \myidx{attributes} of the object. Once a
\pythoninline{Point} object has been instantiated, it is now valid to
refer to its attributes:

\begin{minipage}{\textwidth}
\begin{pythonInteractive}
>>> p = Point()
>>> print p.x, p.y
0 0
>>> p.x = 3
>>> p.y = 4
>>> print p.x, p.y
3 4
\end{pythonInteractive}
\end{minipage}

This syntax is similar to the syntax for selecting a variable from a
module, such as \pythoninline{math.pi} or
\pythoninline{string.uppercase}. Both modules and
instances create their own namespaces, and the syntax for accessing
names contained in each, called \myidx{attributes}, is the same. In
this case the attribute we are selecting is a data item from an
instance.
The following state diagram shows the result of these assignments:

\includegraphics[scale=1]{figures/point-fig}

The variable \pythoninline{p} refers to a \pythoninline{Point} object,
which contains two attributes. Each attribute refers to a number. 
The expression \pythoninline{p.x} means, Go to the object
\pythoninline{p} refers to and get the value of \pythoninline{x}. 
The purpose of dot notation is to identify
which variable you are referring to unambiguously. 
You can use dot notation as part of any expression, so the following
statements are legal:

\begin{minipage}{\textwidth}
\begin{python}
print '(%d, %d)' % (p.x, p.y)
distanceSquared = p.x * p.x + p.y * p.y
\end{python}
\end{minipage}
The first line outputs \pythoninline{(3, 4)}; the second line
calculates the value \pythoninline{25}. 

\section{Methods}

\pythoninline{\_\_init\_\_} is an example of a class function or
\myidx{method}. We can add as many methods as we like to a class, and
this is one of the reasons OOP is so powerful. It's quite a different
way of thinking about programming. Rather than having functions that
act on any old data, in OOP, the data carries the required
functionality around with it. Let's add a few methods to our
\pythoninline{Point} class:

\newpage
\begin{minipage}{\textwidth}
\begin{python}
import math

class Point:
	"""A class to represent a two-dimensional point"""
    def __init__(self):
        self.x = 0
        self.y = 0 
	
    def move(self, dx, dy):
        self.x += dx
        self.y += dy
	
    def distance(self, p2):
        dx = self.x - p2.x
        dy = self.y - p2.y
        return math.sqrt(dx*dx+dy*dy)

p1 = Point()
p1.move(2,3)

p2 = Point()
p2.move(5,7)

print p1.distance(p2)
\end{python}
\end{minipage}

If we run the above program, we should get $5.0$ as the output. 

\section{Sameness}
The meaning of the word same seems perfectly clear until you give it
some thought, and then you realize there is more to it than you
expected.
For example, if you say, Chris and I have the same car, you mean that
his car and yours are the same make and model, but that they are two
different cars. If you say, Chris and I have the same mother, you
mean that his mother and yours are the same person.
When you talk about objects, there is a similar ambiguity. For
example, if two \pythoninline{Points} are the same, does that mean
they contain the same data (coordinates) or that they are actually the
same object? 
To find out if two references refer to the same object, use the
\pythoninline{==} operator. For example: 

\begin{minipage}{\textwidth}
\begin{pythonInteractive}
>>> p1 = Point()
>>> p1.x = 3
>>> p1.y = 4
>>> p2 = Point()
>>> p2.x = 3
>>> p2.y = 4
>>> p1 == p2
False
\end{pythonInteractive}
\end{minipage}
Even though \pythoninline{p1} and \pythoninline{p2} contain the same
coordinates, they are not the same object. If we assign
\pythoninline{p1} to \pythoninline{p2}, then the two variables are
aliases of the same object: 

\begin{minipage}{\textwidth}
\begin{python}
>>> p2 = p1
>>> p1 == p2
True
\end{python}
\end{minipage}
This type of equality is called \myidx{shallow equality} because it
compares only the references, not the contents of the objects.
To compare the contents of the objects---\myidx{deep equality} ---we
can add a method called \pythoninline{equals} to our class definition:

\begin{minipage}{\textwidth}
\begin{python}
import math

class Point:
    """A class to represent a two-dimensional point"""
    def __init__(self):
        self.x = 0
        self.y = 0 
	
    def move(self, dx, dy):
        self.x += dx
        self.y += dy
	
    def distance(self, p2):
        dx = self.x - p2.x
        dy = self.y - p2.y
        return math.sqrt(dx*dx+dy*dy)
	
    def equals(self, p2):
        return (self.x == p2.x) and (self.y == p2.y)

p1 = Point()
p1.move(2,3)

p2 = Point()
p2.move(2,3)

print p1 == p2
print p1.equals(p2)
\end{python}
\end{minipage}
The output of the above program is:

\begin{minipage}{\textwidth}
\begin{pythonOutput}
False
True
\end{pythonOutput}
\end{minipage}
Of course, if the two variables refer to the same object, they have
both shallow and deep equality.

\section{Rectangles}
Let's say that we want a class to represent a rectangle. The question
is, what information do we have to provide in order to specify a
rectangle? To keep things simple, assume that the rectangle is
oriented either vertically or horizontally, never at an angle.
There are a few possibilities: we could specify the center of the
rectangle (two coordinates) and its size (width and height); or we
could specify one of the corners and the size; or we could specify
two opposing corners. A conventional choice is to specify the
upper-left corner of the rectangle and the size.
Again, we'll define a new class called \pythoninline{Rectangle} in a
new file called \pythoninline{Rectangle.py}:

\begin{minipage}{\textwidth}
\begin{python}
from Point import *

class Rectangle:
    def __init__(self):
        self.corner = Point()
        self.width = 100
        self.height = 100

box = Rectangle()
print box.corner.x, box.corner.y, box.width, box.height
\end{python}
\end{minipage}
Which, when run, produces the following output:

\begin{minipage}{\textwidth}
\begin{pythonOutput}
0 0 100 100
\end{pythonOutput}
\end{minipage}
Note that within a \pythoninline{Rectangle} we have created a member
attribute which is itself an object --- in this case a
\pythoninline{Point}. 
The dot operator composes. The expression \pythoninline{box.corner.x}
means, \textit{Go to the object box refers to and select the attribute
named corner; then go to that object and select the attribute named
\pythoninline{x}}. 
The figure shows the state of this object:

\includegraphics[scale=1]{figures/rectangle-fig}

Classes (and hence objects) can be made as complex as we like, and as
programs become larger, hiding this data complexity becomes
increasingly important. This is the notion of \myidx{abstraction} and
\myidx{information hiding}. The power of using classes and objects
arises because the objects can be viewed abstractly with little
thought to how the class is actually implemented. Just like we have
been using strings, lists and dictionaries without thinking about how
they have been implemented, we can also create our own types for later
use, without worrying about their internals.

\section{Instances as return values}

Functions and methods can also return instances. For example, we may
want to calculate the centre of the rectangle. We can do that by
adding a \pythoninline{centre} method to our class definition:

\begin{minipage}{\textwidth}
\begin{python}
from Point import *

class Rectangle:
    def __init__(self):
        self.corner = Point()
        self.width = 100
        self.height = 100

    def centre(self):
        c = Point()
        c.x = self.corner.x + self.width/2.0
        c.y = self.corner.y + self.height/2.0
        return c

box = Rectangle()
print box.corner.x, box.corner.y, box.width, box.height
c = box.centre()
print c.x, c.y
\end{python}
\end{minipage}
If we execute this program, we get:

\begin{minipage}{\textwidth}
\begin{pythonOutput}
0 0 100 100
50.0 50.0
\end{pythonOutput}
\end{minipage}

\section{Objects are mutable}

We can change the state of an object by making an assignment to one
of its attributes. For example, to change the size of a rectangle
without changing its position, we could modify the values of
\pythoninline{width} and \pythoninline{height}: 

\begin{minipage}{\textwidth}
\begin{python}
box.width = box.width + 50
box.height = box.height + 100
\end{python}
\end{minipage}

\section{Copying}

Aliasing can make a program difficult to read because changes made in
one place might have unexpected effects in another place. It is hard
to keep track of all the variables that might refer to a given
object.
Copying an object is often an alternative to aliasing. The copy
module contains a function called \pythoninline{copy} that can
duplicate any object: 

\begin{minipage}{\textwidth}
\begin{pythonInteractive}
>>> import copy
>>> p1 = Point()
>>> p1.x = 3
>>> p1.y = 4
>>> p2 = copy.copy(p1)
>>> p1 == p2
False
>>> p1.equals(p2)
True
\end{pythonInteractive}
\end{minipage}

Once we import the copy module, we can use the copy method to make a
new \pythoninline{Point}. \pythoninline{p1} and \pythoninline{p2} are
not the same point, but they contain the same data. 
To copy a simple object like a \pythoninline{Point}, which doesn't contain any
embedded objects, copy is sufficient. This is called
\myidx{shallow~copying}. 
For something like a \pythoninline{Rectangle}, which contains a
reference to a \pythoninline{Point}, copy doesn't do quite the right
thing. It copies the reference to the \pythoninline{Point} object, so
both the old \pythoninline{Rectangle} and the new one refer to a
single Point. 

If we create a box, \pythoninline{b1}, in the usual way and then make
a copy, \pythoninline{b2}, using copy, the resulting state diagram
looks like this: 

\includegraphics[scale=1]{figures/rectangle2-fig}

This is almost certainly not what we want. Can you think why?
\begin{answerspace}




zend
\end{answerspace}
Fortunately, the copy module contains a method named
\pythoninline{deepcopy} that 
copies not only the object but also any embedded objects. You will
not be surprised to learn that this operation is called a
\myidx{deep copy} .

\begin{minipage}{\textwidth}
\begin{pythonInteractive}
>>> b2 = copy.deepcopy(b1)
\end{pythonInteractive}
\end{minipage}
Now \pythoninline{b1} and \pythoninline{b2} are completely separate objects.

\section{Glossary}

 \begin{description}
 \item[abstraction:]Hiding details of implementation behind a
programming structure such as a class. Essentially abstracting away
the details.
 \item[attribute:]One of the named data items that makes up an
   instance.
 \item[class:]A user-defined compound type. A class can also be
   thought of as a template for the objects that are instances of it.
 \item[constructor:]A method used to create new objects.
 \item[deep copy:]To copy the contents of an object as well as any
   embedded objects, and any objects embedded in them, and so on;
   implemented by the deepcopy function in the copy module.
 \item[deep equality:]Equality of values, or two references that point
   to objects that have the same value.
 \item[information hiding:]See abstraction.
 \item[initialization:]The \pythoninline{\_\_init\_\_} method is used
to initialize an object when it is created.
 \item[instantiate:]To create an instance of a class.
 \item[instance:]An object that belongs to a class.
 \item[method:]A function that is belongs to a class.
 \item[object:]A variable whose type is defined by its class.
 \item[object oriented programming:]Programming by defining classes
and instantiating objects. Classes contain data and functions.
 \item[procedural programming:]Programming where functions and data
are represented separately. This book (but not this chapter) has been
concerned mostly with procedural programming.
 \item[shallow copy:]To copy the contents of an object, including any
   references to embedded objects; implemented by the copy function in
   the copy module.
 \item[shallow equality:]Equality of references, or two references
   that point to the same object.

 \end{description}

\newpage
\section{Laboratory exercises}

\begin{enumerate}
\item Add an \pythoninline{equals} method to the
\pythoninline{Rectangle} class. The method should do a deep equality
check.

\item A \pythoninline{str} object can be constructed by passing any
object to \pythoninline{str} constructor.
\begin{enumerate}
\item Write code that calls \pythoninline{str} on a
Point object and a Rectangle object. Record the output below:
\begin{answerspace}



zend
\end{answerspace}
\item The answer to the previous question is generally not what we
want. To get \pythoninline{str} to produce something sensible, we can
define a \pythoninline{\_\_str\_\_} method that returns any string we
like. 
Add a \pythoninline{\_\_str\_\_} method to \pythoninline{Point} that
returns for example, ``(5, 3)'' for a \pythoninline{Point} whose
\pythoninline{x} value is $5$ and \pythoninline{y} value is $3$.
\item Add a \pythoninline{\_\_str\_\_} method to
\pythoninline{Rectangle} so that it returns something sensible.
 \end{enumerate}

\item Add a method called \pythoninline{move} to
\pythoninline{Rectangle}.

\item \label{classes-gui} Using classes and objects is actually a very nice way of
  developing GUI programs. For example, we can rewrite
  \pythoninline{tk\_move\_circle2.py}, from Section
  \ref{sec-moving-ball} using classes like this:

\begin{minipage}{\textwidth}
\begin{python}
from Tkinter import *
import random

class MovingBallApp():
    def __init__(self, master):
        self.w = Canvas(master, width=200, height=200)
        self.w.grid(column=0,row=0)
        self.x = 5
        self.y = random.randint(0,200)
        self.dx = 2
        self.dy = random.randint(-5,5)
        self.ball = self.w.create_oval(self.x, self.y, self.x+20, self.y+20,
                                       fill="blue")
        self.w.after(100, self.move)

    def move(self):
        self.x += self.dx
        self.y += self.dy
        self.w.coords(self.ball, self.x, self.y, self.x+20, self.y+20)
        self.w.after(100, self.move)
        

root = Tk()
app = MovingBallApp(root)
root.mainloop()
\end{python}
\end{minipage}
Which has the major advantage of doing away with all those global variables.
\begin{enumerate}
\item Create a new class called \pythoninline{Ball} that contains all
  the parameters needed to draw and move the ball. Hint:
  \pythoninline{x}, \pythoninline{y}, \pythoninline{dx}, and
  \pythoninline{dy}, are more properly attributes of a
  \pythoninline{Ball} rather than a \pythoninline{MovingBallApp}.
\item Add a method to \pythoninline{MovingBallApp} called
  \pythoninline{add\_ball(self, ball)}, that adds a ball to the
  application so that multiple balls appear on the screen. Try adding
  several balls to the application.
\end{enumerate}
\item \emph{Extension Exercise:} \label{ex-classes} Modify the code from Exercise
  \ref{classes-gui} so the balls bounce off all the walls.
\item \emph{Double Extension Exercise:} Modify the code from Exercise
  \ref{ex-classes} so the balls bounce of all the walls and each
  other.
\end{enumerate}
