Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Articles
Recherche: 

Breaking Inheritance
Hilmar Zonneveld, December 6, 2001
(The latest update contains minor edits only.) Five easy and fun ways to get yourself into trouble with inheritance. A frequent source of problems in OOP is called "breaking inheritance". This document briefly describes what inheritance is, how it applies to properties and methods, and how it ...
Summary
(The latest update contains minor edits only.) Five easy and fun ways to get yourself into trouble with inheritance. A frequent source of problems in OOP is called "breaking inheritance". This document briefly describes what inheritance is, how it applies to properties and methods, and how it can be maintained or broken. Problems appear especially when inheritance is broken in methods.
Description
Inheritance with Properties When creating an object or class based on another class, the child object (or class) initially inherits properties and methods from the parent class. Example: Create a form class with a blue background. Use it as an ancestor (parent, grandparent, etc.) of all your forms. Now, all forms will have a blue background. Changing the background to red will change all forms based on it to red. Now, if you change the background in the child (in the properties sheet) to gray, inheritance is broken; changes in the parent will no longer be reflected in the child. If you ever want to restore inheritance, right-click in the properties sheet, and select "restore to default". Inheritance with Methods With methods, the situation is slightly more complicated. Often, you want to add additional commands, but still call the default (inherited) method. However, as soon as you type anything in the child method code, the parent method code is no longer called automatically. Please note that "Restore to default" will erase the entire code in the child method. You solve this by explicitly calling the parent method with command DoDefault(). Often, you would place this at the beginning or at the end of the inherited method. Sometimes, you may want to conditionally call the inherited method. VFP 3 doesn't have DoDefault(); instead, you use an operator with the queer name of "scope resolution operator", which requires specifying both the parent class and the method.
* Examples, for method Init(); parent class is cForm
* Example in VFP 5 or later:
DoDefault()

* Example in VFP 3:
cForm::Init()
From now on, I will assume that you can use DoDefault(). Please note that DoDefault() can both accept parameters (which are passed to the parent method), and return a value (the value returned by the parent method). Easy instructions for getting into trouble And now, finally, the fun part. Basically, I managed to get into trouble, by breaking inheritance, in five different ways. In case you ask, yes, I really did get into trouble, on different ocassions. I know how to break inheritance and how to avoid it, but it is still easy to forget some detail in method code. I believe that most programmers will manage, sooner or later, to use at least the first three ways to get into trouble. 1) The most obvious is to include code in the derived object, and simply forget DoDefault(). Example:
* MyForm.Init()
set talk off
set deleted on
* DoDefault() isn't included, and the parent method won't be called.
Corrected version:
* MyForm.Init()
DoDefault() && This will call the parent method
set talk off
set deleted on
Note: This is a quick sample only. In actual practice, "set deleted on" would be placed in the parent-of-all-forms, and it would be placed in the Load() method. 2) Forget that the parent method may require parameters Example:
* MyForm.Init()
lParameters par1, par2  && This was automatically inserted by the method editor,
     && because the parent method had parameters
DoDefault()  && Parameters???
set talk off
set deleted on
Corrected version:
* MyForm.Init()
lParameters Par1, Par2
DoDefault(Par1, Par2)  && Parameters will be passed to the Init() of the parent
set talk off
set deleted on
3) Forget that the parent method may return a value Example:
* MyForm.Init()
DoDefault()  && Return value???
set talk off
set deleted on
Corrected version:
* MyForm.Init()
local llReturnValue
llReturnValue = DoDefault()
set talk off
set deleted on
return llReturnValue
In the above sample, I am assuming that there are no parameters. 4) Forget that a parameter may be an array Example:
* MyForm.Init()
lParameters taPar1, tcPar2   && taPar1 is an array
DoDefault(taPar1, tcPar2)  && Only the first element will be passed!
set talk off
set deleted on
Corrected version:
* MyForm.Init()
lParameters taPar1, tcPar2
DoDefault(@taPar1, tcPar2)  && Entire array is passed by reference
set talk off
set deleted on
5) Forget that the parent method uses a variable number of parameters In case the inherited method uses a variable number of parameters, and actually checks the number of parameters passed with pcount() or parameters(), it is necessary to forward the appropriate number of parameters to the parent code. Example:
* MyForm.Init()
lParameters txPar1, txPar2
DoDefault(txPar1, txPar2)
set talk off
set deleted on
In the above code, the inherited method will receive two parameters, and erroneously process two parameters. This can cause trouble sometimes. Corrected version:
* MyForm.Init()
lParameters txPar1, txPar2
do case
case pcount() = 0
  DoDefault()
case pcount() = 1
  DoDefault()
otherwise
  DoDefault(txPar1, txPar2)
endcase
With respect to this, Sherlog wrote to me (by e-mail): "... you should always forward parameters per reference because this is the only way to preserve the parameter semantics of the function you are forwarding to. Strictly speaking even that is not enough; the full procedure for semantics-preserving forwarding would be like:
   lparameters a, b, c  && and possibly more (up to 27 total) ...
   
   local nArgs, xResult
   
   nArgs = pcount()
   do case
      case m.nArgs < 1
         xResult = dodefault()
      case m.nArgs == 1
         xResult = dodefault(@m.a)
      case m.nArgs == 2
         xResult = dodefault(@m.a, @m.b)
      * more cases as needed ...
   endcase
Fox itself uses code like that in several places, BTW. However, if you know that the called function/method does not use parameter counting - a good reason not to do it in your own code - then passing all parameters per reference is enough of a precaution."
Hilmar Zonneveld, Independent Consultant
Hilmar Zonneveld works in programming since 1986, using dBASE, FoxPro and Visual FoxPro. He is available as an independent consultant. He currently works as a programmer at Bata Shoe Organization; also as an instructor at Cisco Networking Academy. You can contact him through the Universal Thread, or, via e-mail, at hilmarz@yahoo.com. Personal Web page (mainly in Spanish): www.geocities.com/hilmarz.
More articles from this author
Hilmar Zonneveld, May 1, 2003
An audit-trail is a record of who did what changes, and when. In Visual FoxPro, this can easily be accomplished through triggers. I hinted at the possibility of doing an audit-trail, in my article on triggers - now, as a reaction to questions in the Universal Thread, I want to present a sample...
Hilmar Zonneveld, July 1, 2002
Introduction Buffering is a feature in Visual FoxPro that allows us to give the user "undo" and "save" capabilities. In the old FoxPro 2.x days, programmers either didn't provide this capability, or edited memory variables, and copied information between these variables and the table fiel...
Hilmar Zonneveld, October 6, 2005
Due to a recent Windows security fix, users can no longer access a CHM file on a server. The table of contents appears, but the individual pages are replaced by error messages. Access to CHM files in specific folders can be explicitly allowed through special registry settings.
Hilmar Zonneveld, July 20, 2001
(The last update contains minor edits only.) The idea is to have several controls on a form controlled with an array. Thus, you can quickly go through all the controls on the form, managing the array. The sample code included will help you get started quickly. You can easily adapt it to manage...
Hilmar Zonneveld, September 1, 2002
With Automation, you can control all aspects of Excel, Word, or other programs that provide this feature, from Visual FoxPro. In this article, I will concentrate on Excel. Its purpose is to provide a starting point, especially for people new to automation. Introduction With automation, you bas...
Hilmar Zonneveld, March 1, 2003
Introduction One common task in programming is to keep track of what problems are pending. For this purpose, I use a "hierarchical to-do list": a list of items, each of which can have sub-items. All you need is Microsoft Word. Alternatives are available as freeware or shareware, but in t...
Hilmar Zonneveld, October 7, 2005
This is a step-by-step tutorial to show inheritance, specifically in Visual FoxPro forms, as a guidance for people who are not familiar with inheritance in general, or who don’t know how to implement it in Visual FoxPro. The basic idea of inheritance is that all your forms, or several of your for...
Hilmar Zonneveld, May 30, 2004
The code shows how to quickly obtain the greatest common factor, and the least common multiple. Both functions are used when manipulating fractions, among others. Several methods are possible; the method usually taught in school involves prime numbers, but this code will execute much faster (and it ...
Hilmar Zonneveld, November 1, 2006
A standard requirement in a production system, or in systems for cost calculation, is to add up all the raw materials for a number of finished articles, to get the total cost, or simply to purchase the materials. In this article, Hilmar outlines how to do this with multiple levels of intermediate ar...
Hilmar Zonneveld, August 1, 2002
Overview The purpose of this article is to give an overview of normalization. Basically, normalization refers to having an efficient table structure. I will not discuss the famous "first to fifth normal forms" - if you want that information, enough texts exist about it in other places (search sit...
Hilmar Zonneveld, November 8, 2001
The following function will open any document, with its default association (the same application that will be called when you double-click on the file, in Windows Explorer). Use it to open a text-file, a Word or Excel document, an image, etc., with an external application.
Hilmar Zonneveld, May 1, 2002
Introduction This document explains the meaning of primary key, foreign key and candidate index in Visual FoxPro. A discussion of natural and surrogate keys (keys visible, or not visible, to the end-user) is included, including the advantages of each approach, as well as different methods for o...
Hilmar Zonneveld, January 1, 2003
Continuing my series of introductory articles, this article presents an introduction of a simple yet powerful programming concept: recursion. Introduction "To understand recursion, you must first understand recursion." "To make yogurt, you need milk and yogurt." If you are not accustomed...
Hilmar Zonneveld, December 1, 2002
Introduction This article presents an introduction to coding shortcuts in Visual FoxPro - when to use them, and when not to. Notes on coding in general This article is about coding shortcuts; however, I should first emphasize that making the code as small as possible is usually not the number...
Hilmar Zonneveld, July 20, 2001
Rushmore Optimization can help make queries much faster. However, "Full Rushmore Optimization" is not always a desirable goal. "Partial Optimization" is sometimes much faster. It is often believed that to speed things up, you need to have as many indices as possible. This article explains that so...
Hilmar Zonneveld, June 7, 2002
If you need to check elapsed time with seconds() or a datetime value, this function allows you to display the elapsed time in a human-readable format, that is, hours:minutes:seconds, instead of the total number of seconds. Just pass a number of seconds as a parameter.
Hilmar Zonneveld, April 1, 2002
SQL is a standard language used to manipulate databases. Several of the SQL commands are integrated into the Visual FoxPro language. Select This is a very flexible command, used to select data from a table, or from several tables. This command has options to get totals from several record...
Hilmar Zonneveld, August 1, 2003
In this article, I will show several ways to manipulate text-files. Knowledge of these methods is often important to import and export specific formats. Some of the techniques can also be used to work with files of any content; however, this article will concentrate on text-files. When ...
Hilmar Zonneveld, June 1, 2002
The purpose of this article is to show how to use some aspects provided by the Visual FoxPro database engine, to control our data. Indices Perhaps most readers already know indices; anyway, I find it convenient to include a brief summary of the topic, since this is a requisite to understan...
Hilmar Zonneveld, November 1, 2002
A help file can be used either for interactive help, or as an online manual. In this article, I will give an overview over creating help files in the new help format (CHM), for Visual FoxPro 6 and later. This article is introductory and assumes no prior knowledge of the Help Compiler, or of HTML cod...
Hilmar Zonneveld, February 1, 2003
Introduction Any real-world application will sooner or later misbehave. It is important to be able to find those problems. Visual FoxPro's built-in debugger can help a lot to find out why your program doesn't work as you thought it would. Most of the material in this article applies to Visual...
Hilmar Zonneveld, May 1, 2006
This article is an introduction to VisioModeler. This is a free CASE tool, that can help you design your database, in the process sharing the information with the client in a visual, easy-to-understand, format.