Replacing Multiple Inheritance with Java's Interfaces 
Author Message
 Replacing Multiple Inheritance with Java's Interfaces

 rw> I'm doing a research project on Multiple Inheritance and I was hoping to
 rw> get a few opinionated responses to the following questions :

 rw> With inherited classes is all code from the class compiled or just the
 rw> objects used from the inheritance? (Curious if code size is reduced by
 rw> using Interfaces)

This depends purely on the implementation.

 rw> Are Java's Interfaces a better solution to the inherit problems caused
 rw> by Multiple Inheritance

No.  Many people do feel that separating the type hierarchy, (interfaces),
from the implementation hierarchy, (inheritance), is a good thing.  But giving
up Multiple Inheritance all together is a bad thing.  Multiple Inheritance has
a bad rap due to the bad implementation in C++.  In truth, a clean multiple
inheritance, (such as in Eiffel, Sather, CLOS, or Dylan) is far more powerful
than single inheritance.

By more powerful, I mean that less code must be written initially, and less
effort expended in evolution & maintenance to do the same job.  This is
because much of the same work that happens automatically in a good MI
language, must be done manually in Java.  In Java, you have to manually
implement every method in an interface.  This is typically done by putting in
stub methods, which delegate the functionality of that interface to a
contained object.  These stub methods are a constant source of maintenance
load - every time an interface method changes signature, all corresponding
stubs in all implemnting classes must be manually changed.

This strikes me as 100% ridiculous.

But then, single dispatch strikes me as ridiculous too.  If you spend a few
months working with CLOS or Dylan, and really thinking hard about design and
solving real problems, you will soon find it far more natural, and start
seeing all the design spots that would be trivial, if only we could use a
language with both multiple inheritance, and multiple dispatch.

The object oriented FAQ has a ton of good info on these and other subjects.

Don


        Software Manager
        NDC Systems                     818-939-3847
        5314 N. Irwindale Ave           Fax:939-3870
        Irwindale, CA, 91706

Disclaimer: These are my own personal opinions, and not those of my company,
or anyone else.



Fri, 17 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Quote:

>But then, single dispatch strikes me as ridiculous too.

What is single dispatch?


Canadian Mind Products    contract programming     (250) 285-2954
POB 707 Quathiaski Cove   Quadra Island BC         Canada V0P 1N0
http://oberon.ark.com/~roedy for CMP utilities and the Java glossary
-30-



Sat, 18 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Quote:


>>But then, single dispatch strikes me as ridiculous too.

>What is single dispatch?

The standard OO polymorphic messaging paradigm: the runtime chooses which
routine (or method, in Smalltalk) to execute based on the type of "receiver".

The opposite is "multiple dispatch", in which the runtime takes into account
the types of *all* arguments in a message invocation.  C++ attempts to do
this with function overloading, but in CLOS, Dylan et. al. it's dynamic
(during execution), not static (at compile-time).

My question for Mr. Erway, though, is what particular problems does multiple
dispatch solve so elegantly.  The two I've heard are testing for object
equivalence and matrix algebra; while both are annoying in a single-dispatch
language, it's nothing unmanageable.  (Certainly multiple dispatch has its
own weaknesses, such as weak encapsulation, runtime overhead, and significant
complications when combined with multiple inheritance, so I'm not ready to
give up on single dispatch yet.)

--



Mon, 20 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces


Quote:


> >>But then, single dispatch strikes me as ridiculous too.

> >What is single dispatch?

> The standard OO polymorphic messaging paradigm: the runtime chooses which
> routine (or method, in Smalltalk) to execute based on the type of "receiver".

> The opposite is "multiple dispatch", in which the runtime takes into account
> the types of *all* arguments in a message invocation.  C++ attempts to do
> this with function overloading, but in CLOS, Dylan et. al. it's dynamic
> (during execution), not static (at compile-time).

Not so in Dylan. Dispatch may be compile-time or run-time depending on what
the compiler is able to infer at a particular call site.

__Jason



Mon, 20 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces


    Date: 3 Apr 1997 03:11:25 GMT


    The opposite is "multiple dispatch", in which the runtime takes into account
    the types of *all* arguments in a message invocation.  C++ attempts to do
    this with function overloading, but in CLOS, Dylan et. al. it's dynamic
    (during execution), not static (at compile-time).

    My question for Mr. Erway, though, is what particular problems does multiple
    dispatch solve so elegantly.  The two I've heard are testing for object
    equivalence and matrix algebra; while both are annoying in a single-dispatch
    language, it's nothing unmanageable.  (Certainly multiple dispatch has its
    own weaknesses, such as weak encapsulation, runtime overhead, and significant
    complications when combined with multiple inheritance, so I'm not ready to
    give up on single dispatch yet.)

If you use classes as the basis for encapsulation, then, yes, multiple
dispatch and multiple inheritance are problematic.  But in my opinion,
the blame falls squarely on conflating classes with encapsulation.

If I might paraphrase, my question for Mr. Mitchell, though, is what
particular problem does object orientation solve so elegantly?  While
using assembly language is annoying, it's nothing unmanageable.

My point is that you can always use the wrong tool for the job.  I am
sure I'm not the only one whose used the handle of the wrench that
I've already got in my hand to pound down that sticking-up bit of
metal, when the ball-peen hammer in my tool box would be a better
choice.  My favorite example is...

Consider a set of 2d geometric classes: regions (with subclasses
point, line, ellipse, polygon) and transforms (with subclasses
identity, translation, and general).  Implement the function
'transform-region' which, given a transform and a region, applies
the transform to the region and returns a new region.  I think you
will find that multiple dispatch is a major win here.



Mon, 20 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Quote:

>My question for Mr. Erway, though, is what particular problems does multiple
>dispatch solve so elegantly.  The two I've heard are testing for object
>equivalence and matrix algebra

The example I've always used is output.  You may have a hierarchy of
graphics types (text, polygons, ellipses) and a hierarchy of output devices
(screens, plotters, printers); you can then implement draw(graphical,
device) methods.

In a single-dispatch language, you're forced to implement something like:

text::draw(device *d) {
  d->draw_text(this);

Quote:
}

polygon::draw(device *d) {
  d->draw_polygon(this);

Quote:
}

ellipse::draw(device *d) {
  d->draw_ellipse(this);

Quote:
}

and then implement all the draw_XXX methods in each device type.  You'll
probably also have to make all the device classes friends of all the
graphics classes (and since friendship isn't inherited, you'll have to
update them whenever a new device class is created).

Note: I think C++'s templates may simplify this, giving the illusion of
multiple dispatch.
--
Barry Margolin
BBN Corporation, Cambridge, MA

(BBN customers, call (800) 632-7638 option 1 for support)



Tue, 21 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Quote:

> Consider a set of 2d geometric classes: regions (with subclasses
> point, line, ellipse, polygon) and transforms (with subclasses
> identity, translation, and general).  Implement the function
> 'transform-region' which, given a transform and a region, applies
> the transform to the region and returns a new region.  I think you
> will find that multiple dispatch is a major win here.

Or a set of geometric classes with operations union and intersection.
With multiple dispatch, you can have intersection methods specialized
on both arguments ( intersect(line, rectangle), intersect(rectangle,
rectangle), etc.)

Jonathan Moody



Wed, 22 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

First off, in response to another post, I didn't mean to imply that
multimethods couldn't be optimized at compile time.  I merely wanted to
emphasize that, unlike C++'s operator overloading, the compiler doesn't
resolve the routine call based on the static type of the variable, but the
dynamic type of the object -- which might mean dynamic dispatch.

Let me also state up front I don't know C++ at all well.  I've taken maybe
one class with C++, and I've picked up other bits as I go.  At work I use
NEXTSTEP, and so the OO language I'm most familiar with is Objective-C.

Quote:

>The example I've always used is output.  You may have a hierarchy of
>graphics types (text, polygons, ellipses) and a hierarchy of output devices
>(screens, plotters, printers); you can then implement draw(graphical,
>device) methods.

You're right, the ways to manage this in traditional OO -- principally the
Visitor pattern from the Gang of Four -- make this sort of thing tricky.  
Many times, though, you can find some simplifying condition:

        - One of your classes has a a bounded set of subclasses,
          or at least grows more slowly.  (E.g. there are a potentially
          infinite number of Graphics, but only a few broad types of output
          devices, the specializations of which behave pretty much the same.)

        - One argument has a finite and fairly fixed number of primitive
          operations.  (E.g. a GraphicalDevice can draw lines, fill in
          shapes, and composite bitmaps.  postscript has been so successful
          because Adobe created one virtual machine to sit atop any
          peripheral: printer, plotter, or -- with extensions -- a display.)

        - For those languages with a runtime (Eiffel, Objective-C, Smalltalk)
          you can sometimes leverage class information in some
          not-too-heinous way.  This is the last resort, and a step not to
          be taken lightly or often, but sometimes it makes things simpler.
          (E.g. Eiffel implements ANY::is_equal(x, y) by comparing the
          attributes common to both classes.)

In your example, I'd actually implement methods on the GraphicalDevice class
to draw lines and points; the draw methods for each Graphic would use those
primitives to perform their work.

Which is not to say this is a better solution; it may not even be acceptible,
if speed requirements or rapidly changing hardware makes abstracting out
primitive operations difficult.  In e-mail someone presented me with the
problem of geometric transforms to shapes, and while I'd pick the same
solution (Transforms apply the primitives of translation, rotation, and
reflection along an axis to a Shape) I'm not too confident of it.

It comes down to the best tool for the best job, I guess.  If I had a job
which involved functional programming I'd push for Lisp; if I needed
back-chaining of rules I'd learn Prolog.  I just have yet to encounter a task
where I really needed multiple dispatch.  Maybe as the runtimes get faster
and multiple-dispatch languages become more prevalent I'll wonder one day how
I lived without it.  (Much like single-dispatch OO ...)

Quote:
>Note: I think C++'s templates may simplify this, giving the illusion of
>multiple dispatch.

Yeah, but as I understand it, it's (exclusively) compile-time dispatch.  No
real win there.

--



Thu, 23 Sep 1999 04:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

 fm> My question for Mr. Erway, though, is what particular problems does
 fm> multiple dispatch solve so elegantly.  The two I've heard are testing for
 fm> object equivalence and matrix algebra; while both are annoying in a
 fm> single-dispatch language, it's nothing unmanageable.

If you look through "Design Patterns", you will see that many of the patterns
are required to work around the lack of multiple dispatch.  For example, the
visitor pattern is exactly and only to simulate double dispatch.  It is a bad
mess compared to the clean solution provided by a true MD language.

In my work, (industrial process control), I find I often have situations where
I have essentially a cross product of 2 sets of classes, one set may be all
the sensor device classes, and the other set might be the set of all data
types, (time based, position based, histogram, fft, SPC, etc).  I have to
simulate double dispatch all the time to take care of this, or I have to code
in switches on types, (yuch!).

 fm> (Certainly multiple dispatch has its own weaknesses, such as weak
 fm> encapsulation, runtime overhead, and significant complications when
 fm> combined with multiple inheritance, so I'm not ready to give up on single
 fm> dispatch yet.)

I disagree.

Multiple dispatch is orthogonal to encapsulation.  I think a package based
encapsulation, (not necessarily class based), could work better any way.
Certainly, Ada works out quite well this way.

Multiple dispatch has no runtime overhead!  Well, as implemented by a good
dylan compiler, it has no more runtime overhead than is required to solve the
problem.  If static dispatch is adequate, that is what will be executed.  If
single dispatch, then that.  If full multiple dispatch is required to solve
the problem, then letting the compiler work it out is a damn site less likely
to incurr extra overhead than a programmer written visitor pattern,
case/switch statement, or if-then-else on types.

Multiple Inheritance is only significantly complicated in C++!!! Every other
langauge that does it, (Eiffel, Sather, CLOS, Dylan, etc), makes it simple.
It is much simpler than having to manually program and !maintain! a bunch of
stub routines to do delegation.

 fm> First off, in response to another post, I didn't mean to imply that
 fm> multimethods couldn't be optimized at compile time.  I merely wanted to
 fm> emphasize that, unlike C++'s operator overloading, the compiler doesn't
 fm> resolve the routine call based on the static type of the variable, but
 fm> the dynamic type of the object -- which might mean dynamic dispatch.

But this is a good thing!  C++ static overloading does not solve the problems
that are solved by multiple dispatch.  If the problem can be solved by C++'s
single dispatch, then a good CLOS or Dylan compiler can emit that code.  But
if a problem requires double or more dispatch to solve it, (aka visitor
pattern, switches, type-cases, conditionals), then the CLOS or Dylan solution
will be *much* cleaner, and very likely much lower overhead!

Don


        NDC Systems                     818-939-3847
        5314 N. Irwindale Ave           Fax:939-3870
        Irwindale, CA, 91706



Thu, 23 Sep 1999 04:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Although the serious example I usually quote is draw(graphical, device),
there's actually a light-hearted example I like that's probably a better
example of multiple dispatch:

have-sex(man, woman)
have-sex(man, man)
have-sex(woman, woman)
have-sex(woman, man) { probably defined to call have-sex(man,woman) }

In traditional OO analysis, you think of one parameter as being special,
the recipient of the "message."  And in some of the examples of useful MD,
you can often force it into that paradigm and use double dispatch.  But
have-sex is difficult to force into that model -- the two parameters really
are equal in precedence.
--
Barry Margolin
BBN Corporation, Cambridge, MA

(BBN customers, call (800) 632-7638 option 1 for support)



Fri, 24 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces


Quote:
>have-sex(woman, man) { probably defined to call have-sex(man,woman) }

Speak for yourself!

__________________________________________________________________


"I have found that all incompetence comes from not paying attention,
which comes from people doing something that they don't want to do.
And doing what you don't want to do means either you have no choice,
or you don't think that the moments of your life are worth fighting
for." - Hal Hartley
__________________________________________________________________



Fri, 24 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

   Multiple Inheritance is only significantly complicated in C++!!! Every other
   langauge that does it, (Eiffel, Sather, CLOS, Dylan, etc), makes it simple.

Astonishing, isn't it?  Python, too.  Too bad Java doesn't provide it for the
programmer.

Bill
--

 Xerox Palo Alto Research Center, 3333 Coyote Hill Rd, Palo Alto, CA  94304
 URL:  ftp://ftp.parc.xerox.com/pub/ilu/misc/janssen.html



Fri, 24 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

Quote:

> OK, from the discussion here I'm convinced that multiple dispatch is worth
> another look.  (Apparently the first look was less than thorough ...)

> My next question is, where can I find an inexpensive (or free?)
> implementation of a multiple-dispatch language -- nothing high-performance
> necessarily, just something to explore with.

Franz Allegro CL Lite is a very nice environment for exploring
this and other matters, and is downloadable free from www.franz.com.

~~~~~~~~~~~~~~~~~~~~~~

Texas liaison for the International Programmers Guild
For information on IPG, see http://www.ipgnet.com/ipghome.htm



Fri, 24 Sep 1999 03:00:00 GMT  
 Replacing Multiple Inheritance with Java's Interfaces

OK, from the discussion here I'm convinced that multiple dispatch is worth
another look.  (Apparently the first look was less than thorough ...)

My next question is, where can I find an inexpensive (or free?)
implementation of a multiple-dispatch language -- nothing high-performance
necessarily, just something to explore with.

Dylan seems the most promising candidate -- compiled, with no unnecessary
runtime overhead -- but every Dylan web page I've found so far has been a bad
link.

Followups to comp.lang.dylan (inshallah).

--



Sat, 25 Sep 1999 03:00:00 GMT  
 
 [ 30 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. Multiple Dispatch (was Re: Replacing Multiple Inheritance with Java's Interfaces)

2. Replacing Multiple Inheritance with Java's Interfaces

3. Should Java have multiple inheritance?

4. Multiple Inheritance of Interfaces?

5. Inheritance of Interfaces ("like in Java")

6. Different kind of inheritance/Multiple Inheritance

7. Comment on Bertrand Meyer's Multiple Inheritance example at the .net seminar

8. Sather's Multiple Inheritance

9. Inheritance: Interface vs Implementation (was: Questions on inheritance)

10. Date manipulation and Java 'interface' equivalents

11. string.replace() can't replace newline characters???

 

 
Powered by phpBB® Forum Software