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