PART 1 - INTRODUCTION
I've been following the classes dabate with interest and I would
like to make a few comments. I've been reading it offline and
while doing it I colected a few topics to comment.
Probably they are out of time but, anyway, here it goes.
I've some difficulty in expressing this concepts in English but I feel
they are important for the quality of programming and deserve a try.
If you don't understand it or think is rubbish, don't flame right
away. Be patient and give it a second read, please.
When I refer to good OO language/programming I'm using
"Object-oriented software construction" from Bertrand Meyer. By the
way, the topics discussed in this threads (except when Access
specific) and much more are superbly covered by this book.
PART 2 - Modelling with classes
>Dave L wrote:
>What we do in VB and VBA:
>Let's invent a class called clsAddNum, and give the class a method called
>Add() that we can pass two numbers to, and it returns the result of adding
>those numbers together.
clsAddNum is not a good class example, for two reasons:
1- Classes are used to model data not functionality. It just happens
we need functions to manipulate data. This is a bit subtle, but when
programming in OO we shift our focus from functions (which happens to
need data) to objects (which happens to need functions).
I know this is only an example but people not familiar with OO could
get the wrong idea. It seems some of you are using classes just to
organize code or get similar/related things _together_. Classes are
not a panaceia to handle any programming problem... Let's be more
carefull about applying classes, please... Let's focus on data (with
2- If you want to add two numbers in OO, both of them are objects. One
of them receives an ADD message having the other object as a
>Lyle Fairfield wrote:
>Property Gets ... these trouble me.
>Instance1ofAddClass.FirstOperand = 5
>Instance1ofAddClass.SecondOperand = 3
>(perhaps much later)
>intVariable = Instance1ofAddClass.Sum
>which stores 8 into intVariable.
>intVariable = Intstance1ofAddClass.Sum(5,3)
Please don't do this. See above.
Oh! By the way, in good OO languages you add numbers as 5+3 (familiar
isn't it?), even when you are using classes to model numbers.
PART 3 - A bad programming example
(sorry Dave; you are free to disagree...)
>Dave L wrote:
>Public Property Let MIR(sngRate As Single)
> ' Elementary checking example
> If sngRate >= 0 And sngRate < 100 Then
> MsngMortgageInterestRate = sngRate
> MsgBox sngRate & " is not a valid rate@@", _
> vbExclamation, "Mortgage Interest Rate"
This simple example has two bad programming practices:
1- Validating the parameter data (wait a moment, don't flame now)
2- Dealing with the error using a message box.
Explanation follows (trial one...)
1- According to Bertrand Meyer (BM) you should not be validating the
function parameters all the time. Yes, he is saying (and I agree),
contrary to usual belief, that this is BAD programming practice.
BM recommends a "Design by Contract" practice, in which we expose
our classes with some use conditions. If you (the class user) don't
respect the contract conditions, you are in trouble and that's
The advantage? you get simpler and more efficient code. So, when
using a class, if you want to, you can check your parameters BEFORE
calling the function (method). But you only do this if you don't
trust your own code :).
Please note that this IS DIFFERENT from validating USER INPUT. You
can never trust your end-users (because they are human; see also
"idiot checking's" thread).
Design by Contract has a lot more than this and the book explains it
2- (Dealing with the error using a message box.)
Some code will call your procedure. Your procedure must answer to the
code and not to the user. The caller code will CONTINUE execution
as if no problem had ocurred! You should raise an error that
can/should be trappable by the caller code. See raise method in
A lot more can be said concerning exception handling. Essentialy,
- RETRY, as many times as you think is necessary, modifying
the starting conditions and/or using another approach;
- FAIL, failing previous step and as last resort, assume Failure
by cleaning up the context you created and reporting to the caller.
Refer to Access help file and Bertrand Meyer book.
PART 4 - On overloading, polymorphism and other goodies
>Dave L wrote:
>I'm not entirely sure what you are pointing out here Lyle?... One still has
>to specify the parent class and method or property, e.g., parent1.Add(X,Y)
>or parent2.Add(X.Y), if the method/property names are the same in several of
>the parent classes, even in real inheritence. In simulated inheritence we
>just have to do it all of the time.
1- see previous comment on recomended technique to add numbers in OOP
2- Something not clear for me in this part - I think I am going to say
the same as you, with more words.
In OOP when calling a method, you have ALLWAYS to reference
the object, except if it is implicit as "Me" in Access, "this" in C++,
"Current" in Eiffel or "self" in Smalltalk.
So, if you reference the object, the compiler knows its class and
the right method to call. Things get more complex when you have
Polymorphism (see below) and Multiple Inheritance (except if you
simply kill it, as in Java). In this case, the right method can only
be picked at run-time (as opposed to compile time).
In simulated inheritance, your own code must know where the right
method is in the hierarchy. You must have lots of added code to manage
the hierarchy. Too much work to even think about it.
>It's only the presence of the mechanism that handles "overloading" in other
>languages that allows the identity of a parent class to be implied rather
>than explicitly defined when methods have the same name (we haven't touched
>upon overloading because it isn't available in VB, but I would love to see
>overloading introduced into VB).
>Brief explanation of overloading for others reading this: Overloading allows
>one to define more than one function with the same name, providing the
>argument types are different in each definition. The compiler then
>determines which function to call by the types of arguments passed to it. It
>sounds confusing but it's a real gem of a facility when used in a language
>where typecasting is strict (in VB we can stuff just about anything into a
>variant, so we couldn't have overloading because VB wouldn't know which
>function to call).
I would like to expand a little on this concept and warn against it in
In VB we can have the same method name in different classes. In my
opinion this is good enough for most of the time.
Now, when we are talking about the same method name in the same class
(which is not possible in VB) most OO languages resort to what is
called syntatic overloading. In this case, as you say, the function
signature (number of arguments and its type) diferentiates between
methods. The compiler picks the right one at compile time.
However Bertrand Meyer (BM) says that this kind of overloading should
NOT exist in good OO languages.
1- you should not have the same name for doing different things in the
same class. You and the compiler have to look for the method signature
to understand what's happening. Things are not clear with this
2- this is limited because you can't have two different methods having
the same name and the same signature.
A simple example (from BM book):
Consider a class POINT having x and y cartesian coordinates.
You can create a point using two initialization functions using
cartesian or polar coordinates (which also requires two real numbers).
Both of this functions should have the same signature and name. You
can't do it in C++ or Java, for instance.
1- give different names to different functions in the same class (even
for the class creators).
2- use DYNAMIC Overloading (DO) to allow the same method name and
signature, but with different implementations, to co-exist in the same
hierarchy (in a father/child relation).
Simply stated, Dynamic Overloading is the RUN-time capability to pick
the right method for the caller object, which is different from Static
Overloading, in which name resolution is made at COMPILE-time.
BM says the real OO language should have Dynamic Overload (or Dyanmic
Binding, at run-time). This is only really required when we have
polymorphism (the capability to have one variable of type A to hold a
reference to an object of type B, where type B is a child of A) and
The funny thing is that we already have a kind of polymorphism in VB,
supported by the Variant type. We can use a Variant variable to hold
any object reference and we are able to call any of its methods even
there exists another Class with a method with the same name &
signature. One of the limitations is to have the same name&signature
in the same class, which is not a good thing to do (because it's
confusing and hard to read).
Obviously this is a non-relevant kind of polymorphism. The real
polymorphism happens when we have inheritance.
If MS introduces inheritance it would have to change the mecanisms
that handle the Variant type. The semantics of the VB language would
become much more complex and kill THE biggest advantage of VB:
simplicity. Do you remember the meaning of BASIC? It starts with
To finish, BM demostrates that both kind of overloading (syntatic and
dynamic) should not co-exist.
PART 5 - CONCLUSION
1- OO is not a panaceia
I am not implying with my comments we should apply OO programming all
the time. I am simply saying that there lessons to be learned, there
is space for code improvements over classical structured/functional
programmings, using a different light. OOP is not just classes
and objects as you saw. There are other tecniques involved that can
I higly recommend the BM book, not only because he explains OO
very well, but because he made me saw OO programming as a natural next
step after structured/functional programming with some advantages
2- My experience combining OO and Access
I don't generally use classes in Access because I have small projects
and not much space for reusability. But I have some library code in
mind and I will apply as much OO as it makes sense for reusability
3- MS and the OO approach with VB
I am not sure that MS should augment VB to make it more Object
Oriented. I believe we only require all the OO artillery when doing
large projects (yeah, I know, kids grow up) or doing several simillar
If they try it, I hope they can keep it simple, quickly graspable, and
don't mess with the documentation. Remember the meaning of BASIC and
the one of the reasons Visual Basic became so successeful.
By the way, associating modules and the concept of classes was a great
thing to do (I'm sure they have been reading BM book as this is one
of his recomdendations)
WOW! the longest and hardest post of my life. It took an whole morning
of my short hollidays to write it. Hope you find something useful in
Fernando C Martins
> WARNING: very long post ahead, split in 6 independent parts
> PART 1 - INTRODUCTION
> I've been following the classes dabate with interest and I would
> like to make a few comments. I've been reading it offline and
> while doing it I colected a few topics to comment.
> Probably they are out of time but, anyway, here it goes.
> I've some difficulty in expressing this concepts in English but I feel
> they are important for the quality of programming and deserve a try.
> If you don't understand it or think is rubbish, don't flame right
> away. Be patient and give it a second read, please.
> When I refer to good OO language/programming I'm using
> "Object-oriented software construction" from Bertrand Meyer. By the
> way, the topics discussed in this threads (except when Access
> specific) and much more are superbly covered by this book.
> THE END
> WOW! the longest and hardest post of my life. It took an whole morning
> of my short hollidays to write it. Hope you find something useful in
> Fernando C Martins
Very interesting reading! Thanks for taking the time. (Sorry about the lost
I'm sure that others will get into the details with you, but I'm just trying to
stay mildly "au courrant" with OO theory, and I enjoyed what you had to say.
Darryl Johnson Darryl....@nlc-bnc.ca
National Library of Canada
** None of the above has any official status **
I almost missed your post as it was hiding in over 1300 bulletins!...
My somewhat meagre response (due mainly to complete lack of time... I'll be
glad when the year 2001 arrives so I can take a holiday!!!... Well, you
don't expect me to fly anywhere while air traffic control are still using 2
digit years do you?)...
I have to say that the examples in my posts were _extremely_ crude and only
there to get some sort of hold on the basic principles, plus the discussion
topic was not particularly concerned with validation and error trapping at
the time, but the point was (correctly) made in the surrounding comments
that using classes promotes better error checking, and consequently, also
makes the class code properly reusable without modification.
Validating data and handling daft values properly is the responsibility of
the class author, not of the class user. If there is no error checking then
you have to make _absolutely_ sure that it says so in the documentation. The
compromise and solution is to include an error checking property in the
class, then let the calling code set it to false if checking is done
elsewhere. That would allow a class to be used as-is, or buried deep within
other classes without the penalty of speed reduction due to duplicated error
Direct user interaction within a class is very common. Take input masks and
the validation property in Access controls, and DAO itself. Error handling
can do one of three things; Cope with the error (prompt the user and/or deal
with it in some way), set a flag to show an error has occurred, or stop the
program. Classes have a big advantage. They can also generate events to make
error interception easier for the calling code.
In simulated inheritance, you expose the parent properties and methods
through the children, so as far as the calling code is concerned, the
properties and methods belong to the child, what goes on behind the scenes
is between the child and the (possibly many) parent classes. It should be of
no concern at-all to the calling code where the abilities of the child come
from, and providing each class is documented properly, there should be no
trouble maintaining and improving upon them.
I appreciated your post, and please rest assured that it was also received
in the spirit intended.
(Plus, I've run out of matches and haven't got the energy to rub two sticks
>Validating data and handling daft values properly is the responsibility of
>the class author, not of the class user. If there is no error checking then
>you have to make _absolutely_ sure that it says so in the documentation. The
>compromise and solution is to include an error checking property in the
>class, then let the calling code set it to false if checking is done
>elsewhere. That would allow a class to be used as-is, or buried deep within
>other classes without the penalty of speed reduction due to duplicated error
Well, I was trying to tell you (or anyone else) the opposite could be
a better programming approach. I explained the advantage was a better
(clear and more efficient) and simpler code to mantain. Besides,
deffensive programming is NOT a productive one. It exists only to trap
BUGS. This does not apply to user input checking.
Not checking for valid data (other than user's data got from input or
similar) is only PART of a different programming approach proposed by
Bertrand Meyer, called Design by Contract. This methodology REQUIRES
also that we code ASSERTIONS in the language (the supporting
mechanisms do not exist in VB. Perharps they could be simulated
(again)). Assertions are much more powerfull than simple error
checking, more flexible (you can turn on/off outside of your code),
"separate" from the productive code and are used to specify the
functionality of the class (input and output).
But I suppose this is going too much out of topic...
>Direct user interaction within a class is very common. Take input masks and
>the validation property in Access controls, and DAO itself. Error handling
>can do one of three things; Cope with the error (prompt the user and/or deal
>with it in some way), set a flag to show an error has occurred, or stop the
>program. Classes have a big advantage. They can also generate events to make
>error interception easier for the calling code.
Yes, that's fine. What I was explaining (trying to) doesn't apply to
Can you explain the events part? are you talking about Raise?
>I appreciated your post, and please rest assured that it was also received
>in the spirit intended.
Uff, that's nice :)
>(Plus, I've run out of matches and haven't got the energy to rub two sticks
Did you hear about holidays? ;)
Fernando C Martins
>Can you explain the events part? are you talking about Raise?
I'm sorry, this isn't the first time I've made this particular mistake in
this newsgroup 8-(, but you are the first to pick me up on it.
Access doesn't in fact implement events in the classes, it's VB5 that does,
and it's a really excellent facility. My problem is I go between VB5 and
Access like a shuttle in a carpet weaving factory. I'm really sorry if I've
There is, fortunately, a very simple work-around to generate events in
Access from a class.
1. On your form, create a button for each event you want to generate, and
set the transparent property for all of the "event" buttons to True.
2. Put code in each of the On Got Focus events of the buttons to do
3. When you create an instance of your class, send it references to the
transparent buttons (Property Set).
4. When the class needs to generate an event, all it needs to do is set the
focus on the form to one of the transparent buttons.
This technique can be used to synchronise multiple form interfaces too of
I hope MS will reduce my embarrassment by introducing events in Access 9...
Example code to show how it's done
----- The form -----
' In the declarations section of the module behind a form
Dim c As clsEvent
' In the OnLoad event of the form
Set c = New clsEvent
Set c.CTL1 = Me.cmdTransparentEventButton1
' In the OnClose event of the form
Set c = Nothing
----- The Class -----
'In the clsEvent class module declarations
Private mCtl1 As Control
Public Property Set CTL1(Ctl As Control)
Set mCtl1 = Ctl
Private Function GenerateEvent1()
Your other points were noted, although I think we'll have to agree to differ
regarding "defensive" coding. One of the points of object programming is to
make each object as solid as possible. Unpredictable behaviour due to out of
bounds method or property values is not, IMO, an option when authoring
classes, especially when the classes are used by third parties and other
All the best.
Tanks for your post on events.
Today I discovered there are other relevant differences concerning OO
in VB5 in an article from VB Programmer's Journal (August), relative
to polymorphism and inheritance.
It _seems_ (I've just read the introduction) that VB5 allows a kind of
inheritance using the keyword Implements, which is not available in
All the best.
Fernando C Martins
Ops! I forgot it.
I've been doing defensive programming in VBA :-)
AFAIK, only Eiffel has the complementary mechanisms (Assertions) to
support non-defensive programming, keeping final code quality.
Fernando C Martins