R
Rob Teixeira [MVP]
Hung Jung Lu said:Erh? You got the direction wrong. It's not down the tree, it's up the
tree.
Depends which direction the tree is pointing ;-)
Secondly, in Mix-In class methods, you do not want to access parent
data fields, you want to access child data fields. That's the beauty
of it. I guess you just jumped in without having read my points about
virtual data fields.
I read it, but your context got lost in the noise of the other posts.
Ask yourself: how can a parent class method access the data fields of
a child class? A first answer is: you CAN'T. When you designed the
parent class, you had zero information about the child class. In
statically typed languages like C++/Java/C#, there is simply no way of
accessing child data fields directly. These languages don't support
virtual data fields.
Correct, because these languages abide by the tenet that while it's cheap to
access a field of a different type, you should only directly access a field
of your own type, which prevents inadvertant and unwanted value updates and
reads that can cause issues with the implementation details of the other
type. This, in my opinion, is the biggest risk with multiple inheritance
(and as I said, i'm not entirely opposed to MI either).
So far so good for C++, until you are hit with absence of MI class
inheritance in C#/Java. You then scratch your head and ask yourself:
"How in the world can I write a Mix-In class?"
If you abide by the basic definition of a Mix-In class, which is an abstract
class designed to be blended with another type through MI in order to extend
its members, then I think you will find it isn't such a stretch after all.
That in fact, Mix-In classes are just syntactical sugar for alternate
structural mechanisms.
Well, you can still do it. If the Mix-In class B is specifically
designed to enhance an existing class A, your methods in B can take
instance of A as the first argument. You then do
containment+delegation to expose the B interface for the new class.
Yep.
All these things are voodoo magic in C#/Java. (And I am sure I have
lost 95% of the audience.) But in dynamically typed languages like
Python or Ruby, these are banalities not even worth a discussion.
Sure, under the hood they are quite equivalent. But in C#/Java you (a
human) are basically doing the job that a good compiler (a machine)
should do.
While I don't disagree with you, I think the underlying principal is that
the designers of these languages came to the conclusion that the "good
compiler" is allowing programmers to do things that perhaps shouldn't be
done, or at the very least create a recipe for danger too easily. Whether
one agrees with that decision or not is a matter of personal opinion.
Personally, I think there are far better uses for MI than Mix-In classes,
but in the C#/Java world, we simply have to live without it. Now, having had
to maintain programs that were falling apart at the seams because of
convoluted inheritance trees, I can understand the concern, though I haven't
completely decided that I agree 100% or not with the language designers -
especially since, if you forget the gritty internal details and think about
the overall design structure, there certainly are ways to still accomplish
the underlying goals.
After you are laboriously and happily done with using class MI and
factoring out the common code spots of your program, you would
probably cry again when you need to make changes. MI is just too hard
to use directly.
Yes. And therein lies a good deal of the pain
The test of any object model is it's ability to be maintained and extended
AFTER the initial implementation, and MI *can* easily cause that to collapse
quickly. Note that I said *can* because some people insist on preaching that
MI is evil, like it's guaranteed to break things, and I'm certainly not
advocating that line of thought.
In C#/Java, a better approach is to use a code
generator, and just let the common code spread all over different
classes. Sure, this is code bloating (much like templates in C++,
which are just macros). But given the shortcomings of C#/Java, you
don't have much a choice.
Hm, I'm not entirely convinced that's the only choice. And having lived with
deficient code generators before, I'll take my chances with something else
(even if it is a little more manual)
But on the flipside, I can honestly say that I haven't gone through
withdrawl over the lack of MI either.
-Rob Teixeira [MVP]