Multiple inheritance equivanlent in Java/CSharp

H

Hung Jung Lu

Hi,

This is a question for people that have experience with multiple
inheritance (MI) or equivalent in Java/C#.

A relevant url is:
http://www.cyberdyne-object-sys.com/oofaq2/DynInh.htm

Java/C# do not have class MI. Java/C# go through interface MI, they
use containment instead of aggregation, they implement the interface
methods through delegating to the contained instance members. At least
this is the normal approach. Problem is of course when some of the
base interfaces change. It's a pain: you have to edit all the
subclasses that inherit the interfaces.

What do people do to circumvent these problems, short of purchasing
commercial solutions like cyberdyne?

thanks,

Hung Jung
 
X

xarax

Hung Jung Lu said:
Hi,

This is a question for people that have experience with multiple
inheritance (MI) or equivalent in Java/C#.

A relevant url is:
http://www.cyberdyne-object-sys.com/oofaq2/DynInh.htm

Java/C# do not have class MI. Java/C# go through interface MI, they
use containment instead of aggregation, they implement the interface
methods through delegating to the contained instance members. At least
this is the normal approach. Problem is of course when some of the
base interfaces change. It's a pain: you have to edit all the
subclasses that inherit the interfaces.

What do people do to circumvent these problems, short of purchasing
commercial solutions like cyberdyne?

thanks,

Hung Jung

Changing the base interface means that your original
interface design was flawed. Discovering the flaw early
in the design stage, rather than after implementation,
is always best.

Having said that, I use code generators to specify the
interface with any number of parent interfaces, along
with an abstract class implementation of some of the
instance methods declared in the interface. The code
generator merges the abstract class implementations
of all of the parent interfaces into the abstract
class implementation of the current interface being
generated. All of the client code refers only to
the interface type(s), which is/are (partially) implemented
by the abstract class(es).

I use a concrete class to fill-in the remaining pieces
of the interface. This minimizes the amount of change
to the concrete implementation when I must change the
interface definition. Also, when any of the parent
interfaces or implementations change, I regenerate the
dependent (i.e., extending) interfaces and the code
generator re-merges the changes into the abstract class
implementation. Then recompile.

It doesn't handle all possible forms of Multiple
Inheritance of Implementation, but it's very good
for my needs.

The interface specification is in XML, and there
is a Swing GUI wrapper front-end for easy maintenance
of the XML.
 
T

Tor Iver Wilhelmsen

What do people do to circumvent these problems, short of purchasing
commercial solutions like cyberdyne?

Delegate to a Proxy/InvocationHandler pair for instance? :)
 
H

Hung Jung Lu

xarax said:
Changing the base interface means that your original
interface design was flawed. Discovering the flaw early
in the design stage, rather than after implementation,
is always best.

This is easy to say. :) Just as easy as: (a) using pointers to create
and destroy objects is fine, if there is a problem, it's because you
did not follow the rules. (b) Checked exceptions are great, if you did
not fully catch all the exceptions, it's your problem. Well, after
garbage collection appeared, people defending (a) went silent. After
Python/C# usage of unchecked exceptions, Java people (b) went silent.
When there is a problem, you can either blame the programmer or the
programming language. Knowing that multiple inheritance works well in
other languages, like Python, you could draw your own conclusions as
where the problem is. Java does not allow virtual data fields, that's
the root of the problem. Virtual data fields of course are more
expensive to access (just as virtual functions), but as my friend a CS
professor once said: there is only one trick in CS, and that is one
extra layer of indirection. If the extra layer of indirection makes
your life easier, then people are willing to go for it. Java's
original design was flawed. They did not discover the flaw in the
design stage, but rather after implementation. :) So I guess by your
logic they did not do their best. But more seriously, we are all mere
mortals, we can't predict the future. Asking people to know ahead of
time what the future will be is hard. Same with interface designs. A
system that does not allow you to change and adapt, is a bad system.
That being said, we all live with what's given to us, no matter
whether it's the good, the bad, or the ugly.
Having said that, I use code generators to specify the
interface with any number of parent interfaces, along
with an abstract class implementation of some of the
instance methods declared in the interface. The code
generator merges the abstract class implementations
of all of the parent interfaces into the abstract
class implementation of the current interface being
generated. All of the client code refers only to
the interface type(s), which is/are (partially) implemented
by the abstract class(es).

That's cool. So basically you have macros (code generators) to perform
the meaty part of the multiple inheritance, namely, code re-usage of
the method implementations. Basically pre-compile-time
meta-programming. Problem is, it's something on top of Java, just like
Cyberdyne. I guess in plain Java we just have to live with multiple
pairs of (interfaces, class implementations), and keep using
(containment+delegation) to make up for the lack of aggregation. And
as for consumers of interfaces, we will live with zillions of getters
and setters, to make up for the lack of virtual data fields. The
upcoming generics in next release of Java should offers a slightly
easier alternative to this last part.

thanks,

Hung Jung
 
N

nos

all i want is the "goto"

Hung Jung Lu said:
"xarax" <[email protected]> wrote in message

This is easy to say. :) Just as easy as: (a) using pointers to create
and destroy objects is fine, if there is a problem, it's because you
did not follow the rules. (b) Checked exceptions are great, if you did
not fully catch all the exceptions, it's your problem. Well, after
garbage collection appeared, people defending (a) went silent. After
Python/C# usage of unchecked exceptions, Java people (b) went silent.
When there is a problem, you can either blame the programmer or the
programming language. Knowing that multiple inheritance works well in
other languages, like Python, you could draw your own conclusions as
where the problem is. Java does not allow virtual data fields, that's
the root of the problem. Virtual data fields of course are more
expensive to access (just as virtual functions), but as my friend a CS
professor once said: there is only one trick in CS, and that is one
extra layer of indirection. If the extra layer of indirection makes
your life easier, then people are willing to go for it. Java's
original design was flawed. They did not discover the flaw in the
design stage, but rather after implementation. :) So I guess by your
logic they did not do their best. But more seriously, we are all mere
mortals, we can't predict the future. Asking people to know ahead of
time what the future will be is hard. Same with interface designs. A
system that does not allow you to change and adapt, is a bad system.
That being said, we all live with what's given to us, no matter
whether it's the good, the bad, or the ugly.


That's cool. So basically you have macros (code generators) to perform
the meaty part of the multiple inheritance, namely, code re-usage of
the method implementations. Basically pre-compile-time
meta-programming. Problem is, it's something on top of Java, just like
Cyberdyne. I guess in plain Java we just have to live with multiple
pairs of (interfaces, class implementations), and keep using
(containment+delegation) to make up for the lack of aggregation. And
as for consumers of interfaces, we will live with zillions of getters
and setters, to make up for the lack of virtual data fields. The
upcoming generics in next release of Java should offers a slightly
easier alternative to this last part.

thanks,

Hung Jung
 
B

brougham5

Problem is of course when some of the
base interfaces change. It's a pain: you have to edit all the
subclasses that inherit the interfaces.

Simple solution: don't design interfaces that require methods to change.
Design interfaces that are more flexible. If need be, change the interfaces
into abstract classes with default implementations of newly added methods,
so that you don't have to change all your dependent code if you add a new
method.

Complex solution: buy a proprietary "solution" that pretends to mask the
problem of not designing an interface right the first time.

Nobody is claiming to be a guru that never makes a mistake or oversight when
it comes to interface design. But this tool won't help much, either. For
starters, I'd question their "design" that they're using. Start with a bad
design, and your solution is more complex.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top