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