Our first example is the Minimal class; we’ll start with the minimum functionality class and keep adding features to it. The name of the class can be anything. Just make sure that it’s suggestive of the class’s functionality.
A class might reside in the same file as a form, but it’s customary to implement custom classes in a separate module, a Class module. You can also create a Class project, which contains one or more classes. However, a class doesn’t run on its own, and you can’t test it without a form. You can create a Windows application, add the class to it, and then test it by adding the appropriate code to the form. After debugging the class, you can remove the test form and reuse the class with any other project. Because the class is pretty useless outside the context of a Windows application, in this chapter I use Windows applications and add a Class module in the same solution.
Start a new Windows project and name it SimpleClass (or open the sample project by that name). Then create a new class by adding a Class item to your project. Right-click the project’s name in the Solution Explorer window and choose Add Class from the context menu. In the dialog box that pops up, select the Class icon and enter a name for the class. Set the class’s name to Minimal, as shown in Figure 6.1.
Figure 6.1 – Adding a Class item to a project
The code that implements the class resides in the Minimal.vb file, and we’ll use the existing form to test our class. After you have tested and finalized the class’s code, you no longer need the form and you can remove it from the project.
When you open the class by double-clicking its icon in the Project Explorer window, you will see the following lines in the code window:
Public Class Minimal
If you’d rather create a class in the same file as the application’s form, enter the Class keyword followed by the name of the class, after the existing End Class of the form’s code window. The editor will insert the matching End Class for you. Insert a class’s definition in the form’s code window if the class is specific to this form only and no other part of the application will use it. At this point, you already have a class, even if it doesn’t do anything.
Switch back to the Form Designer, add a button to the test form, and insert the following code in its Click event handler:
Dim obj1 As Minimal
Press Enter and type the name of the variable, obj1, followed by a period, on the following line. You will see a list of the methods your class exposes already:
If you don’t see all of these members, switch to the All Members tab of the IntelliSense dropdown box.
These methods are provided by the Common Language Runtime (CLR), and you don’t have to implement them on your own (although you will probably have to provide a new, nongeneric implementation for some of them). They don’t expose any real functionality; they simply reflect the way VB handles all classes. To see the kind of functionality that these methods expose, enter the following lines in the Button’s Click event handler and then run the application:
Dim obj1 As New Minimal
Dim obj2 As New Minimal
The following lines will be printed in the Output window:
The name of the object is the same as its type, which is all the information about your new class that’s available to the CLR. Shortly you’ll see how you can implement your own ToString method and return a more-meaningful string. The hash value of the obj1 variable is an integer value that uniquely identifies the object variable in the context of the current application (it happens to be 18796293, but it is of no consequence).
The next line tells you that two variables of the same type are not equal. But why aren’t they equal? We haven’t differentiated them at all, yet they’re different because they point to two different objects, and the compiler doesn’t know how to compare them. All it can do is figure out whether the variables point to the same object. To understand how objects are compared, add the following statement after the line that declares obj2:
obj2 = obj1
If you run the application again, the last two statements will print True in the Output window. The Equals method compares the two objects and returns a True/False value. Because we haven’t told it how to compare two instances of the class yet, it compares their references just like the ReferenceEquals method. The ReferenceEquals method checks for reference equality; that is, it returns True if both variables point to the same object (the same instance of the class). If you change a property of the obj1 variable, the changes will affect obj2 as well, because both variables point to the same object. We can’t modify the object because it doesn’t expose any members that we can set to differentiate it from another object of the same type. We’ll get to that shortly.
Most classes expose a custom Equals method, which knows how to compare two objects of the same type (two objects based on the same class). The custom Equals method usually compares the properties of the two instances of the class and returns True if a set of basic properties (or all of them) are the same. You’ll learn how to customize the default members of any class later in this chapter.
Notice the name of the class: SimpleClass.Minimal. Within the current project, you can access it as Minimal. Other projects can either import the Minimal class and access it as Minimal, or specify the complete name of the class, which is the name of the project it belongs to followed by the class name.