[Tutor] design of Point class

Gregory, Matthew matt.gregory at oregonstate.edu
Mon Aug 23 19:55:16 CEST 2010


Hi Steven,

Steven D'Aprano wrote:
> Every time you change the interface of inherited methods, you probably
> shouldn't.
> 
> Firstly, it probably breaks the Liskov Substitution Principle. The LSP
> says, essentially, if you subclass A to make B, you should be able to
> use a B anywhere you can use an A. (After all, instances of B are also
> instances of A.) Here's an example of what not to do:
> 
> class Vehicle:
>     def start(self, key):
>         ignition.insert(key)
>         ignition.turn()  # raises exception if out of fuel
>     def go(self, key):
>         self.start(key)
>         self.handbrake = 'off'
>         self.gear = 'drive'
>         self.accelerate()
> 
> class Truck(Vehicle):
>     # add other truck-like methods
> 
> class KeylessTruck(Truck):
>     # Some military vehicles are designed to not require keys.
>     # When on a battlefield, there's nothing worse than being
>     # unable to find the car keys!
>     def go(self):
>         self.start()
>         self.handbrake = 'off'
>         self.gear = 'drive'
>         self.accelerate()
>     def start(self):
>         ignition.turn()  # Actually a push button, but nevermind.
> 
> Can you see the problem? If the caller is expecting a Truck, and pass a
> key to the truck.go() method, they will get an exception if you give
> them a KeylessTruck instead of a Truck. This is a Bad Thing.
> 
> Secondly, changing method interfaces is not compatible with multiple
> inheritance and super(). You can probably get away with it if you stick
> to single inheritance, but it's still a bad thing to do.

Yes, this absolutely makes sense, but I'm less clear on how to solve it.  What I would think is that Vehicle shouldn't be defining start and this should be left up to a delegate within the subclasses?  Or am I showing my ignorance?

matt

matt


More information about the Tutor mailing list