[Tutor] design of Point class

Steven D'Aprano steve at pearwood.info
Sat Aug 21 03:50:40 CEST 2010


On Sat, 21 Aug 2010 08:08:56 am Alan Gauld wrote:
> Every time you change the interface of inherited methods you
> create for yourself extra work in converting types to match the
> superclass. But that is often easier than rewriting the methods
> from scratch.

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.




-- 
Steven D'Aprano


More information about the Tutor mailing list