Jackson wrote: > For a more "concrete" example: > > Suppose all the animals in the world have only 1 or 2 legs. > > class Legs(object) > def run(): pass > def walk(number_of_legs): > # lots of commands > # that do not depend on the > # number of legs but definitely > # have to do with walking > > if number_of_legs == '1': > # blah blah > > if number_of_legs == '2': > # blah blah > > # more commands > > class HasAtLeastOneLeg(Legs): > def walk(): > # Legs.walk(number_of_legs=1) > > class HasTwoLegs(HasAtLeastOneLeg,Legs): > def walk() > # Legs.walk(number_of_legs=2)
Well, I would have done this differently. If the only difference in behavior between one- and two-legged creatures is their gait, I probably wouldn't have bothered breaking Legs into subclasses. I'd just pass the number of legs into __init__: class Legs(object): def __init__(self,number_of_legs): self.number_of_legs = number_of_legs def walk(self): # non-legs-dependent stuff if self.number_of_legs == 1: # one-legged gait elif self.number_of_legs == 2: # two-legged gait else: raise ValueError("invalid number of legs") # more non-legs-dependent stuff Then, when defining some sort of monster class, I'd do something like this: class Human(object): def __init__(self): self.legs = Legs(2) # etc. class Dufflepud(object): def __init__(self): self.legs = Legs(1) # etc. If there's more to it than just gait (say for example, one-legged creatures attack differently, jump higher, and can't turn invisible because they don't have enough limbs to cast Level 4 Invisibility), then I would factor out differences in behavior into subclasses. class Legs(object): def walk(self): # non-leg-related stuff self.set_gait() # more non-leg-related stuff class OneLeg(Legs): def set_gait(self): # set the one-legged gait class TwoLegs(Legs): def set_gait(self): # set the two-legged gait class Human(object): def __init__(self): self.legs = TwoLegs() class Dufflepud(object): def __init__(self): self.legs = OneLeg() ISTM you have been missing out on the true power of inheritance. Behavior exclusive to creatures with two legs should be implmented in the TwoLegs class, but in your example you define a HasTwoLegs class yet still implement this behavior in the base class Legs. That's just poor use of inheritance. My examples implement behavior exclusive to two-legged creatures inside the TwoLegs class, where it belongs. In fact, BEHAVIOR is the key to arranging class hierarchies. (The classical advice, the inheritance represents the "is a" relationship, can be very misleading and I don't recommend using it. The focus should be on behavior.) Anyways, in your universe, there are three kinds of behaviors: A. behaviors exclusive to one-footed creatures B. behaviors exclusive to two-footed creatures C. behaviors common to both Once you consider behaviors in this way, how to arrange the class hierarchy becomes obvious. Each kind of behavior shoud be implemented in its own class: common behaviors go into base classes, exclusive behaviors into subclasses. The hierarchy should look like this: class Legs -- this should implement all common behavior class OneLeg(Legs) -- should implment all behavior exclusive to one-legged creatures class TwoLegs(Legs) -- should implment all behavior exclusive to two-legged creatures Note that there's no need for an AtLeastOneLeg class. There are only one- and two-legged creatures in this univserse, so behaviors exclusive to creatures with at least one leg apply are in fact common to all creatures. But suppose we add zero-footed creatures to the universe. Now we identify five kinds of behaviors: A. behaviors common to all creatures B. behaviors exclusive to zero-footed creatures C. behaviors common to one- and two-footed creatures D. behaviors exclusive to one-footed creatures E. behaviors exclusive to two-footed creatures Now we need an AtLeastOneLeg class in our hierarchy: class Legs class ZeroLegs(Legs) class AtLeastOneLeg(Legs) class OneLeg(AtLeastOneLeg) class TwoLegs(AtLeastOneLeg) But, notice that we still have a OneLeg class, because there's still behavior exclusive to one-legged creatures. It belongs in OneLeg, not in AtLeastOneLeg. Hope this long-winded advice helps. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list