Home > Articles > Programming > Visual Basic

This chapter is from the book

This chapter is from the book

Creating a Class

A class describes the things in your application, such as customers or products. Each piece of data associated with the class is defined as a property of the class. Each set of functionality associated with the class is defined as a method of the class.

For example, the Purchase Tracker sample application works with products. The products are described by a Product class. Each attribute of the products, such as name, number, description, price, and so on, is represented in the class as a property. Each process that must be performed for the products, such as retrieving, saving, and so on, is defined in the class as a method.

A single item, such as an individual product (a ring or sword, for example), is represented by an object created from the class. Because an object is an instance of a class, the act of creating an object from the class is called instantiation.

A common metaphor is to think of the class as the blueprint, and the object as the building constructed from the blueprint. Any number of buildings can be created from the same blueprint. Another metaphor is a cookie cutter. The class is the cookie cutter, and the objects are all the cookies created from the cookie cutter.

If you are building a nontrivial application, build it as a set of layers, as described in Chapter 2, "Designing Software." Implement each layer as a separate project in a solution, as described in Chapter 3, "Building Projects." This gives you separately compiled components, one for each layer.

You build each layer as a set of classes. The user interface layer is comprised of a set of form classes (as shown in Chapter 4, "Building the User Interface Layer") following the user interface design. The business logic layer (as described in this chapter) includes the set of classes you build following the implementation design. The data layer (detailed in Chapter 8, "Building the Data Access Layer") contains classes that provide the interaction between the database and the business logic layer.

When you construct the business logic layer, it is important to define the pertinent set of classes. For each class, you define the appropriate properties and methods. This ensures that the correct set of information and logic is encapsulated in each class, making it easier to work with and maintain the class.

You normally define one class for each key thing involved with the application. For example, the Purchase Tracker sample application has products, customers, and purchases. The products map to a Product class, with properties to manage product information and methods to retrieve, save, and perform any other required processing on product information. The customers map to a Customer class, and so on. For more information on defining classes for your application, see Chapter 2.

You can also define classes for other implementation logic. For example, you could create a class to manage application logging or security. These implementation-based classes were also discussed in Chapter 2.

This section details the process of creating a class. You can use these techniques to create each class needed by your application.

Adding a Class to a Project

There are many ways to add a class to a project. As discussed in the preceding chapter, adding a form project item actually adds two class files to the project. It adds a class in one file with a .vb extension and a partial class in another file with a .designer.vb extension.

When building the business logic layer, you normally add one class project item for each business object class (such as Product and Customer) and one for each implementation class (such as Logging and Security).

To add a class to a project:

  1. Right-click the project in Solution Explorer and select Add | New Item from the context menu, or select Project | Add New Item from the main menu bar.

    Alternatively, you could select Add | Class from the context menu, or select Project | Add Class from the main menu bar.

  2. Select the Class template, name the class, and click the Add button.

    If you created your own class template using the steps in Chapter 3, you can use your template here.

    Use standard naming conventions for your class name. The most common standard is to name the class using the singular name of the business entity or implementation feature represented by the class. For products the class name would be Product, for logging the class name would be Logging, and so on.

    Visual Studio creates the class file with a .vb extension, adds it to Solution Explorer, and then displays the class in the Code Editor.

When Visual Studio creates the class file, it automatically generates the class declaration as follows:

Public Class Product

End Class

You can add any number of classes to your projects as needed by your application. Regardless of the class's purpose or location, the basic process of building a class is the same.

Documenting the Class

It is always a good idea to add documentation for a class immediately after adding the class. By adding the documentation right away, you focus on the class's purpose, which helps you keep the class encapsulated. It is also much easier to document each class as you go along instead of facing the large task of going back later and documenting all the classes.

To document the class:

  1. Open the class in the Code Editor.
  2. Move the insertion point immediately before the word Public in the Public Class statement.
  3. Type three comment markers, defined in Visual Basic as apostrophes ('''), and press the Enter key.

    The XML comments feature automatically creates the structure of your class documentation as follows:

    ''' <summary>
    '''
    ''' </summary>
    ''' <remarks></remarks>
    Public Class Product
    
    End Class
    
  4. Type a summary of the class's purpose between the summary tags and any remarks between the remark tags.

    Your documentation may be similar to this:

    ''' <summary>
    ''' Provides product management features such as
    ''' retrieving product data and saving product changes
    ''' </summary>
    ''' <remarks>Use this class to work with products
    ''' </remarks>
    

Use the summary tags to describe the class and the remarks tags to add supplemental information. The summary is the most important tag because it is the one used by Visual Studio.

When you provide a summary of the class using XML comments, your class displays documentation about itself in appropriate places within Visual Studio, such as in the List Members box, shown in Figure 5.1. Open the List Members box by typing a part of the class name in the Code Editor and pressing Ctrl+Spacebar or by selecting Edit | Intellisense | List Members from the main menu bar or by clicking the Display an Object Member List icon on the Text Editor toolbar.

Figure 5.1

Figure 5.1 The documentation provided in the List Members box is the summary defined in the XML documentation for the class.

Using XML comments to document your classes makes it easier for you and other developers to work with your classes.

Organizing the Code Structure

Code that is organized is much easier to maintain, because you can quickly find the code that needs to be changed. When you standardize this organizational structure, any member of the team can quickly locate and modify any class code, because the code structure of each class is the same.

A class is normally composed of a set of properties and public and private methods. Public methods are methods that can be called from outside of the class, and private methods are those used only within the class.

You define the organizational structure of a class using regions, as described in Chapter 3. If you built a class template using the information in Chapter 3 and then used that template when creating your class, these regions are already defined in your code. If not, you can create the regions as follows:

Public Class Product

#Region " Properties"

#End Region

#Region " Public Methods"

#End Region

#Region " Private Methods"

#End Region

End Class

Add any other regions as needed to define the standard code structure for your classes. For example, if your class has a constructor, you can add a Constructor region as defined later in this section.

As you develop the code for the application, properties are added to the Properties region, public methods are added to the Public Methods region, and so on. To further aid in the organization, you can insert the properties and methods within each region in alphabetical order.

You can also put regions within regions. So, you can put each method in its own region within the Private Methods or Public Methods region. This makes it easier to focus on the code, because you can close all methods except for the one you are working with.

Instantiating an Object

Once a class is defined, you can create objects from the class. This is called object instantiation. You then use the object to access the properties and methods defined in the class.

To create an object from a class:

  1. Declare an object variable.

    For example:

    Dim prod as Product
    
  2. Create a new instance of the class, and assign the object variable to reference that new instance.

    For example:

    prod = New Product
    
  3. Access the properties and methods for the object by using the object variable and a period (.).

    For example:

    prod.ProductName
    

Alternatively, you can accomplish the first two steps in one code line as follows:

Dim prod as New Product

This line declares the object variable and assigns it to reference a new object from the Product class.

Defining the Constructor

A constructor is a built-in method in a class that the .NET runtime executes when an object is first instantiated (created). You add code in the constructor to perform any initialization operations for a new object.

You define a constructor by creating a New method in the class as follows:

#Region " Constructors"
    Public Sub New()

    End Sub
#End Region

The constructor executes when you create an object from the class. For example:

Dim prod as New Product

When the .NET runtime executes this line of code, it calls the New method in the Product class and runs any code in your constructor.

You can pass data into the constructor by defining parameters. The constructor is then called a parameterized constructor. For example, this constructor defines a productID as a parameter:

#Region " Constructors"
    Public Sub New(ByVal productID as Integer)

    End Sub
#End Region

You pass the parameter to the constructor when creating the instance of the object:

Dim prod as New Product(1)

or

Dim prod as Product
prod = New Product(1)

Multiple constructors can be defined for a class. For example, you could define a constructor with no parameters and one with a parameter. The .NET runtime knows which constructor to call based on the parameters passed to the constructor. Defining one method (in this case, New) with two different signatures is called overloading and is described in detail later in this chapter.

In many cases, you don't need any specialized code to be executed when the object is instantiated, so you don't need to create a constructor. If you don't create one, the runtime executes an empty constructor for you.

In other cases, you may want a more formal object creation pattern. The most common formal pattern for object creation is called the Factory pattern. A pattern is a reusable solution for a recurring problem. The Factory pattern defines a standard solution for creating objects. Instead of creating an instance of a class using the New keyword, the Factory pattern defines a method that creates and returns an instance of the class. This makes the process of creating object instances more explicit. See the "Additional Reading" section at the end of Chapter 1, "Introduction to OO in .NET," for more information on patterns.

If you elect to apply the Factory method, you no longer use this style of code to create an object:

Dim prod as Product
prod = New Product

You instead use code like this:

Dim prod as Product
prod = Product.Create()

The Create method, and the syntax used to call it, are defined in detail later in this chapter.

Use constructors or a Factory pattern method to define any code that must be executed when first creating an object from the class. Don't bother creating a constructor if you have no initialization code.

Defining the Destructor

A destructor is a built-in method in a class that the .NET runtime executes when an object is destroyed. You define a destructor by creating a Finalize method in the class. But using a destructor is not recommended, because it does not necessarily execute when you expect it to, and it may not execute at all.

It may seem that the destructor should execute when you specify that you no longer need the object. For example, the following code defines that you no longer need the specified object reference:

prod = Nothing

But this code does not destroy the object. It just releases the object, making it available for destruction.

Your code does not define when an object is destroyed—the .NET garbage collector does. The garbage collector is a memory manager that manages the allocation and release of memory for all .NET applications. The garbage collector performs garbage collection when it needs to. It then releases the memory allocated to a managed object and destroys the object if that object is no longer used. But because you cannot predict when the garbage collector will perform garbage collection, you don't know exactly when your object will be destroyed. Therefore, you cannot know when your destructor will be executed. (See the "Additional Reading" section for more information on the garbage collector.)

In most cases, you don't need to write any cleanup code that executes when an object is destroyed, so you don't need to care about this. You can just allow the garbage collector to destroy your object when it gets around to it.

But if your object works with unmanaged resources, you do need to write some cleanup code. Unmanaged resources are system resources that are not directly managed by the .NET runtime, such as database connections, window handles, open files, network connections, and graphic resources. You need to explicitly release unmanaged resources when your object is released.

Because the execution of the Finalize method is unpredictable, do not put the code to release unmanaged resources in the destructor. Create a Dispose method instead, and explicitly call Dispose when you release the object. Add code in the Dispose method to perform any cleanup activities required for your object—primarily, releasing any unmanaged resources used by your object. And since you are explicitly calling Dispose, you control when the unmanaged resources are released.

Define a Dispose method by implementing the .NET Framework IDisposable interface. Using the IDisposable interface to define your Dispose method ensures that you have a standardized programmatic interface for disposing of your objects.

To implement a Dispose method, do the following:

  1. Open the class in the Code Editor.
  2. Add the Implements statement to the class definition to implement the IDisposable interface:
    Public Class Product
        Implements IDisposable
    
  3. Press the Enter key after the name of the interface.

    The Code Editor automatically adds the signatures for all the properties and methods defined in the interface and related code to the class. This generated code uses the recommended design pattern for proper cleanup of any unmanaged resources that your application uses.

Visual Studio adds two sets of generated code as part of the IDisposable interface implementation, defining two Dispose methods. The first part of the generated code provides a Dispose method that you can customize to your requirements:

Private disposedValue As Boolean = False 'To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposedValue Then
        If disposing Then
            ' TODO: free unmanaged resources when explicitly called
        End If
            ' TODO: free shared unmanaged resources
    End If
    Me.disposedValue = True
End Sub

The disposedValue variable keeps track of whether the object has already been disposed so that it won't dispose it again.

The parameter passed to this customizable Dispose method defines whether Dispose is called from the IDisposable interface Dispose method (shown next). If so, the code should free any unmanaged resources, so put your cleanup code here, by the first TODO Task List comment. If you have shared resources (those defined without a specific instance), put that cleanup code by the second TODO Task List comment.

When all the unmanaged resources are freed, this code sets the disposedValue property so that it won't dispose again.

The second part of the generated code defines the implemented interface:

#Region " IDisposable Support"
    'This code added by Visual Basic to correctly implement the
    'disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        'Do not change this code. Put cleanup code in
        'Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

This code is meant to be left unchanged. This interface Dispose method first calls the customizable Dispose method to perform the cleanup. It then calls the SuppressFinalize method on the garbage collector. SuppressFinalize tells the garbage collector that it does not need to perform further cleanup on the object because the object was already cleaned up by the customized Dispose method.

Unlike the Finalize destructor, the Dispose method is not called automatically. The code that created the object must manually call Dispose explicitly when destroying the object as follows:

prod.Dispose()
prod = Nothing

If your code creates an object using the Using statement, as defined in the preceding chapter, the .NET runtime automatically calls the Dispose method at the end of the Using block, so you don't need to explicitly call Dispose. The Using statement also ensures that Dispose is called even if an error occurs within the Using block.

In this example, the Using statement is as follows:

Using prod As Product = New Product
    'Code to work with the object here
End Using

Or, if you are using a Create Factory pattern method:

Using prod As Product = Product.Create()
    'Code to work with the object here
End Using

If your class does not have or use any unmanaged resources, it can leave it up to the garbage collector to clean things up, and no Dispose method is needed. If your class does use unmanaged resources, implement a Dispose method using the IDisposable interface, as described in this section. Any code that creates an object from your class must then correctly destroy it when it is finished with it by calling the object's Dispose method or by using the Using statement.

Using Partial Classes

By convention, each business object class resides in a single class file. The Product class is in the Product.vb file, the Customer class is in the Customer.vb file, and so on. But that is not a requirement. A class can be divided between any number of class files.

You can break a class into two or more files by defining partial classes. Partial classes are used primarily in situations where you have a code generator that generates part of the class and custom code for the remainder of the class. By placing the generated code in a file separate from the custom code, you can more easily regenerate the generated code without affecting the custom code. Every time you add a form to a project, Visual Studio creates a partial class and generates the code defining the controls on your user interface in that class, as described in Chapter 4.

To define a partial class for your class:

  1. Right-click the project in Solution Explorer and select Add | New Item from the context menu, or select Project | Add New Item from the main menu bar.

    Alternatively, you could select Add | Class from the context menu, or select Project | Add Class from the main menu bar.

  2. Select the Class template, name the class, and click the Add button.

    You cannot have two code files with the same filename, so name the partial class with a unique name.

    Visual Studio creates the class file with a .vb extension, adds it to Solution Explorer, and then displays the class in the Code Editor.

  3. In the Code Editor, add the Partial keyword to the class definition, and modify the class name to match the original class name.

For example, the class definition of a partial class for the Product class is as follows:

Partial Public Class Product

End Class

When the application is built, the code in the file for the class and the files for any partial classes are combined into one logical class. So the runtime behaves as if there is only one class.

One other benefit of partial classes is the ability to separately define Option Strict. Your primary class can have Option Strict set to On, and your partial class can have Option Strict set to Off. This is useful if you have code that needs to work with objects without concern for conversion of their types, such as when calling components written in VB6 or other Component Object Model (COM)-based technologies.

Don't use partial classes unnecessarily. Dividing a class into multiple class files for no particular purpose makes it more difficult to maintain the class. It is more difficult to find where code resides and see how it interacts with other code in the class.

Use partial classes for the defined purpose—separating generated code from custom code. If you are not writing your own code generators, you may never need to create a partial class. If you use third-party code generators, you may notice the partial classes that they create.

Adding Multiple Classes to a Class File

A single class file can contain any number of classes. Although you normally define a class within its own class file, you can add support classes for that class directly in the same class file.

For example, say you define a ProductOutOfStockException class that is used only by the Product class. You can define this exception class in the same code file as the Product class:

End Class ' End of the Product Class

<Serializable()> _
Public Class ProductOutOfStockException
    Inherits ApplicationException

    Public Sub New(ByVal message As String)
        MyBase.New(message)
    End Sub

    Public Sub New(ByVal message As String, _
       ByVal inner As Exception)
        MyBase.New(message, inner)
    End Sub

    Public Sub New( _
       ByVal info As _
       System.Runtime.Serialization.SerializationInfo, _
       ByVal context As _
       System.Runtime.Serialization.StreamingContext)
        MyBase.New(info, context)
    End Sub
End Class

This class inherits from ApplicationException to ensure that it behaves as an exception. It contains three methods, each of which calls the associated base class method. Using the same named methods with different parameters is described later, in the section "Overloading Methods." You can create your own exceptions any time using this style of exception class.

Don't put multiple business object classes in a single class file. Reserve this feature for adding support classes or exception classes only. For example, business object-unique exceptions are an excellent type of class to add to a business object class file.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020