ObjectOriented Programming in Python Goldwasser and Letscher Chapter
Object-Oriented Programming in Python Goldwasser and Letscher Chapter 9 Inheritance Terry Scott University of Northern Colorado 2007 Prentice Hall
Introduction: Chapter 9 Topics • • Augmentation. Specialization. Inheritance why and terminology. is-a and has-a relationships (inheritance and composition). When should inheritance not be used. Class Hierarchies and cs 1 graphics. Multiple inheritance. Case Study: Mailbox class. 2
Inheritance: Why and Terminology • • Inheritance facilitates code reuse. Original class is called base or parent class. Inherited class is called a derived or child class. Augmenting: Child class adds a new method that wasn't present in the parent class. • Specializing: Child class overrides or changes a method that was originally defined in the parent class. 3
Augmentation • Child class adds functionality to parent class. • Create a Deluxe. TV class that inherits from the Television class. • Deluxe. TV class adds (augments) favorite channels attribute and methods to manipulate it to base Television class. 4
Deluxe. TV Class Code from Television import Television def Deluxe. TV(Television) """TV that maintains a set of favorite channels""" def __init__(self): """call the base class Television to initialize the Deluxe. TV also""" Television. __init__(self): self. _favorites = [ ] 5
Deluxe. TV (continued) def add. To. Favorites(self): """Add current channel to favorites""" if self. _power. On and self. _channel not in self. _favorites: self. _favorites. append(self. _channel) def remove. From. Favorites(self): """Remove current channel from favorites""" if self. _power. On and self. _channel in self. _favorites: self. _favorites. remove(self. _channel) 6
Deluxe. TV (continued) def jump. To. Favorite(self): """Jumps to next higher channel in favorites. If none higher then it wraps to lower and no favorites remains the same""" if self. _power. On and len(self. _favorites) > 0: closest = max(self. _channel) if closest <= self. _channel: closest = min(self. _favorites) else: for option in self. _favorites: closest = option self. set. Channel(closest) 7 return closest
Specialization • Augmentation adds new functionality. • Specialization changes parent method so the child class does some new operation. • Deluxe. TV class jump. To. Favorite method was difficult to do because list was not sorted. • Create a new data type called: Sorted. Set(list). • Notice Sorted. Set is a child (derived) class of list. • It will be similar to a list but items will be in sorted order. • Use this set to simplify Deluxe. TV class. 8
Sorted. Set Methods def index. After(self, value): """Places value in list in sorted order""" walk = 0 while walk < len(self) and value >= self[walk]: walk += 1 return walk def insert(self, value): """check to see if item is not in list and places in sorted order using index. After method" if value not in self: place = self. index. After(value) list insert(self. place, value) 9
Sorted. Set • Using the list class as the base class for Sorted. Set has disadvantages. • Some list methods should not be available in the Sorted. Set. This can be accomplished by either preventing access or converting them so that they place items in sorted order. – append, extend, sort, +, index, remove – reverse, pop, indexing [ ], len, ==. <, str 10
Sorted. Set Code: Preventing or Changing Some List Methods def append(self, object): self. insert(object) #remember insert puts object in order def extend(self, other): for element in other: self. insert(element) #places elements in sorted order def sort(self): pass #called a NOP (no operation) in some languages def index(self, value): return self. _items. index(value) 11
Sorted. Set Code (continued) def __add__(self, other): result = Sorted. Set(self) #combines lists so they result. extend(other) #remain in sorted order. return result def remove(self, element): self. _items. remove(element) def pop(self, index=None): return self. _items. pop(index) 12
Sorted. Set Code (continued) def __contains__(self, element): return element in self. _items def __getitem__(self, index): return self. _items[index] def __len__(self): return len(self. _items) 13
Sorted. Set Code (continued) def __eq__(self, other): return self. _items == other. _items def __lt__(self, other): return self. _items < other. _items def __str__(self): return str(self. _items) 14
Sorted. Set Code (continued) def reverse(self): raise Runtime. Error('Sorted. Set cannot be reversed') def __setitem__(self, index, object): raise Runtime. Error('Syntax not supported by Sorted. Set') 15
Deluxe. TV Using Sorted. Set to Implement jump. To. Favorite(self) def jump. To. Favorite(self): if self. _power. On and len(self. _favorites)>0 resultindex = self. _favorites. index. After(self. channel) result = self. _favorties[0] else: result = self. _favorites[result. Index] self. set. Channel(result) return result 16
Inheritance Versus Composition • Inheritance is described as: is-a relationship • Composition is described as: has-a relationship • Can use list as composition rather than inheritance in the Sorted. Set class. • Sorted. Set has-a list. • Maybe easier since unneeded or problem methods do not need to be overridden. 17
• Sorted. Set Class Using list Class with Composition class Sorted. Set: def __init__(self): self. _items = list() • The rest of the class proceeds using self. _items to store the list. • Consult code on pages 309 -310 in book. 18
Star Class in cs 1 graphics • Make a new class Star that inherits from Polygon class Star(Polygon) • Star instance medal = Star(5) paper. add(medal) 19
Star Class Code class Star(Polygon): def __init__(self, num. Rays=5, outer. Radius=10, inner. Ratio=5, center= Point(0, 0)): Polygon. __init__(self) #call parent constructor top=Point(0, -outer. Radius) #top point above origin angle = 180. 0/num. Rays for i in range(num. Rays): self. add. Point(top^(angle* (2 * i))) #rotate point self. add. Point(inner. Ratio * top ^(angle * (2*I + 1))) self. adjust. Reference(0, outer. Radius) self. move(center. get. X(), center. get. Y()) self. _inner. Ratio = inner. Ratio 20
Star Class Code (continued) def set. Inner. Ratio(self, new. Ratio): factor = new. Ratio / self. _inner. Ratio = new. Ratio for i in range(1, self. get. Number. Of. Points(), 2): self. set. Point(factor * self. get. Point(i), i): 21
Square Class • Illustrate inheritance once more but this time with the Square class. • Square class inherits from the rectangle class. • set. Width and set. Height both call set. Size which makes width and height the same. 22
Square Class Code class Square(Rectangle): def __init__(self. size = 10, center = None): Rectangle __init__(self, size, center) def set. Width(self, width): self. set. Size(width) def set. Height(self, height): Rectangle. set. Width(self, size) def set. Size(self, size): Rectangle. set. Width(self, size) Rectangle. set. Height(self, size) def get. Size(self): return self. get. Width() 23
Car Class Inheritance • Have car class inherit from layer • Car can now have attributes of layer and can add methods required for the car class. 24
Car Class Code class Car(Layer): #Car inherits from Layer def __init__(self, body. Color='blue'): Layer. __init__(self) tire 1 = Circle(10, Point(-20, -10) tire 1. set. Fill. Color('black') self. add(tire 1) tire 2 = Circle(10, Point(20, -10)) tire 2. set. Fill. Color('black') self. add(tire 2) self. _body = Rectangle(70, 30, Point(0, -25)) self. _body. set. Fill. Color(body. Color) self. body. set. Depth(60) self. add(self. _body) 25
Car Class Code (Continued) def set. Body. Color(self, body. Color): self. _body. set. Fill. Color(body. Color) 26
Car Class Alternative Implementation • Problem with using Layer as the base class for the Car class. • The add, remove, and clear methods could be used to alter a car object by the user of the class. • A solution is to have the car class inherit from the Drawable class. • _draw is a method in the Drawable class. 27
Class Car Code class Car(Drawable): def __init__(self, body. Color= 'blue') Drawable. __init__(self) #call parent constructor self. _tire 1 = Circle(10, Point(-20, -10) self. tire 1. set. Fill. Color('black') self. _tire 2 = Circle(10, Point(-20, -10) self. tire 2. set. Fill. Color('black') self. body = Rectangle(70, 30, Point(0, -25)) self. body. set. Fill. Color(body. Color) 28
Class Car Code (continued) def set. Body. Color(self, body. Color): self. _body. set. Fill. Color(body. Color) def _draw(self): self. begin. Draw( ) #required protocol self. _body. _draw() self. _tire 1. _draw() self. _tire 2. _draw() self. _complete. Draw( ) #required protocol 29
Multiple Inheritance • So far classes have only inherited from one class. Called single inheritance. • Multiple inheritance: Can inherit from more than one class. • Layer uses multiple inheritance: from Drawable and _Graphics. Container. • Canvas: single inheritance. 30
Layer Inheritance 31
Layer Class Code class Layer(Drawable, _Graphics. Container): def __init__(self): Drawable. __init__(self): #initialize both base _Graphics. Container. __init__(self) #classes def __draw(self): self. _begin. Draw() for shape in self. get. Contents(): shape. _draw() self. _complete. Draw() 32
Labeled. Rectangle Class • Class creates a rectangle. • Places text centered in the rectangle. • Inherit from classes Rectangle and Text. 33
Labeled. Rectangle Class Code class Labeled. Rectangle(Text, Rectangle): def __init__(self, message) Text. __init__(self, message) Rectangle. __init__(self, width, height) self. set. Fill. Color('white') def _draw(self): self. _begin. Draw() Rectangle. _draw(self) Text. _draw(self) self. _complete. Draw() 34
Mailbox Class • Creating a new class. Decide on its properties and its actions. • A Mailbox class properties: – flag. – door. • A Mailbox actions: • • door open. door close. flag up. flag down. 35
Mailbox • Below are possible configurations of the mailbox. • Consult book pages 323 – 325 for the code. 36
- Slides: 36