Beginning Programming in Python
Fall 2019
Agenda
- Inheritance
- Object composition
- Inheritance vs. composition: aka: 'Is a' vs. 'has a'.
- An Example of OOP: Implementing the card game Old Maid
Introduction to inheritance
Class Hierarchies
Terminology
-
Key points:
-
Inheritance is about hierarchical abstraction
-
Inheritance is about is-a relationship
-
Inheritance is about common attributes
-
Inheritance
Inheritance In Python
class Pet:
def __init__(self, pet_name, age):
self.pet_name, self.age = pet_name, age
def __str__(self):
return "Pet name: {}, age: {}".format(self.pet_name, self.age)
p = Pet("Chairman Miow", 5)
q = Pet("Drogon", 2)
print(p)
print(q)
class Cat(Pet): # The bracket notation after the class name indicates
# that Cat is "inherited" from Pet
def __str__(self):
return "Cat name: {}, age: {}".format(self.pet_name, self.age)
class Dragon(Pet):
def __str__(self):
return "Dragon name: {}, age: {}".format(self.pet_name, self.age)
p = Cat("Chairman Miow", 5)
q = Dragon("Drogon", 2)
print(p)
print(q)
some properties
-
A child class has all the functionality of the parent, but you are free to add or redefine methods and variables.
-
Redefinition of methods gives polymorphism: this is what we were doing last lecture with the operator and built-in function overloading.
Overriding __init__()
- In many cases you want to override __init__() method to add new variables, without copying parent classes constructor
class Snake(Pet):
def __init__(self, pet_name, age, venomous=True):
super().__init__(pet_name, age) # Super is magic to
# figure out the correct parent class __init__ method
# You could also call the parent constructor explicitly,
# not using super Pet.__init__(self, pet_name, age)
self.venomous = venomous
def __str__(self):
return "Snake name: {}, age: {}, venomous?: {}".\
format(self.pet_name, self.age, self.venomous)
r = Snake("Cuddly", 1)
print(r)
Object composition
class Point:
""" Create a new Point, at coordinates x, y """
def __init__(self, x=0, y=0):
""" Create a new point at x, y """
self.x = x
self.y = y
def distance_from_origin(self):
""" Compute my distance from the origin """
return ((self.x ** 2) + (self.y ** 2)) ** 0.5
def __str__(self):
"""Return a string representing the point"""
return "({0}, {1})".format(self.x, self.y)
class Rectangle:
""" A class to manufacture rectangle objects """
def __init__(self, posn, w, h):
""" Initialize rectangle at posn, with width w, height h """
self.corner = posn
self.width = w
self.height = h
def __str__(self):
return "({0}, {1}, {2})".format(self.corner, self.width, self.height)
box = Rectangle(Point(0, 0), 100, 200)
print("box: ", box)
Inheritance vs. Composition
-
IS-A vs. HAS-A relationship
-
We could implement rectangle class using inheritance
-
However, a rectangle is not a kind of Point, rather it has corners which are points
-
IS-A: Inheritance
-
HAS-A: Composition
class Rectangle(Point):
""" A class to manufacture rectangle objects """
def __init__(self, x, y, w, h):
""" Initialize rectangle at posn, with width w, height h """
super().__init__(x, y) # Call the Point constructor
self.width = w
self.height = h
def __str__(self):
return "({0}, {1}, {2})".format(super(Rectangle, self).__str__(), self.width, self.height)
box = Rectangle(0, 0, 100, 200)
print("box: ", box)
5 minutes break!
Example
-
A card game has:
-
Individual cards, each with a suit and rank, e.g. Ace, 2, 3, 4, ...
-
One or more decks (a deck being a full set of cards)
-
Hands (a hand is subset of cards)
-
Game logic
-
types needed
Attendance Survey
Questions?
CSE 20 - Lecture 16
By Narges Norouzi
CSE 20 - Lecture 16
- 1,331