I don't nessesarily disagree, but it sure can get frustrating when you
need to add a tiny bit of behavior to a standard class and can't override
the method you need. This forces you to use encapsulation to accomplish it
or create a subclass with a new method. Now none of the methods that
accepted the old class will take the new forcing you into a lot more work.
I agree this doesn't happen often but when it does it is extremely
frustrating. Java's methods are virtual by default and seem to cause a
little less stress in this area. I think .Net took the other route so the
Jitter can be simplier and not have to analyze if a method was over-ridden
and make direct method calls instead of calling indirect through a VTable.
Leon Lambert
That's not really the true story. Actually a JavaJitter will optimize
leaf-classes and treat them as non-virtual for perfomance.
The real deal here is that Anders Hejlsberg borrowed this approach from his
Delphi. It also have default non-virtual methods. It tries to save us from
unwanted polymorphism.
I gave this example a few days before, but here we go again..
I write the class Thingy and a set of cool classes that operates on
Thingys.You like my class but you want to add stuff to it; so you subclass
it into MyThingy. One method you add is .DoStuff(). Now a ship a 1.1 version
of my Thingy library and you add that to the project. But what you didn't
look for was that I added the method .DoStuff().
In Java the problem is two-folded. As methods are virtual and there is no
keyword for overriding methods, you just overridden my method. That means
that whenever my cool classes tries to calls DoStuff() your code will be
executed. That gives for some weird bugs. And when you wrote your method you
had no Super() to call on, so my code doesn't get executed at all. The
thingy will probably be in a corrupt state. And all this just happened
without you even knowing. The compiler compiles away happily.
In C# (and Delphi) methods are not virtual by default. When a collission in
names occur you get a compile-time error telling you to either reintroduce
the method or rename it. If it is virtual you can override it.
In this example the good thing for you would be to rename your method as
ours have nothing to do with eachother.
But you could reintroduce it and everything works just fine. The Thingy
classes only have references to Thingy and so my classes would call my
methods. You only have references to MyThingy and so your methods will be
called from your code.
But then again, the best would be to rename your method.
When a class-developer plans his methods he make these statements:
virtual - This method should be used in a polymoprhic behavour and my code
is so general that it will work for all possible subclasses you can think
of.
non-virtual - This method does stuff. If you don't like stuff you can always
reintroduce and replace whatever code you want. I don't care. You're on your
own.
And as you see, you don't need to create a wrapper. You can often
reintroduce.
Happy Coding
- Michael S