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
0
 Advanced issues found
1
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?