16
Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

Embed Size (px)

Citation preview

Page 1: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

Classes 2

COMPSCI 105 S2 2015Principles of Computer Science

Page 2: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1052

Exercise Define a class that will be used to represent a

square with a given side length. Your class should include a constructor that will

allow the square to be used as follows:

Add a method to the class to calculate the perimeter of the square. The following code shows how the method may be used.

from Geometry import Square

side = 10s = Square(side)

print(s.perimeter())

Lecture05

40

Page 3: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1053

Write a class to represent fractions in Python create a fraction add subtract multiply divide text representation

Example: Fractions

½numeratordenominator

Lecture05

Page 4: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1054

Model of objects in memory

methods

state

num:

den:

7

8

methods

state

num:

den:

3

4

methods

state

num:

den:

1

2

xy

z

from Fraction import Fraction

x = Fraction(1,2)y = Fraction(3,4)z = Fraction(7,8)

Lecture05

Page 5: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1055

All classes must have a constructor The constructor for a Fraction should store the

numerator and the denominator

So far, we can create a Fraction

Constructor

class Fraction: def __init__(self, top, bottom): self.num = top #numerator self.den = bottom #denominator

Lecture05

>>> x = Fraction(3, 4)>>> x.num3>>> x.den4

Page 6: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1056

We can access and changing the state variables directly

Direct access of a data field in an object is not a good practice. The data may be tempered with, e.g., the

denominator should never be 0, but it may be mistakenly set.

The class becomes difficult to maintain and vulnerable to bugs, e.g., a change to the type of a data field in the class effects other program that uses the class.

Using the Fraction class

>>> x.num3>>> x.den -= 4>>> x.den0

Lecture05

Page 7: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1057

To prevent direct modification of data fields, don’t let the client (user) directly access the data fields of an object.

This is known as data hiding, which can be done by defining private data fields in a class.

In Python, the private data fields are defined with two leading underscores.

You can also define a private method named with two leading underscores.

Hiding the data fields

Lecture05

class Fraction: def __init__(self, top, bottom): self.__num = top #numerator self.__den = bottom #denominator

Page 8: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1058

Private data fields (or methods) can be accessed within in a class, but they can not be accessed outside the class.

To make a private data field accessible for the client, provide a get method to return its value.

To enable a private data field to be modifiable, provide a set method to set a new value.

Accessing private data fields

Lecture05

>>> x= Fraction(3,4)>>> x.__numTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Fraction' object has no attribute '__num'>>>

Page 9: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 1059

A get method is referred to as an accessor method.

A set method is referred to as a mutator method.

Accessing the private data fields through accessor and mutator methods.

Accessor and mutator methods

Lecture05

def getNumerator(self): return self.__num

def SetNumerator(self, top): self.__num = top

>>> x = Fraction(3,4)>>> x.getNumerator()3>>> x.setNumerator(10)>>> x.getNumerator()10

Page 10: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10510

Overriding default behaviour All classes have a number of methods provided

by default, e.g. methods to do with representing the output format of

the object methods to do with comparing two objects methods to do with computation between objects,

…… Since default behaviour is not always very useful

and accurate, we should write our own versions of those methods.

Lecture05

>>> x<__main__.Fraction object at 0x10191e3c8>>>> y = Fraction(1,4)>>> print(y)<__main__.Fraction object at 0x10191e630>>>> z = Fraction(1,4)>>> y == zFalse

Page 11: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10511

Often we want to use a string that combines literal text and information from variables Example:

We can use string formatting to perform this task Use curly braces within the string to signify a variable

to be replaced

We can put the argument position in the curly braces

Aside: Use of string formatting syntax

name = 'Andrew'greeting = 'Hello ' + name + '. How are you?'

my_name = 'Andrew'greeting = 'Hello {name}. How are you?'.format(name = my_name)

first = 'Andrew’last = 'Luxton-Reilly'greeting = 'Hello {0} {1}!'.format(first, last)

Lecture05

Page 12: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10512

The __repr__ method produces an string that unambiguously describes the object All classes should have a __repr__ function

implemented Ideally, the representation could be used to create the

object For example, a fraction created using Fraction(2, 3) should

have a __repr__ method that returned 'Fraction(2, 3)'

Using the object

The __repr__ method

class Fraction:def __init__(self, top, bottom): self.__num = top

self.__den = bottom def __repr__(self): return 'Fraction({0}, {1})'.format(self.__num, self.__den)

>>> x = Fraction(2, 3)>>> x Fraction(2, 3)

Lecture05

Page 13: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10513

With the __repr__ method defined in the class, it produces:

Without the __repr__ method

>>> x = Fraction(2, 3)>>> x>>> <__main__.Fraction object at 0x02762290>)

class Fraction: def __init__(self, top, bottom): self.__num = top self.__den = bottom

Lecture05

def __repr__(self): return 'Fraction({0}, {1})'.format(self.__num, self.__den)

>>> x = Fraction(2, 3)>>> x>>> Fraction(2, 3)

Page 14: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10514

The __str__ method returns a string representing the object By default, it calls the __repr__ method The __str__ method should focus on being human

readable We should implement a version with a natural

representation:

After we have implemented the method, we can use standard Python

The __str__ method

def __str__(self): return str(self.__num) + '/' + str(self.__den)

>>> x = Fraction(3, 4)>>> print(x)>>> 3/4

Lecture05

Page 15: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10515

With the __str__ method defined in the class, it produces:

Without the __str__ method

>>> x = Fraction(2, 3)>>> print(x)>>> <__main__.Fraction object at 0x02762290>)

class Fraction: def __init__(self, top, bottom): self.__num = top self.__den = bottom

Lecture05

def __str__(self): return str(self.__num) + '/' + str(self.__den)

>>> x = Fraction(2, 3)>>> print(x)>>> 2/3

Page 16: Classes 2 COMPSCI 105 S2 2015 Principles of Computer Science

COMPSCI 10516

Exercise Write the __repr__ method for the Square

class created earlier.

Would it be useful to implement a __str__ method?

What would you choose to produce as output from a __str__ method?

Lecture05