Ken,
I'm on a team building some class libraries to be used by many other
projects.
Some members of our team insist that "All public methods should be virtual"
just in case "anything needs to be changed". This is very much against my
instincts. Can anyone offer some solid design guidelines for me?
They are missing the point of object orientation. The first and foremost
benefit is not "ultimate" flexibility", neither is is re-use. The main
benefits are control of complexity; 1:1 mapping of the real world to a model
and comprehensiveness.
First, virtual methods do not come free, they perform worse than non-virtual
methods. Now this may be an issue and it may not, depending on the kind of
application and the way the methods are used.
Another thing. If something is declared virtual, that is a statement on the
part of the designer. It implies some generic behavior that may need to be
altered somehow for any derived.class in order to obtain the desired
behavior. It helps the developer understand the problem domain. Declaring
everything virtual is bad because the developer will wonder how he should
deal with the method in e derived class. Must he override it? Must he call
the inherited implementation? Before or after his own actions? Can he leave
it like it is? If I were that developer and I had been thinking this over,
trying to understand the purpose of a particular virtual method not
understanding how to deal with it and I finally went go to the designer of
the base class and I would ask why and he would say "For no particular
reason, I just couldn't be bothered thinking too hard about the consequences
of sealing it so I left it all open for you, providing ultimate flexibility,
so you can do the thinking I could not be bothered with, aren't you happy?"
Then I would not be happy.
Imagine every public method of a fairly complex class being virtual. Most of
them will implement fixed behavior that is not supposed to be overridden. It
would only invite developers to screw things up and they would not
understand what is expected of them.
Finally, if at some point "something needs to be changed" and polymorphism
would be the answer, then that would be the right moment to open the base
classes source and change the declaration for the particular method to
protected (not public, heaven forbid).
I read the discussion on private virtual methods too. While some languages
may technically allow them they don't make sense. In Delphi for instance you
can declare both the base class's virtual methods and the overrided derived
class's method private but that only compiles as long as both the base class
and the derived class are in the same source file. Once the derived class in
in a different source file, all the base class's private methods are
invisible and the project won't compile. Needless to say that little
projects have all classes declared in the same source file. Since it only
works if you put everything together or make everything friend with
everything else it is absolutely pointless because you can in those
situations access anything in your base class from anywhere, it is as good
as putting everything in the same class right away and not derive at all.
So the boys are wrong, you are right. Rub it in.
Martin.