When you create the member variables of a class or of a
structure, such as the above Radius of the Circle class, it is a good idea not to directly expose them to other parts of the
program so that those other parts would not be able to easily change the
values of the members and retrieve their values anyhow. This technique makes sure
that a member variable is not accessed outside the class (or structure) so that the
clients of the class (or structure) cannot directly influence the value of the member
variable. To avoid this type of access, you can make the member variable(s)
private. This would transform the above Circle class to the following:

Public Class Circle
Private rad As Double
End Class

If you create a member variable as private but still want other
classes (or structures) or procedures to access or get the value of such a member variable,
you should then provide a means for members of the class to access that
private member.

Accessories for Properties

A
property is a member of a class that acts as an intermediary to a member
variable of the class. For example, if you have a member variable of a class
and that member represents the salary of an employee, a property can be
the "door" that other procedures or classes that need the salary
must present their requests to. As such, these external procedures and
classes cannot just change the salary or retrieve it as they wish. A
property can be used to validate their request, to reject or to accept
them.

As mentioned already, a property is used to
"filter" access to a member variable of a class. Therefore, you
start by declaring a (private (if you don't make it private, you may be
deceiving the purpose of creating a property)) member variable as we did
for the rad member variable of the above Circle class.

Obviously, as we learned in Lesson
21, this private member variable cannot be
accessed by a procedure or class outside of its class. Therefore, to let
outside classes access this variable, you would/can create a property. To create a property,
you use the Property keyword. With regards to their role, there are two types of
properties.

Practical
Learning: Introducing Properties

Start your programming environment

Create a Console Application named
DeptStore3

To create a new class, on the main menu, click Project -> Add
Class...

A property is referred to as read-only if its role
is only to make available the value of the member variable it represents.
To create a read-only property, use a formula as follows (this formula
takes into consideration only the keywords we have learned so far; there
are other options that we choose to ignore at this time):

The optional Public, Private, or Protected keywords
allow you to specify the level of access of the property. As introduced in
the Lesson 11, the Public keyword would indicate that the
property can be accessed outside of its class. The Private
keyword would show that the property is available only to members of its
class. The Protected keyword would indicate that the property can be
accessed by either the members of its class or only the members of classes
derived from it.

The optional Shared keyword would allow you to
use the property without declaring an instance of its class.

The ReadOnly keyword is used to indicate that the
property's value can be accessed but it cannot be changed. If you
are creating a read-only property, you must include the ReadOnly
keyword.

The Property keyword is required. It is
followed by the name of the property. The name essentially follows the
rules of Visual Basic object names. The Get keyword, the End Get
and the End Property lines are also required.

Here is an example:

Public Class Circle
' This is a new property
Public ReadOnly Property Radius()
Get
End Get
End Property
End Class

Notice that we omitted the As keyword and the data
type of the property. If you don't specify the data type, the property is
treated as Object. Otherwise, you can specify the necessary data type of
the property. Here is an example:

Public Class Circle
' This is a new property
Public ReadOnly Property Radius() As Double
Get
End Get
End Property
End Class

Between the Get and the End Get lines, you can implement the
behavior that would be used to make the member variable's value available
outside. The simplest way consists of just returning the corresponding
member variable. To do this, type the Return keyword, followed by the
hidden member variable whose value would be accessed through this property. Here is an example:

Public Class Circle
Private rad As Double
' This is a new property
Public ReadOnly Property Radius() As Double
Get
Return rad
End Get
End Property
End Class

When the clients of a class access a read-only
property, they can only retrieve the value of
the property but they cannot change it. Therefore, if you create a
read-only property, you should provide the users with the ability to primarily
specify the value of the member variable. To do this, you can create an
appropriate method whose role would only be used to initialize the
property. Most of the time, you would use a constructor to do this. Here
is an example of such a constructor used to initialize a read-only
property:

Public Class Circle
Private rad As Double
Public Sub New(ByVal r As Double)
rad = r
End Sub
' This is a new property
Public ReadOnly Property Radius()
Get
Return rad
End Get
End Property
End Class

Once a read-only property has been created, other classes
or procedures can access it, for example they read its value as follows:

We described a property as serving as a door from
outside to its corresponding member variable, preventing those outside
classes, structures, or procedures to mess with the member variable. Notice that the Square class was
given a negative value for the member variable, which is usually
unrealistic for the side of a square. In this case and others, while still
protecting the member variable as private, you can use the read property
to reset the value of the member variable or even to reject it. To provide
this functionality, you can create a conditional statement in the
property to perform a checking process. Here is an example:

File: Circle.vb

Public Class Circle
Private rad As Double
Public Sub New()
rad = 0
End Sub
Public Sub New(ByVal r As Double)
rad = r
End Sub
Public ReadOnly Property Radius()
Get
If rad < 0 Then Return 0
' else is implied
Return rad
End Get
End Property
End Class

To create read-only properties, change the contents of the
DepartmentStore file as
follows:

Public Class DepartmentStore
Private pItemNo As String
Private pCat As String
Private pName As String
Private pSize As String
Private pPrice As Double
Public Sub New(ByVal nbr As String, ByVal ctg As String, _
ByVal nme As String, ByVal siz As String, _
ByVal prc As Double)
pItemNo = nbr
pCat = ctg
pName = nme
pSize = siz
pPrice = prc
End Sub
' A property for store number of a merchandise
Public ReadOnly Property ItemNumber() As String
Get
If pItemNo = "" Then
Return "Invalid Item"
Else
Return pItemNo
End If
End Get
End Property
' A property for type of a merchandise
Public ReadOnly Property Category() As String
Get
If pCat= "" Then
Return "Unknown Category"
Else
Return pCat
End If
End Get
End Property
' A property for the name of a merchandise
Public ReadOnly Property ItemName() As String
Get
If pName = "" Then
Return "Item no Description"
Else
Return pName
End If
End Get
End Property
' A property for size of a merchandise
Public ReadOnly Property Size() As String
Get
If pSize = "" Then
Return "Unknown Size or Fits All"
Else
Return pSize
End If
End Get
End Property
' A property for the marked price of an item
Public ReadOnly Property UnitPrice() As Double
Get
If pPrice.Equals(0) Then
Return 0.0
Else
Return pPrice
End If
End Get
End Property
End Class

In the Solution Explorer, right-click Module1.vb and click Rename

Type it DeptStore.vb and press Enter.
If asked whether you want to change the file, click Yes

In the Solution Explorer, double-click
DeptStore.vb
and change its file as follows:

In our Square class so far, we were using a
constructor to initialize the value of the member variable. This meant that we had to always make
sure that we knew the value of the member variable when we declared an
instance of the class. We implemented the Radius property as read-only
and the clients of the Square class could only read the value of the
member variable. In some cases, you may not want those external procedures
or classes to read the value but only to be able to change it. To provide
this functionality, you can create a property that is referred to as
write-only.

A property is called write-only if the clients of the
class can change the value of that property but cannot read. The formula
to create a write-only property is (once again, this formula mentions only the keywords we have
reviewed so far):

The WriteOnly keyword is used to indicate that the
property's value can be changed by the clients of the class but they cannot
change it. If you
are creating a write-only property, you must include the WriteOnly
keyword.

To allow clients of a class to be able to change the
value of the property, the Set statement takes an argument. Here is an example:

Public Class Circle
Private rad As Double
Public Sub New()
rad = 0
End Sub
Public Sub New(ByVal r As Double)
rad = r
End Sub
Public WriteOnly Property Radius() As Double
Set(ByVal Value As Double)
End Set
End Property
End Class

The minimum operation you can perform with a write-only
property is to assign it a value that would be provided by the outside
world. To do this, you can assign the value of the Set argument to the
corresponding member variable that the property represents. Here is an
example:

Public Class Circle
Private rad As Double
Public Sub New()
rad = 0
End Sub
Public Sub New(ByVal r As Double)
rad = r
End Sub
Public WriteOnly Property Radius() As Double
Set(ByVal Value As Double)
rad = Value
End Set
End Property
End Class

As you see, clients of a class can change the
corresponding member variable of a member variable through the Set property writer.

Read/Write Properties

You may have realized that, if you create a read-only
property without the ability to write to it, the clients of a class can
only get the value of the property. On the other hand, a write-only
property restricts the ability to read the value it holds. In some rare
cases, you can keep these two functionalities separate. In most cases,
when creating a property, you would want its role to serve as a complete
"door" through which the clients of a class can read or change
the value of its hidden member variable. Such a property is create with
read-write capabilities.

A property is referred to as read-write if it allows
external classes, structures, and procedures to either change its value or
to read that value when necessary. To create a read-write property, you
must implement both the Get and the Set statements. The formula to follow
would be:

Notice that, because this is a read-write property,
you omit the ReadOnly and the WriteOnly keywords. When
implementing the property, provide the necessary functionality in the Get
and Set statements as we reviewed in the respective above sections. Here
is an example:

File: Circle.vb

Public Class Circle
Private ReadOnly PI As Double = 3.14158
Private rad As Double
Public Sub New()
rad = 0
End Sub
Public Sub New(ByVal r As Double)
rad = r
End Sub
Public Property Radius() As Double
Get
If rad < 0 Then
Return 0
Else
Return rad
End If
End Get
Set(ByVal Value As Double)
rad = Value
End Set
End Property
Public ReadOnly Property Diameter() As Double
Get
Return rad * 2
End Get
End Property
Public ReadOnly Property Circumference() As Double
Get
Return Diameter * PI
End Get
End Property
Public ReadOnly Property Area() As Double
Get
Return rad * rad * PI
End Get
End Property
End Class

To create read-write properties and complete the program, change the
content of the file as follows:

Public Class DepartmentStore
Private pItemNo As String
Private pCat As String
Private pName As String
Private pSize As String
Private pPrice As Double
Public Sub New(ByVal nbr As String, ByVal ctg As String, _
ByVal nme As String, ByVal siz As String, _
ByVal prc As Double)
pItemNo = nbr
pCat = ctg
pName = nme
pSize = siz
pPrice = prc
End Sub
' A property for store number of a merchandise
Public Property ItemNumber() As String
Get
If pItemNo = "" Then
Return "Invalid Item"
Else
Return pItemNo
End If
End Get
Set(ByVal Value As String)
pItemNo = Value
End Set
End Property
' A property for type of a merchandise
Public Property Category() As String
Get
If pCat = "" Then
Return "Unknown Category"
Else
Return pCat
End If
End Get
Set(ByVal Value As String)
pCat = Value
End Set
End Property
' A property for the name of a merchandise
Public Property ItemName() As String
Get
If pName = "" Then
Return "Item no Description"
Else
Return pName
End If
End Get
Set(ByVal Value As String)
pName = Value
End Set
End Property
' A property for size of a merchandise
Public Property Size() As String
Get
If pSize = "" Then
Return "Unknown Size or Fits All"
Else
Return pSize
End If
End Get
Set(ByVal Value As String)
pSize = Value
End Set
End Property
' A property for the marked price of an item
Public Property UnitPrice() As Double
Get
If pPrice = 0 Then
Return 0.0
Else
Return pPrice
End If
End Get
Set(ByVal Value As Double)
pPrice = Value
End Set
End Property
End Class