A Visual Basic .NET class isn't a VB6 class. VB6 classes are declared and defined using the interface keyword in Visual Basic .NET. Classes in Visual Basic .NET are user -defined aggregate types that support inheritance and are distinct from COM interfaces, which is exactly what a VB6 class module is.
All classes in Visual Basic .NET are defined in a .VB file (as opposed to a .CLS file), and a .VB file may contain one or more classes. (Source files can mix and match classes, structures, and modules in the same file.) The basic syntax of a class is as follows :
Class classname End Class
If you accidentally mistype the declaration of a class, the Visual Studio .NET IDE will use a squiggly underline to indicate the location of the error (see Figure 7.1).
Figure 7.1. The Visual Studio .NET IDE uses a squiggly line to underscore problem areas in your code.
Generally , classes are preceded by the Public access specifier , but can use other access specifiers. Refer to the section "Using Class Access Specifiers" for more on using access specifiers with classes.
The Class and End Class statements form the unit of encapsulation for the class idiom. All the members of the class are placed between these statements.
You can add any number of fields, properties, methods , and events to define an abstraction that suits the needs of a particular solution domain. Although you can add any number of members to a class, in most cases the following generic guidelines will help make your decisions easier.
Fields, properties, events, and methods can all be referred to as members. The term member simply refers to something being defined as part of a class.
As with all rules, there are exceptions. There is the " Good Enough " principle introduced by Grady Booch, which suggests that a reasonable and sufficient number and variety of members is good enough. There are advanced idioms introduced by James Coplien in Advanced C++ that violate the general rules. A further example is represented by classes with all Shared members, like the Math class in the Common Language Runtime.
As I mentioned, the basic guidelines for defining classes are a reasonable starting point, but there are other rules and other motivations for creating classes. For example, the refactoring "Introduce Parameter Object" that yields efficiency in parameter passing can require the creation of extra classes.
Using Class Access Specifiers
There are five access specifiers in Visual Basic .NET, defined in the subsections that follow.
Public Access Specifier
The Public class specifier applied at the class level is the most common specifier. Public classes are classes that are intended to be used by any consumer. The Public access specifier follows any attributes and is placed immediately before the Class keyword. (Refer to Chapter 12 for more information on attributes.)
Public Class MyClass End Class
Protected Access Specifier
The Protected access specifier can only be applied to nested classes. Protected nested classes are only accessible within the class and within child classes. You cannot define instance members of nested classes with higher visibility than the class definition.
A Protected nested class definition takes the following form:
Public Class HasProtected Protected Class ProtectedClass End Class End Class
The class HasProtected has a nested class ProtectedClass. HasProtected can implement instances of ProtectedClass, and classes that inherit from HasProtected can declare and create instances of the nested class ProtectedClass.
Friend Access Specifier
Friend classes are accessible only within the program in which they are defined. If you add the Friend access specifier to a class definition, instances of that class can only be created from within the same program.
Assume we have a class library with a Friend class named FriendClass. We could create instances of FriendClass in the class library but not from within any consumer of the class library. We might say that FriendClass is for internal consumption only. Here's an example:
Friend Class FriendClass Public Shared Sub PublicMethod() MsgBox("FriendClass.PublicMethod()") End Sub End Class
Use the Friend specifier to make a class part of the implementation details of a class library or some other application, precluding consumers of the application from using the Friend class.
Protected Friend Access Specifier
Protected Friend classes represent a union of the Protected and Friend specifiers. Protected classes must be nested classes; thus Protected Friend classes must be nested classes too. The following example shows a nested Protected Friend class:
Public Class HasProtectedFriend Protected Friend Class ProtectedFriend Public Shared Sub Test() MsgBox("Test") End Sub End Class End Class
Protected Friend classes are nested classes. They generally are used as implementation classes of the class that contains them. Methods defined in nested classes can be called indirectly through proxy methods of the containing class. You can't return an instance of a Protected Friend class. Given the preceding example, the following code would be illegal:
Public Class HasProtectedFriend Protected Friend Class ProtectedFriend Public Shared Sub Test() MsgBox("Test") End Sub End Class Public Shared Function Factory() As ProtectedFriend End Function End Class
The ProtectedFriend that appears in bold here would be underlined with a squiggly line, and the task list would contain a notice that 'Factory' illegally exposes a Protected Friend type outside of the Public Class 'HasProtectedFriend'.
Private Access Specifier
The Private access specifier can only be applied to a nested class. A Private nested class represents implementation details of a class. When you have an internal problem that requires more problem-solving horsepower than simple methods can provide, define a nested private class that implements the abstraction. Here's how the syntax looks:
Public Class HasPrivate Private Class PrivateClass End Class End Class
Instances of PrivateClass can only be created in instances of HasPrivate. A motivation for using a private class exists when you have a grouping of methods and properties, and you might need to store multiple instances of state for each of these objects. The distinction is that you don't want to expose the nested private class to external consumers.
You will seldom employ nested protected and private classes. However, the idiom exists and if you can contrive a useful purpose for it, go ahead.