Meeting9 - 10 Classes and Object Oriented Programming N
Meeting9 - 10 Classes and Object Oriented Programming N
Meetings #9_10
AOU- M110 2
Procedural Programming
AOU- M110 3
Object-Oriented Programming (1 of 2)
Object-oriented programming: Whereas procedural programming is centered on creating
procedures (functions), object-oriented programming (OOP)is focused on creating objects
Object: An object is a software entity that contains data and procedures.
An object’s data attributes are simply variables that reference data.
The procedures that an object performs are known as methods.
An object’s methods are functions that perform operations on the object’s data attributes.
The object is, conceptually, a self-contained unit that consists of data attributes and
methods that operate on the data attributes.
• Data is known as data attributes and procedures are known as methods.
• Methods perform operations on the data attributes.
AOU- M110 4
Object-Oriented Programming (2 of 2)
AOU- M110 5
Classes
Before an object can be created, it must be designed by a programmer. The
programmer determines the data attributes and methods that are necessary,
then creates a class.
• Class: is a code that specifies the data attributes and methods of a
particular type of object. A class is considered as a factory to create objects.
• Like a blueprint* of a house. The blueprint itself is not a house but is a detailed
description of a house.
• A Python class uses variables (attributes) to define data fields and
methods to define behaviors.
• Instance: is an object created from a class
• Like a specific house built according to the blueprint.
• There can be many instances of one class. Each house is a separate instance of
the house described by the blueprint.
* blueprint :a design plan or other technical drawing
AOU- M110 6
Classes
A way of thinking about the difference between a class and an object is to think of
the difference between a cookie cutter and a cookie. While a cookie cutter itself is
not a cookie, it describes a cookie. The cookie cutter can be used to make several
cookies, as shown in Figure 3. Think of a class as a cookie cutter, and the objects
created from the class as cookies.
AOU- M110 8
Classes
For example, If we design a class based on the states and behaviors of a Person, then
States can be represented as instance variables and behaviors as class methods.
Instances
instance variables
instance methods
Both instances (p1 and p2) are created from the same
class, but they have different states and behaviors.
AOU- M110 9
Class Definitions
In Python, class is defined by using the class keyword.
The syntax to create a class is given below.
class class_name:
'''This is a docstring. I have created a new class'‘’
<statement 1>
<statement 2>
.
.
<statement N>
To create a class, you write a class definition.
• class_name: It is the name of the class
• Class names often start with uppercase letter
• Docstring: It is the first string inside the class with a brief description of the class.
• statements: Attributes and methods
Method definition like any other python function definition
• self parameter: required in every method in the class – references the specific object
that the method is working on
AOU- M110 10
Class Definitions- example
• Example:
point.py
class Point:
x = 0 1 class Point:
y = 0 2 x = 0
3 y = 0
# main
p1 = Point()
p1.x = 2
p1.y = -5
AOU- M110 11
Using a Class
import class
– client programs must import the classes they use
point_main.py
1 from Point import *
2
3 # main
4 p1 = Point()
5 p1.x = 7
6 p1.y = -3
7 ...
8
9 # Python objects are dynamic (can add fields
10 any time!)
p1.name = “Salim Hamad"
AOU- M110 12
Object Methods
def name(self, parameter, ..., parameter):
statements
class Point:
def translate(self, dx, dy):
self.x += dx
self.y += dy
...
AOU- M110 13
Calling Methods
• Example:
p.translate(1, 5)
Point.translate(p, 1, 5)
AOU- M110 14
Class Methods: Example
class Person:
name = "I have no name :("
def sayName(self):
print("My name is...", self.name)
def main():
aPerson = Person()
aPerson.sayName()
aPerson.name = "Big Smiley :D"
aPerson.sayName()
main()
AOU- M110 15
What Is The ‘Self’ Parameter
• Reminder: When defining/calling methods of a class there is always
at least one parameter.
• This parameter is called the ‘self’ reference which allows an object to
access attributes inside its methods.
• ‘self’ is needed to distinguish the attributes of different objects of the
same class. No self! No self!
• Example:
bassem = Person() def sayName():
lisa = Person() print "My name is...", name
lisa.sayName()
AOU- M110 16
The Self Parameter: A Complete Example
class Person:
name = "I have no name :("
def sayName(self):
print("My name is...", self.name)
def main():
lisa = Person()
lisa.name = "Lisa Haddad, pleased to meet you."
bassem = Person()
bassem.name = "I'm Bassem Hassan, who are you???!!!"
lisa.sayName()
bassem.sayName()
main()
AOU- M110 17
Recap: Accessing Attributes & Methods
• Inside the class definition (inside the body of the class methods)
• Preface the attribute or method using the ‘self’ reference
class Person:
name = "No-name"
def sayName(self):
print("My name is...", self.name)
AOU- M110 18
Class Definitions: Initializing The Attributes
• Classes have a special method that can be used to initialize the starting
values of a class to some specific values.
• This method is automatically called whenever an object is created.
Two underscores without spaces between them
• Format:
class <Class name>:
def __init__(self, <other parameters>):
<body of the method> This design approach is
consistent with many languages
• Example:
class Person:
name = ""
def __init__(self):
self.name = "No name"
AOU- M110 19
Class Definitions
• Initializer method: automatically executed when an instance of the
class is created
• Initializes object’s data attributes and assigns self parameter to the object
that was just created
• Format: def __init__ (self):
• Usually, the first method in a class definition
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Coin:
# The _ _init_ _ method initializes the sideup data attribute with 'Heads’.
def _ _init_ _(self):
self.sideup = 'Heads'
AOU- M110 20
Class Definitions
• To create instances of a class, you call the class using class name (and
pass in whatever arguments its __init__ method accepts).
• Format: My_instance = Class_Name()
• To call any of the class methods using the created instance, use dot
notation
• Format: My_instance.method()
• Because the self parameter references the specific instance of the object, the
method will affect this instance
• Reference to self is passed automatically
AOU- M110 21
Initializing The Attributes Of A Class
• Because the ‘init()’ method is a method, it can also be called with parameters which
are then used to initialize the attributes.
• Example:
# Attribute is set to a default in the class definition and then the # attribute can be set to a non-default
value in the init() method.
# (Not standard Python but a common approach with many languages)
class Person:
name = "Default name" # Create attribute here
def __init___(self, aName):
self.name = aName
OR
# Create the attribute in the init() method. (Approach often used in Python).
class Person:
def __init___(self, aName):
self.name = aName # Create attribute here
AOU- M110 22
Using The “Init()” Method-Example
class Person:
name = “No name"
def main():
aPerson = Person(“Jamal Nader")
print(aPerson.name)
main()
Output:
Jamal Nader
AOU- M110 23
Class Attributes vs Instance Attributes in Python
Class attributes are the variables defined directly in the class that are shared by all
objects of the class.
AOU- M110 24
Class Attributes vs Instance Attributes in Python
The following example demonstrates the use of class attribute count.
class Student: In this example, count is an attribute in the Student class.
count = 0 Whenever a new object is created, the value of count is
def __init__(self): incremented by 1.
Student.count += 1
std1=Student()
print(std1.count)
std2=Student()
print(std2.count)
print(Student.count)
Student.count=5
print(std1.count, std2.count)
AOU- M110 25
Coin Class Example
AOU- M110 26
import random
class Coin:
# The _ _init_ _ method initializes the sideup data attribute with 'Heads’.
def __init__(self):
self.sideup = 'Heads'
# The toss method generates a random number in the range of 0 through 1.
#If the number is 0, then sideup is set to 'Heads'.
# Otherwise, sideup is set to 'Tails'.
def toss(self):
if random.randint(0,1) == 0:
self.sideup = 'Heads'
else:
self.sideup = 'Tails'
# The get_sideup method returns the value referenced by sideup.
def get_sideup(self):
return self.sideup
# The main function
def main():
# Create an object from the Coin class.
my_coin = Coin()
# Display the side of the coin that is facing up.
print('This side is up:', my_coin.get_sideup())
# Toss the coin.
print('I am tossing the coin ...')
my_coin.toss()
# Display the side of the coin that is facing up.
print('This side is up:', my_coin.get_sideup())
# Call the main function.
main()
AOU- M110 27
Hiding Attributes
• An object’s data attributes should be private
• To make sure of this, place two underscores (__) in front of attribute name
• Example: _ _sideup
An object’s data attributes should be private, so that only the object’s methods can
directly access them. This protects the object’s data attributes from accidental
corruption. However, in the Coin class that was shown in the previous example, the
sideup attribute is not private. It can be directly accessed by statements that are not in
a Coin class method.
If we truly want to simulate a coin that is being tossed, then we don’t want code outside
the class to be able to change the result of the toss method. To prevent this from
happening, we need to make the sideup attribute private.
In Python, you can hide an attribute by starting its name with two underscore
characters. If we change the name of the sideup attribute to _ _sideup, then code outside
the Coin class will not be able to access it.
AOU- M110 28
import random
# The Coin class simulates a coin that can be flipped
class Coin:
# The _ _init_ _ method initializes the __sideup data attribute with 'Heads’.
def __init__(self):
self.__sideup = 'Heads'
# The toss method generates a random number in the range of 0 through 1.
#If the number is 0, then sideup is set to 'Heads’; otherwise, sideup is set to 'Tails'.
def toss(self):
if random.randint(0,1) == 0:
self.__sideup = 'Heads'
else:
self.__sideup = 'Tails'
# The get_sideup method returns the value referenced by sideup.
def get_sideup(self):
return self.__sideup
# The main function
def main():
# Create an object from the Coin class.
my_coin = Coin()
print('This side is up:', my_coin.get_sideup())
# Toss the coin.
print('I am tossing the coin ...')
my_coin.toss()
print('This side is up:', my_coin.get_sideup())
# Call the main function.
main()
AOU- M110 29
Another Example
class hiding():
# class attribute, "__" before an attribute will hide it
__hideAttr = 10
def func(self):
self.__hideAttr += 1
print(self.__hideAttr)
a = hiding()
a.func()
a.func()
AOU- M110 30
How to access a Hidden Attribute
To access hidden attributes of the class, we use:
instance._class name__hiddenAttr
class JustCounter:
# A class hidden attribute
__secretCount = 0
def count(self):
self.__secretCount += 1
def PrintCount(self):
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.PrintCount()
counter._JustCounter__secretCount=3000
counter.PrintCount()
counter.count()
print(counter._JustCounter__secretCount)
AOU- M110 31
Accessing the Hidden Attribute – Example 2
class hiding(): OUTPUT
__hideAttr = 10 #"__" will hide it
def func(self):
self.__hideAttr += 1
print(self.__hideAttr)
a = hiding()
a.func()
a.func()
print (a.__hideAttr) # will not work!
OUTPUT
To access hidden attributes of the hiding class, we use:
12 is the last
print (a._hiding__hideAttr)# we have succeeded to directly print the HA updated value
a._hiding__hideAttr=20 # we have succeeded to change the HA value 12 from the
a.func() 21 previous
21 example
print (a._hiding__hideAttr) # we have succeeded to directly print the HA
AOU- M110 32
Accessing the Hidden Attribute – Example 3
class Point:
def __init__(self, x, y):
self.__x = x
self.__y = y
def translate(self, dx, dy):
self.__x += dx OUTPUT
self.__y += dy
def printit(self):
print("x=",self.__x,"\
ty=",self.__y) x= 7 y= 15
p=Point(5,10) x= 52 y= 20
p.translate(2,5)
p.printit()
p._Point__x=50
p.translate(2,5)
p.printit()
AOU- M110 33
Storing Classes in Modules
• Classes can be stored in modules
• Filename for module must end in .py
• Module can be imported to programs that use the class
AOU- M110 34
Program A- coin Module
import random
# The Coin class simulates a coin that can be flipped
class Coin:
# The _ _init_ _ method initializes the __sideup data attribute with 'Heads’.
def __init__(self):
self.__sideup = 'Heads'
# The toss method generates a random number in the range of 0 through 1.
#If the number is 0, then sideup is set to 'Heads’; otherwise, sideup is set to 'Tails'.
def toss(self):
if random.randint(0,1) == 0:
self.__sideup = 'Heads'
else:
self.__sideup = 'Tails'
# The get_sideup method returns the value referenced by sideup.
def get_sideup(self):
return self.__sideup
AOU- M110 35
Program B-coin program
# This program imports the coin module and creates an instance of the Coin class
import coin
def main():
# Create an object from the Coin class.
my_coin = coin.Coin()
# Display the side of the coin that is facing up.
print('This side is up:', my_coin.get_sideup())
# Toss the coin.
print('I am tossing the coin ...')
my_coin.toss()
my_coin.__sideup = 'Heads'
# Display the side of the coin that is facing up.
print('This side is up:', my_coin.get_sideup())
# Call the main function.
main()
Line 2 imports the coin module. Notice in line 5, we had to qualify the name of the Coin
class by prefixing it with the name of the module, followed by a dot
AOU- M110 36
More About Classes
• Class methods can have multiple parameters in addition to self
• For __init__, parameters needed to create an instance of the class
• Example: a BankAccount object is created with a balance
• When called, the initializer method receives a value to be assigned to a __balance attribute
class BankAccount:
# The _ _init_ _ method accepts an argument for
# the account's balance. It is assigned to the _ _balance attribute
def _ _init_ _(self, bal):
self._ _balance = bal
Notice the _ _init_ _ method has two parameter variables: self and bal. The bal
parameter will accept the account’s starting balance as an argument. Then, the
bal parameter amount is assigned to the object’s _ _balance attribute.
AOU- M110 37
More About Classes
This method has two parameter variables: self and amount. When the method
is called, the amount that is to be deposited into the account is passed into the
amount parameter.
The value of the parameter is then added to the _ _balance attribute.
AOU- M110 38
The BankAccount class
class BankAccount:
AOU- M110 39
The BankAccount class- Test
AOU- M110 40
Simple Vehicle Example
Write a Python program to create a Vehicle class with max_speed, price and
mileage instance attributes. The _ _init_ _ method initializes the attributes
class Vehicle:
def __init__(self, max_speed, price, mileage):
OUTPUT
self.max_speed = max_speed
self.price = price
self.mileage = mileage
AOU- M110 41
The __str__ method
• Object’s state: the values of the object’s attribute at a given moment
• __str__ method: displays the object’s state
• Automatically called when the object is passed as an argument to the print function
• Automatically called when the object is passed as an argument to the str function
class Employee:
id = -1 OUTPUT
name = ''
def __init__(self, i, n, r):
self.id = i
self.name = n Employee[id=10, name=Jamal, role=CEO]
self.role = r
def __str__(self):
return "Employee[id={}, name={}, role={}]".format(self.id, self.name, self.role)
e = Employee(10, 'Jamal', 'CEO')
print(e)
AOU- M110 42
Working With Instances (1 of 2)
When a method uses the self parameter to create an attribute, the attribute
belongs to the specific object that self references.
We call these attributes instance attributes because they belong to a specific
instance of the class.
It is possible to create many instances of the same class in a program.
Each instance will then have its own set of attributes.
For example, look at the following Program.
This program creates three instances of the Coin class. Each instance has its
own _ _sideup attribute.
AOU- M110 43
# This program imports the simulation module and
# creates three instances of the Coin class.
import coin
def main():
# Create three objects from the Coin class.
coin1 = coin.Coin()
coin2 = coin.Coin()
coin3 = coin.Coin()
# Display the side of each coin that is facing up.
print('I have three coins with these sides up:')
print(coin1.get_sideup())
print(coin2.get_sideup())
print(coin3.get_sideup())
print()
# Toss the coin.
print('I am tossing all three coins ...')
print()
coin1.toss()
coin2.toss()
coin3.toss()
# Display the side of each coin that is facing up.
print('Now here are the sides that are up:')
print(coin1.get_sideup())
print(coin2.get_sideup())
print(coin3.get_sideup())
print()
# Call the main function.
main()
AOU- M110 44
Working With Instances (2 of 2)
Figure 6 The coin1, coin2, and coin3 variables reference three Coin objects
AOU- M110 45
Accessor and Mutator Methods
• Typically, all a class’s data attributes are private and provide methods to
access and change them
• Accessor methods: Methods that return a value from a class’s attribute
without changing it
• Safe way for code outside the class to retrieve the value of attributes
• Mutator methods: Methods that store or change the value of a data
attribute
AOU- M110 46
Accessor and Mutator Methods - Example
class MyClass():
def __init__(self):
self.__my_attr = 3
def set_my_attr(self,val):
self.__my_attr = val
def get_my_attr(self):
return self.__my_attr
obj1 = MyClass()
print (obj1.get_my_attr())
obj1.set_my_attr(7)
print (obj1.get_my_attr())
AOU- M110 47
Passing Objects as Arguments
AOU- M110 48
Techniques for Designing Classes
AOU- M110 49
Finding the Classes in a Problem (1 of 3)
• When developing object-oriented program, first goal is to identify
classes
• Typically involves identifying the real-world objects that are in the problem
• Technique for identifying classes:
1. Get written description of the problem domain
2. Identify all nouns in the description, each of which is a potential class
3. Refine the list to include only classes that are relevant to the problem
AOU- M110 50
Finding the Classes in a Problem (2 of 3)
1. Get written description of the problem domain
• May be written by you or by an expert
• Should include any or all of the following:
• Physical objects simulated by the program
• The role played by a person
• The result of a business event
• Recordkeeping items
AOU- M110 51
Finding the Classes in a Problem (3 of 3)
3. Refine the list to include only classes that are relevant to the
problem
• Remove nouns that mean the same thing
• Remove nouns that represent items that the program does not need to be
concerned with
• Remove nouns that represent objects, not classes
• Remove nouns that represent simple values that can be assigned to a
variable
AOU- M110 52
Identifying a Class’s Responsibilities
AOU- M110 53
Introduction to Inheritance
• In the real world, many objects are a specialized version of more general
objects
• Example: grasshoppers and bees are specialized types of insect
• In addition to the general insect characteristics, they have unique characteristics:
• Grasshoppers can jump
• Bees can sting, make honey, and build hives
AOU- M110 54
Inheritance and the “Is a” Relationship (1 of 4)
AOU- M110 55
Inheritance and the “Is a” Relationship (2 of 4)
AOU- M110 56
Inheritance and the “Is a” Relationship (3 of 4)
• For example, need to create classes for cars, pickup trucks, and SUVs
• All are automobiles
• Have a make, year model, mileage, and price
• This can be the attributes for the base class
• In addition:
• Car has a number of doors
• Pickup truck has a drive type
• SUV has a passenger capacity
AOU- M110 57
Inheritance and the “Is a” Relationship (4 of 4)
AOU- M110 58
# The Automobile class holds general data about an automobile in inventory.
class Automobile:
# The __init__ method accepts arguments for the make, model, mileage,
# and price. It initializes the data attributes with these values.
# The following methods are mutators for the class's data attributes.
AOU- M110 59
# The following methods are the accessors for the class's data attributes.
def get_make(self):
return self.__make
def get_model(self):
return self.__model
def get_mileage(self):
return self.__mileage
def get_price(self):
return self.__price
AOU- M110 60
# The Car class represents a car. It is a subclass of the Automobile class.
class Car(Automobile):
# The __init__ method accepts arguments for the
# car's make, model, mileage, price, and doors.
def get_doors(self):
return self.__doors
AOU- M110 61
# The Truck class represents a pickup truck. It is a subclass of the Automobile class.
class Truck(Automobile):
# The __init__ method accepts arguments for the
# truck's make, model, mileage, price, and drive type.
def get_drive_type(self):
return self.__drive_type
AOU- M110 62
# The SUV class represents a sport utility vehicle. It is a subclass of the Automobile class.
class SUV(Automobile):
# The __init__ method accepts arguments for the
# SUV's make, model, mileage, price, and passenger capacity.
def get_pass_cap(self):
return self.__pass_cap
AOU- M110 63
# This program creates a Car object, a Truck object, # Display the car's data.
# and an SUV object. print('The following car is in inventory:')
print('Make:', car.get_make())
import vehicles print('Model:', car.get_model())
print('Mileage:', car.get_mileage())
def main(): print('Price:', car.get_price())
# Create a Car object for a used 2001 BMW print('Number of doors:', car.get_doors())
# with 70,000 miles, priced at $15,000, with print()
# 4 doors.
car = vehicles.Car('BMW', 2001, 70000, 15000.0, 4) # Display the truck's data.
print('The following pickup truck is in inventory.')
# Create a Truck object for a used 2002 print('Make:', truck.get_make())
# Toyota pickup with 40,000 miles, priced print('Model:', truck.get_model())
# at $12,000, with 4-wheel drive. print('Mileage:', truck.get_mileage())
truck = vehicles.Truck('Toyota', 2002, 40000, 12000.0, '4WD') print('Price:', truck.get_price())
print('Drive type:', truck.get_drive_type())
# Create an SUV object for a used 2000 print()
# Volvo with 30,000 miles, priced # Display the SUV's data.
# at $18,500, with 5 passenger capacity. print('The following SUV is in inventory.')
suv = vehicles.SUV('Volvo', 2000, 30000, 18500.0, 5) print('Make:', suv.get_make())
print('Model:', suv.get_model())
print('USED CAR INVENTORY') print('Mileage:', suv.get_mileage())
print('===================') print('Price:', suv.get_price())
print('Passenger Capacity:', suv.get_pass_cap())
AOU- M110 64
Inheritance in UML Diagrams
• In UML diagram, show inheritance by drawing a line with an open
arrowhead from subclass to superclass
AOU- M110 65
Summary
• This lecture covered:
• Procedural vs. object-oriented programming
• Classes and instances
• Class definitions, including:
• The self parameter
• Data attributes and methods
• __init__ and __str__ functions
• Hiding attributes from code outside a class
• Storing classes in modules
• Designing classes
• Inheritance
AOU- M110 66