Wiki Home

VBReuse For VFP ers Part 2

Namespace: SoftwareEng
A Wednesday Night Lecture on Dec 20th given by Vin Miller

VB Code Re-Use for VFPer's Part 2: Interface Inheritance and IMPLEMENTS
A follow-up to the November 29 lecture on VB code re-use. We concentrated very heavily on interface inheritance in that lecture, and, truth be told, just began to scratch the surface. So, this follow-up will focus on the next steps for understanding and making use of interface inhreitance in VB. Topics covered will include:

  • Implemented interfaces and Polymorphism. How can interface inheritance enforce polymorphism?
  • Abstract interfaces and VB's Instancing property. Should my interfaces be purely abstract, and if so, what does that mean for my class design?
  • Multiple Interface Inheritance. Can I inherit more than one interface, and if so, what does that mean exactly? How does VB decided how to act in the case of identical method or property declarations?
  • Multiple layers of interface inheritance. How can I daisy-chain ancestors to really specialize and extend my subclasses? Which techniques make sense?
  • Interface Inheritance of Properties. What's with this Let and Get stuff?
    This lecture will pick up where we left off from the November 29 lecture, so if you did not attend that lecture, I strongly recommend that you check out the posted transcripts at VBReuse For VFP ers . To be fair to those who did attend that lecture, we will not be re-covering that material.

    [Irrelvant material has been trimmed.]

    Session Start: Wed Dec 20 20:48:38 2000

    [20:51] *** Cindy Winegarden changes topic to 'VB Reuse for VPPer's Part 2 with Vin Miller'

    [20:59] {CindyWinegarden} The presenter tonight is Vin Miller. Vin Miller is an independent consultant based in New York City, working in both Visual FoxPro and Visual Basic. He was a contributing author to Que's Special Edition UsingVisualFoxPro6??, and has published recent articles in both FoxPro Advisor and Access-VB-SQLServer?? Advisor. A brief mid-90's foray into statistics and research resulted in co-authorship of several works on international demography and quantitative research techniques.

    [21:05] {VinMiller} Well, I'd like to pick up where we left off last time. When I first planned a "Code Reuse in VB" lecture, I had about five topics planned. Interface Inheritance, and delegation, was just one. But, as so often happens, I soon realized that we needed more time on it. As I mentioned last time, one of the primary methods of code reuse in VB involved Interface inheritance, via the Implements keyword.

    [21:07] {VinMiller} To start with, and I know I discussed this last week as well, we need to think about the concept of an interface. In VFP and VB both, programmers work with classes. In VFP one or more classes can be stored in a class library, while in VB, each class has its own class module file.

    [21:08] {VinMiller} An Interface is the "public face" of a class. In other words, it represents the contract between the class(es) and any client processes. We don't really have this concept, technically, in VFP. But, if you've ever worked with abstract parent classes, which are intended purely as classes from which to subclass method calls and propeties, you have a good idea of what I am talking about.

    [21:10] {VinMiller} Methods and properties are defined, so that other classes can inherit them. But, you would not want someone going out and creating an instance of such an interface. In fact, many VFP developers I know have a RETURN .F. in the Init of these classes.

    [21:11] {VinMiller} Conceptually, that's an interface. And in VB as well, programmers work with interfaces, even if they don't realize it. That's because while the concept of an interface exists in VB, and you can IMPLEMENT an interface, you create one just as you would a plain old class.

    [21:11] {Evan Delay} Why the RETURN .F. ?

    [21:12] {MarkusVoellmy} To avoid the creation of the Object Evan. I have worked with class structures where, for instance, the highest class in the hierarchy is intended purely as a structure for subclasses. It wouldn't really have a meaning in and of itself.

    [21:12] {Evan Delay} Thanks Vin.

    [21:13] {VinMiller} Well, in VB, as I said, the concept of an interface is somewhat more present, although it shares with VFP the lack of a separate Interface editor.

    [21:14] {VinMiller} I dwell on this because I really want to share something... many VB programmers I have met are fuzzy on this stuff, too. It really becommes more crucial in a COM context, but it is definitely useful for reusing code in VB as well. The reason for this is the following:

    [21:14] {VinMiller} While you cannot inherit code in VB, you can, in fact, inherit an interface. We began to demonstrate that last time, and I think we got quite far, but I really wanted to continue this evening with discussing the concepts -- and practices! - involved.

    [21:16] {VinMiller} It might be time to go ahead and download the sample files: This project is pretty similar to the VB project from the first part of this lecture. The example in this project was inspired by a question that a colleague asked. he worked on a financial app and wanted to know how, without true inheritance, a VB programmer could reuse the code that any sort of financial transaction needs to make use of. In other words, in an environment that supports inheritance, like VFP or C++, he would create a Transaction object with various methods. Then, he would subclass as needed from there. He was really at a loss as to how this could be done in VB, though -- but he guessed (correctly) that there must be some way to not have to retype common methods.

    [21:21] {VinMiller} For those with the VB project, take a look at the frmSubmitTransaction. You can get to this by pressing Ctrl-R and then expanding the Forms folder.

    [21:22] {Evan Delay} OK

    [21:22] {VinMiller} I've created a very basic little form here -- two (meaningless) text boxes, and three command buttons labelled "Contribution" "Withdrawal" and "Transfer." Each of these buttons creates an instance of a class and executes a method or two of that class.

    [21:23] {VinMiller} I want to review very quickly the class structure, which we discussed in length last week:

    [21:24] {VinMiller} Under "Classes" in the project window, you will see a Transaction class. I will be using this as a parent class, or as an interface. There's not too much going on here. I have defined a couple of methods and properties, and I have thrown messageboxes in to show us that they are being called.

    [21:25] {VinMiller} But if you go ahead and open the Contribution class, you'll notice something different right off the bat. The first line is "Implements Transaction". This says that the contribution class wants to inherit the interface of the Transaction class.

    [21:27] {VinMiller} We discussed this last time, so I won't dwell too much. Two important points:

  • 1. under the combo box on the left hand side of the code window, you will see that there is now a Transaction secotion of code. If you select this section, all of the methods of the Transaction class appear on the right. The IDE pulls them in, and you can now fill them with something meaningful.
  • 2. A common technique for code reuse among VBer's is to inherit an interface, and then delegate calls to the interface's methods onto a child instance of the "parent" class. And that's exactly what we do in this Contribution class. We Implement the Transaction interface. Then, we also create an instance of the Transaction class, and a series of references, under each and every method, to pass any calls onto this instance.

    [21:30] {VinMiller} Last time, I talked about how this is, in effect, turning the inheritance paradigm we are used to on its head.

    [21:31] {VinMiller} This is a common technique, because while, with say 15 methods and 10 properties, it's a heck of a lot more typing than DEFINE CLASS x AS y, once it is done, any changes to the Transaction class will be reflected in any class using this technique.

    [21:31] {VinMiller} Does that make sense? We reviewed it last week, but as I have said, it is a bit odd to those of us used to a slicker inheritance model.

    [21:32] {Evan Delay} Yup

    [21:32] {LesPinter} Yup, also

    [21:32] {MarkusVoellmy} Yup, though I'd call it a workaround ;)

    [21:32] {VinMiller} It definitely is a workaround. It is NOT true inheritance. But, it is a way to reuse code in VB, which is important to point out. We are all so used to inheritance that it becomes easy to forget that there are other approaches, and, the interface inheritance part of this actually is quite important. The reason will become apparent as we move on.

    [21:34] {VinMiller} Last week, I showed how, in a client process, you could define and instance of the Contribution clas, and "see" all of the Transaction methods -- prefixed with a Transaction_.

    [21:35] {VinMiller} I really wanted to show that they were "there" and "present." But, actually, it's not so likely you would use it in that way. The really important ramification of Interface Inheritance is tied up quite closely with strong typing of variables in VB. As you know, in VFP, we simply create an object reference: oX = CREATEOBJECT("MarkusClass"), while in VB, you usually define (DIM) a variable, and then create it: DIM oX as MarkusClass | SET oX = New MarkusClass.

    [21:37] {VinMiller} This may seem redundant -- in fact, it usually *is* redundant. But, since the contribution class has Implemented the Transaction class, in VB, the variable that will hold the Contribution object can be DIM'd as either class!

    [21:36] {MarkusVoellmy} ;)

    [21:38] {Evan Delay} Is either way more correct, or prefered?

    [21:38] {VinMiller} Well, it really depends. If you DIM oX AS Contribution, you will be able to reference and deal with the methods of that class, including all of the Transaction_ methods, but if you first DIM oX AS Transaction, the transaction methods are available to you without that Transaction_prefix. In toerh words, the IDE (and the compiler) recognize this object as a Transaction -- and the Transaction methods are available to you.

    [21:39] {VinMiller} So, Evan, to answer your question -- DIM'ing as the Interface usually makes more sense.

    [21:40] {Evan Delay} Thanks.

    [21:41] {VinMiller} There are several reasons this makes more sense, and is very helpful. To begin with, you can design subs or functions that expect to deal with a Transaction. Then, as long as you pass it an object that was DIM'd as a Transaction, it doesn't matter if it's a Withdrawal or a Contribution. This is sometimes hard to absorb if your head is deep into VFP, because strong-typing and early-binding don't affect us (yet!!) but what you can do, and what I do int he Contribution command button click method, is to say "This is a transaction. Now make it a contribution"

    [21:43] {VinMiller} Does this make sense?

    [21:44] {Evan Delay} Hmm

    [21:45] {BillArmbrecht} Not yet...

    [21:45] {VinMiller} I should point out that we have veered away from the "reuse" piece of all this a bit; the delegation piece (within the Contributions subclass) is definitely a great tool for reuse. What I have been following up with tonight is more of a followup on how classes are really used in VB. I didn't want folks to get confused when they would see these more realistic examples, with the multiple-typing of variables. So, if you are wondering "how does this help in code reuse" don't worry -- it doesn't,... very much that is.

    [21:47] {BillArmbrecht} Why would you dim as a Transactions then create a Contribution? Why not DIM a Contribution?

    [21:47] {VinMiller} A few reasons. First, you might have a series of functions that are intended to work with Tranasaction objects. In VB, if you were to pass a textbox to a function expecting a Transaction object, you would get design time/compile and run-time errors. Likewise, if you send a Contribution into such a function, you would bomb out.

    [21:49] {VinMiller} So let's say there's some external function that you want to have accept a contribution or a withdrawal. What to do?

    [21:49] {VinMiller} Well, you could create two separate methods even though the functionality would be identical.. yuck!

    [21:50] {BillArmbrecht} Light bulb beginning to turn on...

    [21:50] {VinMiller} You could also not specify at all in the parameter list what kind of variable is accepted. But this is slow slow slow. So instead, in our example, you could always DIM your transactions as Transactions, and then create them as whatever kind of transaction you want. So, the speed and development ease of strong-typing of variables is one reason.

    [21:51] {BillArmbrecht} Ok

    [21:52] {VinMiller} A second reason, in my experience, is ease of version control of the app. Here's what I mean. Let's say I have created an ActiveX DLL for use by... oh, let's say a VFP client. In fact, let's say that we don't care what the client is. This ActiveX DLL might have ten different types of transactions within it. They ALL inherit the Transaction interface. A common question, when releaseing a new version of this component, is "what do my Web / VFP / Excel users need to know about this component." Just the interface. Hopefully, you are fully in control of all this and have had all your caffeine, and right off the bat you say "Don't worry, none of the exposed methods changed at all."

    [21:54] {VinMiller} Right!

    [21:55] {VinMiller} It's kind of nice to be able to say "Well, the Contributions class changed, but the Transaction interface did not, so you guys don't have to worry."

    [21:55] {BillArmbrecht} Thanks.

    [21:56] {VinMiller} Again, since VFP doesn't require us to think of the "type" of a variable in quite the same way, this can take some getting used to.

    [21:56] {MarkusVoellmy} To learn that I needed half a year of Delphi programming ... but it's still true. ;)

    [21:57] {VinMiller} Well, you'll see something interesting in a few of the button Click's. The Contributions object for instance, is a Type Of Transaction. It is also a Type Of Contribution.

    [21:57] {VinMiller} Conceptually, this is like saying (even in VFP) "I am a number. I am also a 4-byte integer." This really makes the most sense when you think about these classes existing in an external class, instead of in the same project as my siimple example shows. And as I said, this doesn't add very much to code re-use in and of itself, but it's how you will often see IMPLEMENTS and classes used.

    [22:00] {MarkusVoellmy} Well it's more encapsulation then.

    [22:00] {VinMiller} How do you mean?

    [22:00] {MarkusVoellmy} When you only publish the interface of a "black box" class.

    [22:01] {VinMiller} Right, and again, in the example I provide, we are dealing with one project, and not all the benefits / uses are readily apparent. But, as I said above, it's awfully nice to be able to say "the Contributions class changed but the Transactiosn class did not, so my client-programmers have nothing to worry about." (well, probably not *nothing*... ;-))

    [22:03] {VinMiller} In fact, I should point out that a common naming convention in VB is to preface any interfaces with I -- as in ITranasaction.

    [22:03] {VinMiller} I hope that between last week, and this week, you are starting to get a sense of hoow interface inheritance and delegation are used by VB programmers to reuse their code, and to establish contracts bewtten different class modules.

    [22:04] {BillArmbrecht} When I loaded the project in VB 5, I got a error, Invalid key 'Retain'. Do I need VB 6?

    [22:04] {VinMiller} Hmmm... this was thrown together in VB6. It looks like you do. I wonder what that is about, though?

    [22:04] {BillArmbrecht} Well if YOU don't know... :)

    [22:05] {BillArmbrecht} I was able to follow along anyway.

    [22:05] {VinMiller} Ha! I thought that Implements was available in 5.0 but maybe it wasn't.

    [22:05] {BillArmbrecht} VB 6 is on order at work as of today :)

    [22:05] {VinMiller} Glad you could follow along} I think I will wrap up now. Evan and I have talked about several future topics on VB Code-Reuse for VFP'ers. Again, I know this one was not focused so much on re-use but I hope it was helpful.

    [22:06] {BillArmbrecht} Thanks and bye

    [22:06] {MarkusVoellmy} Thanks Vin. Great presentation.

    Session Close: Wed Dec 20 22:15:01 2000

    Contributors: Vin Miller, Evan Delay, Cindy Winegarden
    Category Wednesday Night Lectures
  • ( Topic last updated: 2000.12.23 05:10:06 PM )