Software Design Spring 2006 For today: 1) work on Homework 7 (poker) For lab: 1) finish Homework 7 In lab we will work on an exercise on GUIs. There will be no homework (except choosing a project!) We will have a quiz Friday. Inheritance ----------- Probably the characteristic feature of object-oriented programming. A new class extends an existing class: class Hand(Deck): def __init__(self, name=''): self.cards = [] self.name = name The new class has all the methods of the old class. The new class can add additional methods, or override existing ones. For example, this __init__ replaces Deck.__init__ class Tagger(Turtle): def __init__(self, world, speed=1, angle=60): Turtle.__init__(self, world) self.delay = 0 self.speed = speed self.angle = angle self.it = 0 self.sulking = 0 self.goal = None def step(self): ... A Tagger is a kind of Turtle, so it has all the methods in the Turtle class. Tagger.__init__ overrides Turtle.__init__, but it also invokes Turtle.__init__ Tagger inherits from Turtle, Turtle inherits from Animal, Animal is a base class -- it inherits from the Ur-object. These chains form a CLASS HIERARCHY. Child classes inherit from parent classes. (or sometimes) Subclasses extend superclasses. UML Class Diagrams ------------------ A UML Class Diagram shows relationships between classes. It is less detailed than an object diagram. Inheritance denotes the IS-A relationship between classes: 1) a Tagger is a kind of Turtle 2) a Turtle is a kind of Animal Embedded objects represent a HAS-A relationship between objects: 1) a Turtle has a reference to a World 2) World has a list of references to Animals 3) a Deck has a list of references to Cards These relationships are shown graphically in a UML Class Diagram. Homework 6 Solutions -------------------- sd_hw06_soln.py is available from the usual place. If you create a new class that inherits from exception: class Missed(Exception): """this the exception raised when a turtle tries to tag someone too far away""" You can use the class object in a raise statement (no need to instantiate a Missed object): def apply_tag(self, other): """try to tag the other turtle. if it is too far away, let the other turtle flee and raise an exception""" if self.distance_from(other) < 10: self.not_it() other.youre_it() else: other.flee(self) raise Missed Optionally, you can provide additional information: raise Missed, 'nah, nah!' Either way, you can catch the exception: if self.it: target = self.closest(world.animals) try: self.apply_tag(target) except Missed: self.chase(target) Closest demonstrates a variation on the DSU pattern: def closest(self, others): """return the animal in the list that is closest to self (not including self!)""" t = [(self.distance_from(animal), animal) for animal in others if animal is not self] (distance, animal) = min(t) return animal And a nice (?) use of a list comprehension.