0% found this document useful (0 votes)
143 views42 pages

Object-Oriented Programming: Computer Science & Engineering Department The Chinese University of Hong Kong

The document discusses object-oriented programming (OOP) concepts including classes, objects, attributes, methods, and inheritance. It provides examples using a Rocket class to demonstrate how objects can be instantiated from a class and have their own attributes and behaviors. Multiple rocket objects can be created and their positions and distances between them can be calculated. OOP allows code reuse through inheritance where a new class can be created building upon an existing class.

Uploaded by

Kezia Mally
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
143 views42 pages

Object-Oriented Programming: Computer Science & Engineering Department The Chinese University of Hong Kong

The document discusses object-oriented programming (OOP) concepts including classes, objects, attributes, methods, and inheritance. It provides examples using a Rocket class to demonstrate how objects can be instantiated from a class and have their own attributes and behaviors. Multiple rocket objects can be created and their positions and distances between them can be calculated. OOP allows code reuse through inheritance where a new class can be created building upon an existing class.

Uploaded by

Kezia Mally
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Object-Oriented

Programming
Computer Science & Engineering Department
The Chinese University of Hong Kong

CSCI2040 INTRODUCTION TO PYTHON 1


Assessment
• 5 labs 40%
• We have Lab 3 released soon, and 2 more in coming 3 weeks

• Final exam 60%


• Date : Nov 30
• Time: 10-11am
• Venue LSK LT7
• You must obtain at least 30% of the final examination score in order
to pass.

CSCI2040B Introduction to Python 2


Problem of Bugs
• According to some studies1
• Industry average: about 15-50 errors happened per 1000 lines of code(LOC)
• Microsoft Applications: about 10-20 defects per 1000 LOC during in house
testing, & 0.5 defect per 1000 LOC
• In order to reduce number of bugs in our software, one way is to
develop based on established, thoroughly tested and debugged code

1. Code Complete: A Practical Handbook of Software Construction, Second Edition 2nd Edition
Steve McConnelMicrosoft Press; 2nd edition (June 19, 2004)
CSCI2040 INTRODUCTION TO PYTHON 4
Object-Oriented Programming (OOP)
• One of the most popular programming paradigms
• OOP emphasize the concept of software reuse -
once a certain program is being written, later others can build a new
prototype base on current one with minimal modification

• Or think of building many identical flats with basic functions such as


water, electricity
• New tenants can customize each flat into their own preferred style
with different paints, furniture, carpets etc.

CSCI2040 INTRODUCTION TO PYTHON 5


Object-Oriented Programming (OOP)
• Most important concept is “classes”
• Class : a way to combine both data(variables) and
behaviour(functions) within a construct, think of template/blueprint
• We use an example of creating a rocket ship in a physics simulation
• Let say we want to track (x,y) coordinates of the rocket

CSCI2040 INTRODUCTION TO PYTHON 6


1 # Rocket is a class which simulates a rocket ship
2 class Rocket():
3 def __init__(self): # Each rocket has an (x,y) position, and init to 0
4 self.x = 0
5 self.y = 0
6
7 def move_up(self): # a method which moves the rocket ship up by 1 unit
8 self.y = self.y + 1
9
10 # One can *instantiate* an instance of the Rocket class
11 my_rocket = Rocket() # instantiate an instance
12 # my_rocket has a copy of each of the class's variables,
13 # and it can do any action that is defined for the class.
14 print(my_rocket) # shows that my_rocket is stored at a particular location
15 print('my_rocket x is = ', my_rocket.x, ", my rocket y is = ", my_rocket.y)

<__main__.Rocket object at 0x0000023D65B964E0>


my_rocket x value is = 0 , my rocket y value is = 0
CSCI2040 INTRODUCTION TO PYTHON 7
OOP Concepts
• Classes are the core component of OOP
• When we want to use a class in one of your programs, we create an
object (or instance) from that class
• OOP Terms
• Attribute
a piece of information or data within a class. E.g., x and y in Rocket().
• Behavior/Method
an action that defined within a class. E.g., mov_up() in Rocket().
• Object : a particular instance of a class. E.g., my_rocket

CSCI2040 INTRODUCTION TO PYTHON 8


1 # Rocket is a class which simulates a rocket ship
2 class Rocket():
3 def __init__(self): # Each rocket has an (x,y) position, and init to 0
4 self.x = 0
5 self.y = 0
6
7 def move_up(self): # a method which moves the rocket ship up by 1 unit
8 self.y = self.y + 1
9
10 # One can *instantiate* an instance of the Rocket class
11 my_rocket = Rocket() # instantiate an instance
12 # my_rocket has a copy of each of the class's variables,
13 # and it can do any action that is defined for the class.
14 print(my_rocket) # shows that my_rocket is stored at a particular location
15 print('my_rocket x is = ', my_rocket.x, ", my rocket y is = ", my_rocket.y)

Behavior/Method declarations
CSCI2040 INTRODUCTION TO PYTHON 9
1 # Rocket is a class which simulates a rocket ship
2 class Rocket():
3 def __init__(self): # Each rocket has an (x,y) position, and init to 0
4 self.x = 0
5 self.y = 0
6
7 def move_up(self): # a method which moves the rocket ship up by 1 unit
8 self.y = self.y + 1
9
10 # One can *instantiate* an instance of the Rocket class
11 my_rocket = Rocket() # instantiate an instance
12 # my_rocket has a copy of each of the class's variables,
13 # and it can do any action that is defined for the class.
14 print(my_rocket) # shows that my_rocket is stored at a particular location
15 print('my_rocket x is = ', my_rocket.x, ", my rocket y is = ", my_rocket.y)

Attributes declarations
CSCI2040 INTRODUCTION TO PYTHON 10
1 # Let's see how we can invoke the class's method
2
3 my_rocket = Rocket() # instantiate an instance
4 for counter in range(3):
5 my_rocket.move_up() # invoke class function
6
7 print('my_rocket x is = ', my_rocket.x, ", my rocket y is = ", my_rocket.y)
8
9
10
11
12
13
14
15

my_rocket x is = 0 , my rocket y is = 3
CSCI2040 INTRODUCTION TO PYTHON 11
1 # The following code shows that one can create **multiple instances** of
2 # Create a fleet of 5 rockets, and store them in a list.
3
4
5 my_rockets = [ ]
6 for x in range(0,5): # go through the loop 5 times
7 new_rocket = Rocket()
8 my_rockets.append(new_rocket) # my_rocket contains 5 Rocket instances
9
10
11 # Show that each rocket is a separate object.
12 for rocket in my_rockets:
13 print(rocket)
14
15

<__main__.Rocket object at 0x000001F7ECBB64E0>


<__main__.Rocket object at 0x000001F7ECBB66D8>
<__main__.Rocket object at 0x000001F7ECC16358>
<__main__.Rocket object at 0x000001F7ECC16390>
<__main__.Rocket object at 0x000001F7ECC163C8> CSCI2040 INTRODUCTION TO PYTHON 12
1 # The following code shows a more elegant way to create **multiple
2 instances** # using **list comprehension**
3
4
# Create a fleet of 5 rockets, and store them in a list.
5 :
6 # Create a fleet of 5 rockets, and store them in a list.
7 my_rockets = [Rocket() for x in range(0,5)] # This is a more elegant way #
8 my_rockets[0].move_up()
my_rockets[1].move_up()
9 my_rockets[1].move_up()
10 my_rockets[3].move_up()
11 my_rockets[3].move_up()
my_rockets[3].move_up()
12 my_rockets[4].move_up()
13 my_rockets[4].move_up()

14 for rocket in my_rockets: # Let's display their y-values


15 print('For rocket in memory:', rocket, ', its altitude is: ', rocket.y)
For rocket in memory: <__main__.Rocket object at 0x0000018B732A6588> , its altitude is: 1
For rocket in memory: <__main__.Rocket object at 0x0000018B732A6780> , its altitude is: 2
For rocket in memory: <__main__.Rocket object at 0x0000018B73306400> , its altitude is: 0
For rocket in memory: <__main__.Rocket object at 0x0000018B73306438> , its altitude is: 3
For rocket in memory: <__main__.Rocket object at CSCI2040 INTRODUCTION
0x0000018B73306470> TO PYTHON
, its altitude is: 2 13
Object-Oriented Programming (OOP)
• We will introduce more concepts through further refine our Rocket
class
• When we create our rocket instance, we cannot set the initial value
• __init__ method can be changed to tailor this need

• We change it so that new rockets can be initialized at any position.

CSCI2040 INTRODUCTION TO PYTHON 14


1 class Rocket():
2 def __init__(self, x=0, y=0): # using keywords with default values
3 self.x = x
4 self.y = y
5
6 def move_up(self): # Increment the y-position of the rocket.
7 self.y += 1
8 rockets = [ ]
9 rockets.append(Rocket())
10 rockets.append(Rocket(0,10))
11 rockets.append(Rocket(100,0))
12 # Show where each rocket is.
13 for index, rocket in enumerate(rockets): # let's look up the documentation
14 print("Rocket {} is at ({}, {})." .format (index, rocket.x, rocket.y))
15

Rocket 0 is at (0, 0).


Rocket 1 is at (0, 10).
CSCI2040 INTRODUCTION TO PYTHON 15
Rocket 2 is at (100, 0).
1 from math import sqrt
2 def get_distance(self, other_rocket):
3 # Calculates the distance from this rocket to another rocket, and returns that value.
4 distance = sqrt((self.x-other_rocket.x)**2+(self.y-other_rocket.y)**2)
5 return distance
6
7 # Make two rockets, at different places.
8 rocket_0 = Rocket()
9 rocket_1 = Rocket(10,5)
10 # Show the distance between them.
11 distance = rocket_0.get_distance(rocket_0)
12 print("The rockets are %f units apart." % distance)
13 distance = rocket_0.get_distance(rocket_1)
14 print("The rockets are %f units apart." % distance)
15

The rockets are 0.000000 units apart.


The rockets are 11.180340 units apart.
CSCI2040 INTRODUCTION TO PYTHON 16
Inheritance (OOP)
• We wish to save our programming effort by using existing reliable
program
• OOP allows us to reuse code by creating a new class by inheriting
from an existing class
• the new class inherits all of the attributes and behavior of old class

• Can override undesirable features as well as create new ones


• but any attributes that are defined in the child class are not available
to the parent class

CSCI2040 INTRODUCTION TO PYTHON 17


1 From Rocket Import Rocket
2 class Shuttle(Rocket): # Shuttle is a child of the Rocket() class,
3 # flights_completed is new attribute
4 def __init__(self, x=0, y=0, flights_completed=0): # this is new init()
5 super().__init__(x, y) # it first calls its super class init()
6 self.flights_completed = flights_completed # it also does its own initialization
7
8 shuttle = Shuttle(10,0,3)
9 print(shuttle)
10 print("This shuttle has x = ", shuttle.x, "y = ", shuttle.y, "# of completed flights ",
11 shuttle.flights_completed)
12
13
14
15

<__main__.Shuttle object at 0x000002AEE18776A0>


This shuttle has x = 10 y = 0 # of completed flights 3
CSCI2040 INTRODUCTION TO PYTHON 18
More OOP Concepts
• We further illustrate the application of OOP in daily lives
• Consider banking operation, we have accounts opened in bank
• We want to keep track of the balance of the account and be able to
withdraw and deposit money into it’

CSCI2040 INTRODUCTION TO PYTHON 19


1 class BankAccount(object):
2 def __init__(self, balance=0):
3 self.balance = balance
4 def deposit (self, amount):
5 self.balance = self.balance + amount
6 def withdraw (self, amount):
7 self.balance = self.balance - amount
8 def getBalance(self):
9 return self.balance
10 my_account1 = BankAccount (200)
11 # what is the balance in my_account1 ?
12 print ('my_account 1 balance: ', my_account1.getBalance())
13 my_account2 = BankAccount ()
14 # what is the balance in my_account2 ?
15 print ('my_account 2 balance: ', my_account2.getBalance())

my_account 1 balance: 200


my_account 2 balance: 0
CSCI2040 INTRODUCTION TO PYTHON 20
More OOP Concepts
• Objects are internally stored as references
• assigning an object only means its reference being copies
1 husband_account = BankAccount(500)
2 wife_account = husband_account
3 wife_account.withdraw(300)
4 print("hushand account's balance = ", husband_account.balance)
5 print("wife account's balance = ", wife_account.balance)
6
7

hushand account's balance = 200


wife account's balance = 200 CSCI2040 INTRODUCTION TO PYTHON 21
1 class CheckAccount(BankAccount):
2 def __init__(self, initBal=0):
3 10 BankAccount.__init__(self, initBal)
4 self.checkRecord = {}
5 def processCheck(self, number, toWho, amount):
6 self.withdraw(amount)
7 self.checkRecord[number]= (toWho, amount)
8 def checkInfo(self, number):
9 if number in self.checkRecord:
10 return self.checkRecord[number]
11 ca = CheckAccount (1000)
12 ca.processCheck(100, 'CUHK', 328.)
13 ca.processCheck(101, 'HK Electric', 452.)
14 print('Check 101 has information of: ', ca.checkInfo(101))
15 print ('The current balance is: ', ca.getBalance())
16 ca.deposit(100)
17 print('The current balance is: ', ca.getBalance())
Check 101 has information of: ('HK Electric', 452.0)
The current balance is: 220.0CSCI2040 INTRODUCTION TO PYTHON 22
The current balance is: 320.0
Overriding
• Sometimes necessary for child class to modify or replace the behavior
inherited from parent class
• Child class redefines the function using the same name and arguments
• To invoke original parent class function, class name must be explicitly
provided (or using super() in most of the cases)

class CheckAccount( BankAccount):


:
def withdraw(self, amount):
print ('withdrawing ', amount)
BankAccount.withdraw(self, amount)

CSCI2040 INTRODUCTION TO PYTHON 23


OOP Application
• Let’s try to build a calculator using reverse polish notation (RPN)
• In order for RPN be used, we first need to have a stack
• A stack is a last-in-first-out data structure
• Imagine you want to take a dish from a pile of dishes
• To take the top data from stack is a “pop operation
• To add new data to stack, we have the “push” operation

• We also need to implement some housekeeping operations

CSCI2040 INTRODUCTION TO PYTHON 24


Stack in OOP
class Stack(object): stackOne = Stack()
def __init__(self): stackTwo = Stack()
self.storage = [] stackOne.push( 12 )
def push (self, newValue): stackTwo.push( 'abc' )
self.storage.append( newValue ) stackOne.push( 23 )
def top( self ): print(stackOne.top())
return self.storage[len(self.storage) - 1] >>> 23
def pop( self ): stackOne.pop()
result = self.top() print(stackOne.top())
self.storage.pop() >>>12
return result print(stackTwo.top())
def isEmpty(self): >>>’abc’
return len(self.storage) == 0
Stack implementation in Python Test code
CSCI2040 INTRODUCTION TO PYTHON 25
Using stack to build a calculator
class CalculatorEngine(object):
def __init__(self):
self.dataStack = Stack()

def pushOperand (self, value):


self.dataStack.push( value )

def currentOperand ( self ):


return self.dataStack.top()

def performBinary (self, fun ):


right = self.dataStack.pop()
left = self.dataStack.pop()
self.dataStack.push( fun(left, right))
CSCI2040 INTRODUCTION TO PYTHON 26
Using stack to build a calculator
class CalculatorEngine(object):
:
def doAddition (self):
self.performBinary(lambda x, y: x + y)

def doSubtraction (self):


self.performBinary(lambda x, y: x - y)

def doMultiplication (self):


self.performBinary(lambda x, y: x * y)

def doDivision (self):


self.performBinary(lambda x, y: x / y)
CSCI2040 INTRODUCTION TO PYTHON 27
Using stack to build a calculator
def doTextOp (self, op):
if (op == '+'): self.doAddition()
elif (op == '-'): self.doSubtraction()
elif (op == '*'): self.doMultiplication()
elif (op == '/'): self.doDivision()

calc = CalculatorEngine()
calc.pushOperand( 3 )
calc.pushOperand( 4 )
calc.doTextOp ( '*' )
print calc.currentOperand()

>>> 12 CSCI2040 INTRODUCTION TO PYTHON 28


Calculator Interface
class RPNCalculator(object): calc = RPNCalculator()
def __init__(self): calc.run()
self.calcEngine = CalculatorEngine() Type an expression : 3 4 + 2 *
def eval (self, line):
words = line.split(" ") >>>14
for item in words:
if item in '+-*/':
self.calcEngine.doTextOp( item )
else:
self.calcEngine.pushOperand( int (item))
return self.calcEngine.currentOperand()
def run(self):
while True:
line = input("type an expression: ")
if len(line) == 0:
break
print self.eval( line ) CSCI2040 INTRODUCTION TO PYTHON 29
Separating Model from View
• The calculator is constructed from 3 classes – stack, calculator, interface
• considered independent of each other
• Calculator engine encapsulates logic of using stack to perform evaluation
• But calculator knows nothing about interface

• Advantages:
1.Make program easier to understand
2.Enable software reuse e.g. stack
3.Division of calculator engine and interface
• View is the object that interacts with end user
• Model is the logic that actually implements the tasks being performed
• Can also change the interface to others without need to rewritten the calculator
engine CSCI2040 INTRODUCTION TO PYTHON 30
Types & Tests
• Each class definition creates a new type
>>> print (type(myAccount))
<class '__main__.BankAccount'>
>>> print (type(BankAccount))
<type 'type'>

• Test for membership in a class


>>> newAccount = CheckAccount(4000)
>>> sndAccount = BankAccount(100)
>>> print (isinstance(newAccount, BankAccount))
True
>>> print (isinstance(newAccount, CheckAccount))
True
>>> print (isinstance(sndAccount, CheckAccount))
False
CSCI2040 INTRODUCTION TO PYTHON 31
Types & Tests
• issubclass(A,B) returns true if class A is a subclass of B
>>> print (issubclass(CheckAccount, BankAccount))
True

• Can also perform type checking for built-in types


>>> import types
>>> isinstance(3, types.IntType)
True
>>> isinstance(3, types.FloatType)
False

CSCI2040 INTRODUCTION TO PYTHON 32


Multiple Inheritance
• Class definition specify inheritance from more than one class
• Not recommended

class A(object):
def doa(self):
print ("I'm a“)
class B (object):
def dob(self):
print ("I'm b“)
class C(A,B):
def doc(self):
print ("I'm c“)
>>> v=C()
>>> v.doc()
I'm c
>>> v.doa()
I'm a
>>> v.dob()
I'm b

CSCI2040 INTRODUCTION TO PYTHON 33


Class scope
• Class has its scope, but not part of LEGB
• A class method can see their surrounding scope, but cannot see the class scope
• Normally it’s okay as classes defined at top level
def silly():
x = 12
class A:
x = 42
def foo(self):
print (x)
print (self.x)
return A()
anA = silly()
anA.foo()
>>> 12
42

CSCI2040 INTRODUCTION TO PYTHON 34


Class variables
• Variables defined at class level are shared by all instances
• Initialization only once
• Variables defined using self are unique to each instance

class CountingClass:
count = 0
def __init__(self):
CountingClass.count = CountingClass.count + 1
>>>a = CountingClass()
>>>b = CountingClass()
>>>print (CountingClass.count)
2

CSCI2040 INTRODUCTION TO PYTHON 35


Scopes, Names, and References
• Scope is property of a name, not a property of a value
• Two names can refer to the same value, and they have different scopes

class Box(object):
def __init__( self, v):
self.value = v

def newScope(x):
y = x
y.value = 42

a = Box(3)
newScope(a)
print (a.value)
>>>42 CSCI2040 INTRODUCTION TO PYTHON 36
Qualified Names
• A period following a base e.g. object.attribute
• Base is first determined using LEGB rule
• Names can be qualified include
• Classes
• Instances or objects
• Instances of built-in types e.g. list, dictionary
• Modules

CSCI2040 INTRODUCTION TO PYTHON 37


Qualified Names
• Names resolution are performed using dictionaries
• locals() and globals() return the current scope through
dictionary
• Classes store their name space in a field __dict__
• Can be accessed (or modified!) by programmer

>>> CountingClass.__dict__
{'count': 2, '__module__': '__main__', '__doc__':
None, '__init__': <function __init__ at
0x00FDE4F0>}

CSCI2040 INTRODUCTION TO PYTHON 38


Modules
• Simply a Python file
• Only the handling of names in modules differs
• Import statement scans a file and execute each statement in program
• Names of all values in module are stored in its own dictionary
• Thus the qualified name modName.x is actually just modName.__dict__[‘x’]

>>> import string


>>> print type(string)
<type 'module'>
>>> print string.__dict__['split']
<function split at 0x00BD81B0>

CSCI2040 INTRODUCTION TO PYTHON 39


Module
• Just like library
• Can have two ways when used:
• import modName
• from modName import attribute

• For second way of using module


• Means construct the module dictionary, the given attribute is then
copied into local dictionary
• Thus the attribute can be used without qualification in local space

CSCI2040 INTRODUCTION TO PYTHON 40


Module
• Suppose we want to use bar method in module foo
• import foo
• .. Then use foo.bar to use it
• Two run-time lookups needed in this case :
1. locate foo,
2. locate bar

• from foo import bar


• bar is called directly without qualification
• Only One search required
• More execution efficiency
CSCI2040 INTRODUCTION TO PYTHON 41
Avoid Name Space collision
• Can use wild card ‘*’ to import - from mod import *
• Has risk of name collision

>>> from math import *


>>> print e
2.71828182846

• Can Use as clause to avoid


>>> e = 42
>>> from math import e as eConst
>>> e
42

CSCI2040 INTRODUCTION TO PYTHON 42


Creating your own module
• Just another Python program
• Only difference is it is being loaded by import statement
• Normally contains only classes and function definitions
• Can also have statements inside be executed
• Name of current module is held in internal variable called __name__
• Top level program executed by Python interpreter is of the name
__main__
• Can use the following to conditionally executing those statements

if __name__ == '__main__':
.. statements
CSCI2040 INTRODUCTION TO PYTHON 43

You might also like