Inheritence & Composition

Patterns for Code Reuse

class Post():
  def __init__(self, creator):
    self.creator = creator

class Tweet(Post):
  def retweet(self):
    print("retweeted by " + self.creator)

class Snap(Post):
  def expire(self):
    print("expired snap by " + self.creator)

snap = Snap("edsu")
snap.expire()

expired snap by edsu

class Post():
  def __init__(self, creator):
    self.creator = creator

class Tweet(Post):
  def retweet(self):
    print("retweeted by " + self.creator)

class Snap(Post):
  def expire(self):
    print("expired snap by " + self.creator)

tweet = Tweet(creator="edsu")
tweet.retweet()

retweeted by edsu

class Post():
  def __init__(self, creator):
    self.creator = creator

class Tweet(Post):
  def retweet(self):
    print("retweeted by " + self.creator)

class Snap(Post):
  def expire(self):
    print("expired snap by " + self.creator)

tweet = Tweet(creator="edsu")
tweet.expire()

AttributeError: ‘Tweet’ object has no attribute ‘expire’

class Post():
  def __init__(self, creator):
    self.creator = creator
  def delete(self):
    print("post deleted by " + self.creator)

class Tweet(Post):
  def retweet(self):
    print("retweeted by " + self.creator)

class Snap(Post):
  def expire(self):
    print("expired snap by " + self.creator)

tweet = Tweet(creator="edsu")
tweet.delete()

post deleted by edsu

Overriding Methods

class Post():
  def __init__(self, creator):
    self.creator = creator
  def update(self):
    print("post updated by " + self.creator)

class Tweet(Post):
  def update(self):
    print("you can never update tweets!")

class Snap(Post):
  def expire(self):
    print("expired snap by " + self.creator)

tweet = Tweet(creator="edsu")
tweet.update()

you can never delete tweets!""

Exercise

Remember our Email class that we used for processing the Enron email? Let’s extend the one I’ve uploaded as email.py to Module 7 in ELMS and add a method that will return the subject of the email.

Composition


Pizza

  • crust
  • toppings
  • cheese
  • sauce

class Topping():

    def __init__(self, name, num_pieces):
        self.name = name
        self.num_pieces = num_pieces

topping = Topping("pepperoni", 25)
print(topping)

<main.Topping object at 0x10c6374e0>

class Pizza():

    def __init__(self):
        self.toppings = []

    def add_topping(self, topping):
        self.toppings.append(topping)

pizza = Pizza()
print(pizza)

<main.Pizza object at 0x10c6374e0>

class Pizza():
    def __init__(self):
        self.toppings = []
    def add_topping(self, topping):
        self.toppings.append(topping)

class Topping():
    def __init__(self, name, num_pieces):
        self.name = name
        self.num_pieces = num_pieces

pizza = Pizza()
pizza.add_topping(Topping("pepperoni", 18))
pizza.add_topping(Topping("mushrooms", 12))
pizza.add_topping(Topping("green peppers", 15))
print(pizza.toppings)

[<main.Topping object at 0x10c9ae748>, <main.Topping object at 0x10c9aea58>, <main.Topping object at 0x10c9aea90>]

class Topping():

    def __init__(self, name, num_pieces):
        self.name = name
        self.num_pieces = num_pieces

    def __repr__(self):
        return "{} pieces of {}".format(self.num_pieces, self.name))

pizza = Pizza()
pizza.add_topping(Topping("pepperoni", 18))
pizza.add_topping(Topping("mushrooms", 12))
pizza.add_topping(Topping("green peppers", 15))
print(pizza.toppings)

[18 pieces of pepperoni, 12 pieces of mushrooms, 15 pieces of green peppers]

class Pizza():
    def __init__(self):
        self.toppings = []

    def add_topping(self, topping):
        self.toppings.append(topping)

    def num_pieces(self):
        count = 0
        for topping in self.toppings:
            count += topping.num_pieces
        return count

pizza = Pizza()
pizza.add_topping(Topping("pepperoni", 18))
pizza.add_topping(Topping("mushrooms", 12))
pizza.add_topping(Topping("green peppers", 15))
print(pizza.num_toppings())

45

OOP Patterns

Class composition is a much more useful Object Oriented Programming pattern than inheritance.

Inheritance should be used sparingly because elaborate inheritance hierarchies can be difficult to maintain over time as requirements change.

Exercise

Download the pizza.py file from Module 7 and modify Pizza.add_topping to ensure that no more than 7 toppings are added.

If someone adds more than 7 toppings it should print “Sorry that is too many toppings!”.