While the My objects and the hundreds of types in the .NET Framework Class Library provide ready-to-use solutions to many of the tasks you need to perform in a Visual Basic application, at some point you'll need to create your own classes. In this section, you'll see how to do that. You'll also see how you can control access to the variables and methods in your classes, and when it might make sense to use a Structure a "light-weight" class instead.
3.3.1. Defining a Class
Before you build a car, you need a design. The design of a car specifies its properties, its behaviors, and how it works internally. Likewise, to design a class of your own, you need to specify the methods and properties, as well as the internal workings of the class.
To see how to define a class, let's create a Stack class of our own. In the following steps, you'll use the Visual Studio 2005 class designer to get the work done.
Example 3-9. The definition for the StackClass class
Public Class StackClass '---stores the items in the stack Private element() As Object '---indicate the current stack pointer Private pointer As Integer '---instantiates and specify the default size of the stack Public Sub New() ReDim element(100) pointer = 0 End Sub '---instantiates and specify the size of the stack Public Sub New(ByVal size As Integer) ReDim element(size - 1) pointer = 0 End Sub '---push an item into the stack Public Sub Push(ByVal item As Object) If pointer > UBound(element) Then Throw New Exception("Stack is full.") End If element(pointer) = item pointer += 1 End Sub '---pop an item from the stack Public Function Pop() As Object pointer -= 1 If pointer < 0 Then Throw New Exception("Stack is empty.") End If Return element(pointer) End Function '---return the number of items in the stack ReadOnly Property count() As Integer Get Return pointer End Get End Property End Class
Observe that StackClass contains the following elements:
3.3.2. Controlling Access to Class Members
Variables, classes, and members can be declared to be public or private using the Public and Private access modifiers. Access modifiers restrict the scope of member variables in a class. For example, a variable defined with the Private keyword is visible only within the class in which it is defined. A Public variable, on the other hand, is visible outside the class. Declaring a private variable is useful in cases where you do not want users who are using your class to know about the detailed workings of your class.
There are two more access modifiers that you can use:
To see how these two access modifiers affect the scope of variables, classes, and member variables, consider the following example.
Suppose you have the following class definition:
Public Class BMW Friend var1 As Integer Protected var2 As Integer Private var3 As Integer Public var4 As Integer End Class
Within the class, you have four variables each declared with a different access modifier. Create an instance of class BMW and try to assign values to the member variables:
Dim objA As New BMW objA.var1 = 1 objA.var2 = 2 ' Error; not allowed objA.var3 = 3 ' Error; not allowed objA.var4 = 4
You will notice that var2 and var3 are not accessible because:
Consider the following example, where class MiniCooper inherits from class BMW:
Public Class MiniCooper Inherits BMW Public Sub doSomething() MyBase.var1 = 1 MyBase.var2 = 2 MyBase.var3 = 3 'Error; not allowed MyBase.var4 = 4 End Sub End Class
Within class MiniCooper, you have a method doSomething that tries to access the four variables in the base class. Notice that var2 is accessible but var3 is not. This is because:
In the two examples above, you may notice that var1 is visible all along. Basically, the Friend and the Public access modifiers are similar with the exception that Friend variables are accessible from within their declaration context and from anywhere else in the same program (but not outside the program).
You can combine the two access modifiers, Protected and Friend, together to give a variable both protected and friend access. For example, here var2 is now declared as Protected Friend:
Public Class BMW Friend var1 As Integer Protected Friend var2 As Integer Private var3 As Integer Public var4 As Integer End Class
This means that var2 is visible within the subclass and also visible within the same program. The following code example shows that now var2 is visible within the same program:
Dim objA As New BMW objA.var1 = 1 objA.var2 = 2 ' Allowed! objA.var3 = 3 ' Error; not allowed objA.var4 = 4
3.3.3. Aggregating Data Types Using a Structure
Sometimes you need to represent a piece of information using multiple data types, but don't necessarily want the overhead of defining a class and managing an object. For example, suppose you need to maintain information about the different types of car owned by a company, such as model and year of registration. In this case, you can either use a class or a structure to aggregate all the required information.
In VB 2005, a structure is implemented using the Structure keyword. In VB 6, you define structure using the Type…End Type syntax, which is no longer supported in VB 2005.
Example 3-10 shows the definition for a Structure named Car.
Example 3-10. Declaring a structure
Structure Car Public Model As String Public Year As UShort End Structure
To use a Structure, you simply declare variables to be of the structure type, as shown in Example 3-11.
Example 3-11. Using structures
Dim Car1, Car2 As Car Car1.Model = "Nissan Maxima" Car1.Year = 2004 Car2 = Car1 Car2.Model = "Toyota Camry"
Example 3-11 creates two variables of type Car. The first variable is initialized and then copied to the second variable. Because structure is a value type, changes to the second variable do not affect the first member (see Figure 3-13).
Figure 3-13. Memory storage for a structure
So, what is the difference between a class and a structure? A class is a reference type, which means that the actual storage of an object is on the heap with the object variable on the stack pointing to it. A structure, on the other hand, is a value type, and its value is stored directly on the stack.
You should use a structure when:
A class is preferred when: