Since VBScript 5.0, developers have been able to create classes to use in their scriptsa definite step along the road of object-oriented programming in VBScript. Writing classes with VBScript is very similar to writing COM objects with VB. Before we look at writing an actual class, let's go over some of the terminology so we are clear on what we are doing and what we are referring to.
A class is simply the template for an object. When you instantiate an object (that is, create an instance of a class) in code, VBScript makes a copy of the class for your use. All objects come from a class. Writing the class is simply a matter of creating a design for the objects that you want to use.
So naturally, it follows that an object is simply a copy of the class that you are making available to your program. You can make as many copies as you like for your use. The copies are temporary structures for holding information or creating interactions. When you are done with the objects, you can release them. If you need another one, you can instantiate another copy.
In VBScript, classes must be created in the scripts where you want to use them or they must be included in the scripts that use them. Since VBScript isn't compiled, unless you use Windows Script Components, you don't have the advantage of being able to write a set of VBScript COM classes that are reusable outside of the scripts in which they're defined or that can be easily accessed by programs and scripts written in other languages.
2.2.1 The Class Construct
You declare a class using the Class...End Class construct. The syntax of the Class statement is:
where classname is the name you want to assign to the class. It must follow standard VBScript variable naming conventions.
Classes can contain variables, properties, methods, and events. How many of these and of what types is completely up to you. It is possible to have an object that has no properties or methods and supports only the two default events, but it won't be a very useful class.
To instantiate an objectthat is, to create an instance of your class that you can use in your codeuse the following syntax:
Set oObj = New classname
where oObj is the name you want to assign to your object variable (it again must follow standard VBScript variable naming conventions), and classname is the name of the class. The statement creates an object referencethat is, the variable oObj contains the address of your object in memory, rather than the object itself.
2.2.2 Class Variables
In addition to properties, methods (which are either functions or subroutines), and events (which are subroutines), the code inside a Class structure can include variable definitions (but not variable assignments). The variable definition can take any of the following forms:
Dim varName1 [, varName2...] Private varName1 [, varName2...] Public varName1 [, varName2...]
The variable name must once again follow standard VBScript variable naming conventions.
The Dim, Private, and Public keywords indicate whether the variable is accessible outside of the class. By default, variables are publicthat is, they are visible outside of the Class...End Class structure. This means that the Dim and Public keywords both declare public variables, while the Private keyword declares a variable that's not visible outside of the class.
In general, it is poor programming practice to make a class variable visible outside of the class. There are numerous reasons for this, the most important of which is that you have no control over the value assigned to the variable (which is especially a problem when dealing with a weakly typed language like VBScript) and no ability to detect when the value of the variable has been changed. As a rule, then, all variables declared within your classes should be private.
2.2.3 Class Properties
Typically, class properties are used to "wrap" the private variables of a class. That is, to change the value of a private variable, the user of your class changes the value of a property; the property assignment procedure (called a Property Let procedure) handles the process of data validation and assigning the new value to the private variable. If the private variable is an object, use an object property assignment procedure (called a Property Set procedure) to assign the new property value to the private object variable. Similarly, to retrieve the value of a private variable, the user of your class retrieves the value of a property; theproperty retrieval procedure (called a Property Get procedure) handles the process of returning the value of the private variable.
Read-only properties (which wrap read-only private variables) have only a Property Get procedure, while write-only properties (which are rare) have only a Property Let or a Property Set procedure. Otherwise, properties have a Property Get procedure and either a Property Let or a Property Set procedure and are read-write.
The use of public properties that are available outside of the class to wrap private variables is illustrated in Example 2-5, which shows a simple class that defines a private variable, modStrType, and two read-write properties, ComputerType and OperatingSystem, the latter of which is an object property. Normally, you would validate the incoming data in the Property Let and Property Set procedures before assigning it to private variables, although that hasn't been done here to keep the example as simple as possible.
Example 2-5. Using properties to wrap private variables
Class Computer Private modStrType Private oOS Public Property Let ComputerType(strType) modStrType = strType End Property Public Property Get ComputerType( ) ComputerType = modStrType End Property Public Property Set OperatingSystem(oObj) Set oOS = oObj End Property Public Property Get OperatingSystem( ) Set OperatingSystem = oOS End Property End Class
2.2.4 Class Methods
Methods allow the class to do something. There is no magic to methodsthey are simply subroutines or functions that do whatever it is you wish for the object to do. For example, if we created an object to represent a laptop computer in a company's inventory, then we would like to have a method that reports the laptop's owner. Example 2-6 shows a class with such a method.
Example 2-6. Creating a class method
Class LaptopComputer Private modOwner Public Property Let CompOwner(strOwner) modOwner = strOwner End Property Public Property Get CompOwner( ) CompOwner = modOwner End Property Public Function GetOwner( ) GetOwner = modOwner End Function End Class
As with properties, you can use the Public and Private keywords to make methods available inside or outside of the class. In the previous example, the method and both properties are available outside of the class because they are declared as Public.
Note that in Example 2-6, the Property Get procedure performs the same functionality as the GetOwner method. This is quite common: you often can choose whether you want to implement a feature as a property or as a method. In this case, you could define both property procedures to be private; then the only way for anyone to get the owner information from the object would be to invoke the GetOwner method.
The GetOwner method is declared as a function because it returns a value to the calling code. You can write methods as subroutines as well. You would do this when the method that you are calling does not need to pass back a return value to the caller.
2.2.5 Class Events
Two events are automatically associated with every class you create:Class_Initialize andClass_Terminate. Class_Initialize is fired whenever you instantiate an object based on this class. Executing the statement:
Set objectname = New classname
causes the event to fire. You can use this event to set class variables, to create database connections, or to check to see if conditions necessary for the creation of the object exist. You can make this event handler either public or private, but usually event handlers are privatethis keeps the interface from being fired from outside code. The general format of the Class_Initialize event is:
Private Sub Class_Initialize( ) Initalization code goes here End Sub
The Class_Terminate event handler is called when the script engine determines that there are no remaining references on an object. That might happen when an object variable goes out of scope or when an object variable is set equal to Nothing, but it also might not happen at either of these times if other variables continue to refer to the object. You can use this handler to clean up any other objects that might be opened or to shut down resources that are no longer necessary. Consider it a housekeeping event. This is a good place to make sure that you have returned all memory and cleaned up any objects no longer needed. The format of the Class_Terminate event is:
Private Sub Class_Terminate( ) Termination code goes here End Sub
Once again, the event handler can either be public or private, though ordinarily it's defined as private to prevent termination code from being executed from outside of the class.