advice on programming style: is multiple inheritance bad?

Dietrich Epp dietrich at zdome.net
Mon Feb 2 22:24:18 EST 2004


On Feb 2, 2004, at 12:06 AM, Gary Stephenson wrote:

> Fwiw, I am both a human, and a customer of my bank.  My computer is 
> both an
> "electrical_device" and a "depreciable-asset".  It is completely 
> natural in
> the real world for objects to have multiple "is-a" relationships with
> various other objects.   Why then, should we not use multiple 
> inheritance
> when modelling such relationships?

Because we (or at least I) don't program that way.

The problem is context.  Programming usually involves very specific 
contexts, such as accounting, image processing, or networking.  Classes 
in those contexts can be very narrowly defined.

Humans don't work in single contexts.  We understand that a pencil is a 
kind of writing instrument, but it is also a kind of weapon.  It 
depends on how you are holding it.  Chairs are usually kinds of 
furniture, but some chairs belong more in the category of art.  To make 
things worse [for computers], humans sometimes use terms that logically 
contradict.  Humans are very good at contexts.

Object-oriented programming is not meant to replicate natural language. 
  It's just a bridge between the way people think and the way computers 
process data.  Humans make lots of complicated "is a" relationships, 
but it's not particularly useful when programming.  Another way to 
think of inheritance is a "has functionality of" relationships."  Let's 
say I have some data I want dynamically loaded from XML files and a 
MySQL database.

class DataLoader:
     pass

class XMLDataLoader(DataLoader):
     def Load(self, what):
         ...

class SQLDataLoader(DataLoader):
     def Load(self, what):
         ...

Since DataLoader has no functionality, I would delete it.

> One major reason why multiple inheritance has such a bad name can be 
> sheeted
> back to the brain-dead way in which C++ implements it.  The other main
> reason is that inheritance itself, single or multiple, implementation 
> or
> interface, is _way_ overrated as a code structuring technique.  This is
> probably due to it not even being consistently defined - it seems to 
> mean
> different things to different people at different times (depending on 
> which
> language they're currently working with).

I agree.  In addition to the rampant poor software design, programmers 
use object-oriented programming to hammer their screws into the wall, 
so to speak.  However, I see OOP as fundamentally a good thing.  It 
tends to make code simpler, more obvious, and reduces duplication.  I 
also think that "is a" and "does" relationships are a good way to learn 
OOP.

> IMHO, inheritance only works robustly in the face of change if you can
> guarantee that the potential instances of your (sub)classes form a 
> strict
> proper subset (mathematically speaking) of the potential instances of 
> their
> ancestor classes.  afaik, which is not terribly far really
> ;-) , there is no OO language on earth that can _guarantee_ this 
> subclass ==
> subset relationship for you - you have to arrange it yourself 
> (somehow).

This paragraph really confuses me.  So if I have A, and B (subclass of 
A), then the instances of B must be a subset of A?  Isn't this a 
tautology?  I assume that you don't really mean 'proper' subset, as 
that implies no abstract classes exist.

> Other folk have also suggested that in order to properly achieve the 
> above,
> you need to follow the rule: "only abstract classes can be subclassed".
> That is, if you want to create class B as a subclass of class A, and A 
> is
> not already an abstract class, you should create a third class A', 
> which
> _is_ an abstract class, and have both class A and class B inherit from 
> that.
> For a far better explanation of this and many other related issues I 
> refer
> the interested reader to:
>
>      http://okmij.org/ftp/Computation/Subtyping/Trouble.html
>
> my $A0.0148,

In C++, subclass implies subtype.  But in Python, we don't really use 
types in our programming.  Only the functionality matters, which gives 
it its agility IMHO.

Last and most certainly least (look at top),

class Me(Human, DoesPatronizeBank):
     def __init__(self):
         self.deposit(Dollars(1e12))
     def do_stuff(self):
         if self.hungry
             self.eat(self.find_food(select(Thai, Mexican, Italian))

class Computer(ElectricalDevice):
     def __init__(self):
         self.tech_support_history = []

class Asset:
     def __init__(self, obj):
         self.obj = obj





More information about the Python-list mailing list