ENG 202: Computers and Engineering
Object Oriented Programming in PYTHON
LECTURE 9 – PYTHON Classes and Inheritance
Maurice J. KHABBAZ, Ph.D.
Abstraction of data types
through classes.
Last Time
Basic Coordinate Example.
NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. Friday, December 13, 2019 2
Accessors
(i.e. Getters)
Mutators
(i.e. Setters)
Today More on Classes
Information Hiding
Inheritance
Class Variables
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 3
Class Implementation V.S. Usage
Implementing The Class Using The Class
Implementing a new object type Using the new object type in
with a class: code:
• Define the class. • Create instances of the object
• Define data attributes (i.e. What is?). type.
• Define methods (i.e. How to use?). • Execute operations with them.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 4
Class Implementation V.S. Usage
Class Definition of an Object Type Instance of a Class
• Class name is the type: • It is one specific realization:
c = Coordinate(1,2)
class Coordinate(object):
• Data attribute values vary between
• Class is defined generically: different instances.
• Use self throughout the class definition: c1 = Coordinate(1, 2)
allows a class instance to refer to itself:
c2 = Coordinate(3, 4)
(self.x – self.y)**2 • c1 and c2 may have different data
• self is a parameter to methods throughout attribute values x and y because they
the class definition. are different objects
• Class defines data and methods common • Any instance has the same structure
across all instances. of the class itself.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 5
Usage of OOP And
Classes of Objects
• Mimic real life.
• Group objects belonging to the same type
6
Data Attributes:
• Representation of an object with data.
• Abstract descriptions of object characteristics.
Groups of • Examples:
• Point: its x, y and z, coordinates.
Objects Have • Animal: its name, age, type (i.e. cat, dog, horse, … etc).
Attributes: Procedural Attributes (i.e. behavior, operations,
methods):
Recall • Means of interaction with an object.
• Abstract descriptions of the object’s behavior and what it
does.
• Examples:
• Point: find the distance between two points, form a line.
• Animal: eat, drink, make a sound, etc.
NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. Friday, December 13, 2019 7
Class Definition: Recall
class Animal(object):
def __init__(self, age):
[Link] = age
[Link] = None
myAnimal = Animal(3)
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 8
Accessor and Mutator Methods
• Also known respectively as Getter and Setter methods.
• Should be used outside the class to access (i.e. read/modify) attributes.
• Example:
class Animal(object):
def __init__(self, age):
[Link] = age; [Link] = None
def getAge(self): return [Link]
def getName(self): return [Link]
def setAge(self, age): [Link] = age
def setName(self, name = “”): [Link] = name
def __str__(self): return [Link]+“:”+str([Link])
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 9
An Instance and DOT Notation: Recall
• Instantiation implies the creation of an instance of an object class.
• Example:
a = Animal(3)
• DOT notation used to access attributes (data/methods):
• This is not recommended for accessing data attributes.
• Use ONLY for accessing procedural (methods) attributes:
• Methods will internally handle an instance’s own attributes through the self variable.
• Example: - Access of data attribute
- Allowed but not recommended
[Link]
- Access of procedural attributes
[Link]() - Best use getters and setters
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 10
Information Hiding
• Class definition authors may change data attribute names:
• Example:
class Animal(object): class Animal(object):
def __init__(self, age): def __init__(self, age):
[Link] = age [Link] = age
def getAge(self): def getAge(self):
return [Link] return [Link]
• Direct data attribute access outside the class using DOT ⇒ errors.
• Outside class, use accessor/mutator methods:
• Example: USE [Link]() NOT [Link]
• Good style, easy to maintain code, prevents bugs.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 11
Does PYTHON Fail At Information Hiding?
• So far:
• PYTHON allows direct data attribute access from outside class definition.
• Example: print([Link])
• PYTHON allows direct data attribute mutation from outside class definition.
• Example: [Link] = 10
• PYTHON even allows creation of new data attributes from outside class definition.
• Example: [Link] = “tiny”
• It is not a good programming style and/or practice.
• How is data encapsulation ensured here? … Well it is, so far, not ensured!
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 12
Data/Procedural Attributes Access Modifiers
• Data/Procedural attributes in PYTHON are typically:
• Public: accessible from outside the class using the object’s name and DOT.
• Data attributes, in general, have to be made either/or:
• Private: deny any access to them from any environment outside the class.
• Protected: accessible from within the class itself and/or its sub-classes.
• No other external environment is allowed to access such data attributes.
• Enables specific resources of the parent class to be inherited by child class:
• (INHERITANCE DISCUSSED LATER THROUGHOUT THIS LECTURE).
• Ensure data protection/encapsulation through:
• Making data attributes private/protected.
• Keeping procedural attributes public.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 13
Access Modifiers in PYTHON
• In PYTHON all data/procedural attributes are public by default.
• PYTHON:
• Has no mechanism to effectively restrict access to instance variables/methods.
• Prescribes prefixing convention for variables/methods names with:
• A single underscore “_” to make them protected.
• A double underscore “__” to make them private.
• Example: Original Employee class
class Employee(object):
def __init__(self, name, salary)
[Link] = name
[Link] = salary
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 14
Access Modifiers in PYTHON – Cont’d.
class Employee(object):
def __init__(self, name, salary)
[Link] = name
[Link] = salary
• Assume that e = Employee(“Jason”, 1500) is instantiated.
• e’s attributes are accessible and mutable directly:
[Link] = “Jad”
[Link] = 2000
print([Link] + “:” + str([Link]))
• Output: Jad:2000
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 15
Access Modifiers in PYTHON – Cont’d.
class Employee(object): class Employee(object):
def __init__(self, name, salary) def __init__(self, name, salary)
[Link] = name self._name = name
[Link] = salary self._salary = salary
protected
• Assume that e = Employee(“Jason”, 1500) is instantiated.
• e’s protected attributes are still accessible and mutable directly:
e._name = “Jad”
e._salary = 2000
print(e._name + “:” + str(e._salary))
• Output: Jad:2000
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 16
Access Modifiers in PYTHON – Cont’d.
class Employee(object): class Employee(object):
def __init__(self, name, salary) def __init__(self, name, salary)
[Link] = name self.__name = name
[Link] = salary self.__salary = salary
private
• Assume that e = Employee(“Jason”, 1500) is instantiated.
• e’s private attributes no longer accessible and mutable directly:
e.__name = “Jad”
Output: AttributeError:
‘Employee’ object has no attribute ‘__name’
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 17
Access Modifiers in PYTHON – Cont’d.
class Employee(object):
def __init__(self, name, salary)
self.__name = name
self.__salary = salary
def getName(self):
Accessor methods
return self.__name
allow indirect access
def getSalary(self):
to private attributes
return self.__salary
• Assume that e = Employee(“Jason”, 1500) is instantiated.
• e’s private attributes no longer accessible and mutable directly:
print([Link]() + “:” + str([Link]())
Output: Jason:1500
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 18
Default Arguments
• Defined for formal parameters and used if no actual arguments are passed.
• Example:
def setName(self, name = “”)
[Link] = name
a = Animal(3)
[Link]()
print([Link]()) prints “” to the screen
[Link](“Piggy”)
print([Link]()) prints “Piggy” to the screen
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 19
Hierarchies
• Best explained using an example: Accounts
Root
Accounts
Level
Social
Bank E-Mail Parent
Media
Accounts Accounts Level
Accounts
Checking Savings NDU Child
Gmail Hotmail Facebook Whatsapp
Account Account Mail Level
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 20
Hierarchies
• A parent class is also known as a superclass.
• A child class is also known as a subclass:
• Inherits all data and procedural attributes of its parent class.
• Adds more data attributes (information).
• Adds more procedural attributes (methods).
• May override methods of parent classes.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 21
Inheritance: Parent Class
- Everything is an object
- Class object implements basic PYTHON operations
class Employee(object): (e.g. binding variables, etc)
def __init__(self, name, salary):
self.__name = name; self.__salary = salary
def getName(self): return self.__name
def getSalary(self): return self.__salary
def setName(self, name = “”):
self.__name = name
def setSalary(self, salary = 0):
self.__salary = salary
def __str__(self):
return self.__name + “:” + str(self.__salary)
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 22
Inheritance: Subclass Professor inherits all attributes of Employee:
__init__(), name, salary, getName(), getSalary(),
class Professor(Employee): setName(), setSalary(), __str__()
def teach(self): add new functionality
print(“PYTHON is important because...”)
def __str__(self): Overrides __str__() defined in Employee
return “Dr. ” + self.__name + “:” + str(self.__salary))
• Add new functionality teach():
• Instance of Professor can be called with new methods.
• Instance of Employee yields an error if called with Professor’s new method.
• __init__() is not missing, Professor uses the Employee version.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 23
Method Usage
• A subclass may have methods with the same name as superclass.
• For an instance of a subclass, look for method in the subclass definition.
• If not found, look for method name up the hierarchy:
• i.e. parent class, grandparent class, and so forth…
• Use the first method up the hierarchy that is found with the called name.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 24
Inheritance: Example
Parent class is Animal
class Person(Animal):
def __init__(self, name, age):
Animal.__init__(self, age) call Animal constructor
[Link](name); [Link] = [] Add new data attributes
def getFriends(self): return [Link]
def addFriend(self, frdName):
new methods
if frdNAme not in [Link]:
[Link](frdName)
def speak(self): print(“Hello There!”)
def ageDiff(self, other):
print(abs([Link] – [Link]), “years”)
def __str__(self): override Animal’s __str__() method
return “person”: + str([Link]) + “:” + str([Link])
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 25
Inheritance: Example – Cont’d.
import random bring in methods from random class
class Student(Person): inherits Person and Animal attributes
def __init__(self, name, age, major = None):
Person.__init__(self, name, age)
[Link] = major Add new data attributes
def changeMajor(self, major):
[Link] = major
def speak(self):
r = [Link]() random()method returns a floating point number in [0, 1)
if r < 0.25: print(“I have a homework”)
elif 0.25 <= r < 0.5: print (“I need sleep”)
elif 0.5 <= r < 0.75: print (“I must eat”)
else: print(“I am watching TV”)
def __str__(): return “student:” + [Link] + “:” + [Link]
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 26
Class Variables and The Rabbit Subclass
• class variables and their values are shared between all instances of a class.
parent class
class Rabbit(Animal):
tag = 1
def __init__(self, age, parent1=None, parent2=None):
Animal.__init__(self, age)
self.parent1 = parent1
self.parent2 = parent2
[Link] = [Link] access class variable
[Link] += 1 changing the class variable’s value changes
it for all instances that may reference it
• tag used to give unique ID to each new Rabbit instance.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 27
Rabbit Getter Methods
class Rabbit(Animal):
tag = 1
def __init__(self, age, parent1=None, parent2=None):
Animal.__init__(self, age)
self.parent1 = parent1
self.parent2 = parent2
[Link] = [Link] pads a string with zeros
[Link] += 1 (e.g. 001 not 1)
def getRID(self): return str([Link]).zfill(3)
def getParent1(self): return self.parent1
def getParent2(self): return self.parent2
In addition to these specific getters for Rabbit there are
those inherited from Animal: getName() and getAge()
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 28
Working With Custom-Built Types
def __add__(self, other):
# returning object of same type as this class
return Rabbit(0, self, other)
Recall Rabbit’s __init__(self, age, parent1=None, parent2=None)
• Define the + operator between two Rabbit instances:
• Define what something like this does: r4=r1+r2 (r1/r2 are Rabbit instances)
• r4 is a new Rabbit instance with age 0.
• r4 has self as one parent and other as the other parent.
• In __init__(), parent1 and parent2 are of type Rabbit.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 29
Working With Custom-Built Types – Cont’d.
• Decide that two rabbits are equal if they have the same two parents.
def __eq__(self, other):
parentsSame = [Link] == [Link] \
and [Link] == [Link]
parentsOpposite = [Link] == [Link] \
and [Link] == [Link]
return parentsSame or parentsOpposite
• Compare IDs of parents since IDs are unique (class variables)
• Note that objects cannot be compared directly:
• Example: self.parent1 == other.parent1 calls __eq__() method.
• The __eq__() call goes over and over until it gets called on None.
• Then it gives an AttributeError when it tries to execute None.parent1
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 30
Object Oriented Programming
• Create custom-built data collections.
• Organize information.
• Divide and conquer the work.
• Access information in a consistent manner.
• Add layers of complexity.
• Similar to Functions:
• Classes are a mechanism for decomposition and abstraction in programming.
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 31
Friday, December 13, 2019 NDU - ENG 202 - Maurice J. KHABBAZ, Ph.D. 32