Characteristics of Members of a Class

 The Fields of a Class

 Constant Member Variables
 We know that you can create a constant variable in your program. In the same way, you can make a member variable of class to be constant. To do this, follow the same formula we used previously to declare a constant. Here is an example:
```Public Module Exercise
Public Class Circle
Public Const Twice As Integer = 2

Public Sub New()

End Sub
End Class

Public Function Main() As Integer
Dim circ As Circle
Dim Diameter As Double

circ = New Circle

MsgBox("Circle Characteristics" & vbCrLf & _
"Diameter:" & vbTab & Diameter)

Return 0
End Function
End Module```

This would produce:

In the same way, in Lesson 3, we saw that you could declare a variable as ReadOnly if you wanted its value to be constant. This can also be applied to a member of a class. To do this, follow the same formula we saw for those variables, except that the variable should be made a member of the class. Unlike a constant variable that you must initialize when creating it, you can declare a ReadOnly variable in the class without initializing it. This would be done as follows:

`Public ReadOnly PI As Double`

After declaring the variable, you should initialize it. You can do this when declaring it, as done for a constant. Here is an example:

```Public Class Circle
Public Const Twice As Integer = 2
Public ReadOnly PI As Double = 3.14159
End Class```

Alternatively, you can initialize the variable in the(a) constructor of its class. This would be done as follows:

```Public Module Exercise
Public Class Circle
Public Const Twice As Integer = 2

Public Sub New()
PI = 3.14159
End Sub
End Class

Public Function Main() As Integer
Dim circ As Circle
Dim Diameter As Double
Dim Circumference As Double

circ = New Circle
Circumference = Diameter * circ.PI

MsgBox("Circle Characteristics" & vbCrLf & _
"Diameter:" & vbTab & vbTab & Diameter & vbCrLf & _
"Circumference:" & vbTab & Circumference)

Return 0
End Function
End Module```

This would produce:

If the value held by a read-only member variable is gotten from an expression, then the value should be initialized in the(a) construction with the desired expression. If you don't rightly initialize it, the compiler would initialize it with the default value based on the type of that variable. Therefore, you should make sure you initialize your ReadOnly member variables in a constructor, if those variables are based on an expression. Here are a few examples:

```Public Module Exercise
Public Class Circle
Public Const Twice As Integer = 2

Public Sub New()
PI = 3.14159
Circumference = Diameter * PI
End Sub
End Class

Public Function Main() As Integer
Dim Circ As Circle = New Circle

MsgBox("Circle Characteristics" & vbCrLf & _
"Diameter:" & vbTab & vbTab & Circ.Diameter & vbCrLf & _
"Circumference:" & vbTab & Circ.Circumference & vbCrLf & _
"Area:" & vbTab & vbTab & Circ.Area)
Return 0
End Function
End Module```

This would produce:

In the previous section, we saw that a constant variable must be initialized when it is created. Although a read-only variable seems to follow the same rule, it doesn't. Remember that you don't need to initialize a read-only variable when you declare it since you can do this in the(a) constructor of the class. Also, because a constructor can be overloaded, a read-only member variable can hold different values depending on the particular constructor that is accessed at a particular time but the value of a constant variable cannot change: it is initialized once, in the class (or in a method) and it keeps that value throughout the class (or method).

 A Class as a Field

Just like any of the variables we have used so far, you can make a class or a structure a member variable of another class. To use a class in your own class, of course you must have that class. You can use one of the classes already available in C# or you can first create your own class. Here is an example of a class:

```Public Class Point
Friend x As Short
Friend y As Short
End Class```

A field is a member variable created from another class instead of a primitive type. To use one class as a member variable of another class, simply declare its variable as you would proceed with any of the member variables we have declared so far. Here is an example:

```Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private Start As Point
End Class```

After a class has been declared as a member variable of another class, it can be used regularly. Because the member is a class, declared as a reference, there are some rules you must follow to use it. After declaring the member variable, you must make sure you have allocated memory for it. You must also make sure that the variable is initialized appropriately before it can be used; otherwise you would receive an error when compiling the program.

 Practical Learning: Using a Class as a Field
1. Start a new Console Application and name it ElectronicStore1
2. In the Solution Explorer, right-click Module1.vb and click Rename
3. Type ElectronicStore.vb and press Enter
4. To create a new class, in the Solution Explorer, right-click the name of the project, position the mouse on Add and click Class...
5. Set the Name to StoreItem and click Add
6. Complete the file as follows:

 ```Public Class StoreItem Private nbr As Long Private cat As Char Private mk As String Private mdl As String Private price As Double Public Function GetItemNumber() As Long Return nbr End Function Public Sub SetItemNumber(ByVal number As Long) Me.nbr = number End Sub Public Function GetCategory() As String Select Case cat Case "a", "A" Return "Audio Cables" Case "b", "B" Return "Instructional and Tutorials (Books)" Case "c", "C" Return "Cell Phones and Accessories" Case "d", "D" Return "Bags and Cases" Case "e", "E" Return "Headphones" Case "f", "F" Return "Instructional and Tutorials (VHS & DVD)" Case "g", "G" Return "Digital Cameras" Case "h", "H" Return "Cables and Connectors" Case "i", "I" Return "PDAs and Accessories" Case "j", "J" Return "Telephones and Accessories" Case "k", "K" Return "Surge Protector" Case "l", "L" Return "TVs and Videos" Case Else Return "Unknown" End Select End Function Public Sub SetCategory(ByVal category As Char) Me.cat = category End Sub Public Function GetMake() As String Return mk End Function Public Sub SetMake(ByVal make As String) Me.mk = make End Sub Public Function GetModel() As String Return mdl End Function Public Sub SetModel(ByVal model As String) Me.mdl = model End Sub Public Function GetUnitPrice() As Double Return price End Function Public Sub SetUnitPrice(ByVal unitPrice As Double) Me.price = unitPrice End Sub End Class```
7. Save all

 Returning a Class or Passing a Class

 Returning a Class From a Method

Like a value from a regular type, you can return a class value from a method of a class. To do this, you can first declare the method and specify the class as the return type. Here is an example:

```Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private PtStart As Point
Private PtEnd As Point

Public Function GetThePoint() As Point

End Function
End Class```

After implementing the method, you must return a value that is conform to the class, otherwise you would receive an error when compiling the application. You can proceed by declaring a variable of the class in the body of the method, initializing the variable, and then returning it. Here is an example:

```Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private PtStart As Point
Private PtEnd As Point

Public Function GetThePoint() As Point
Dim Pt As Point = New Point

Pt.x = CShort(InputBox("Enter the x coordinate of the point: "))
Pt.y = CShort(InputBox("Enter the y coordinate of the point: "))

Return Pt
End Function
End Class```

Once a method has returned a value of a class, the value can be used as normally as possible. Here is an example:

```Public Module Exercise
Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private PtStart As Point
Private PtEnd As Point

Public Function GetThePoint() As Point
Dim Pt As Point = New Point

Pt.x = CShort(InputBox("Enter the x coordinate of the point: "))
Pt.y = CShort(InputBox("Enter the y coordinate of the point: "))

Return Pt
End Function
End Class

Public Function Main() As Integer
Dim Coordinate As Point
Dim Coordinator As CoordinateSystem

Coordinator = New CoordinateSystem
Coordinate = Coordinator.GetThePoint()

Return 0
End Function
End Module```
 Passing a Class as Argument

Once a class has been created, it can be used like any other variable. For example, its variable can be passed as argument to a procedure or to a method of another class. When a class is passed as argument:

• Its public members are available to procedures and classes of its project and procedures and classes of o ther projects
• Its friendly members are available to the procedures and classes of the same project

As done for the arguments of primitive types, in the body of the procedure gets the argument, access its public or friendly members and use them as you see fit. Here is an example:

```Public Module Exercise
Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private PtStart As Point
Private PtEnd As Point

Public Function GetThePoint() As Point
Dim Pt As Point = New Point

Pt.x = CShort(InputBox("Enter the x coordinate of the point: "))
Pt.y = CShort(InputBox("Enter the y coordinate of the point: "))

Return Pt
End Function

Public Sub ShowThePoint(ByVal Coord As Point)
MsgBox("Point Coordinate P(" & Coord.x & ", " & Coord.y & ")")
End Sub
End Class

Public Function Main() As Integer
Dim Coordinate As Point
Dim Coordinator As CoordinateSystem

Coordinator = New CoordinateSystem
Coordinate = Coordinator.GetThePoint()
Coordinator.ShowThePoint(Coordinate)
Return 0
End Function
End Module```

Here is an example of running the program:

As done for the arguments of primitive types, you can pass more than one class as argument to a method.

Because classes are always used as references, when passing a class as argument, it is implied to be passed by reference. To reinforce this, you can type the ByRef keyword to the left of the argument. Here are examples:

```Public Module Exercise
Public Class Point
Friend x As Short
Friend y As Short
End Class

Public Class CoordinateSystem
Private PtStart As Point
Private PtEnd As Point

Public Function GetThePoint() As Point
Dim Pt As Point = New Point

Pt.x = CShort(InputBox("Enter the x coordinate of the point: "))
Pt.y = CShort(InputBox("Enter the y coordinate of the point: "))

Return Pt
End Function

Public Sub ShowTheLine(ByRef StartPoint As Point, _
ByRef EndPoint As Point)
MsgBox("Line Characteristics: The line goes from P(" & _
StartPoint.x & ", " & StartPoint.y & ") to Q(" & _
EndPoint.x & ", " & EndPoint.y & ")")
End Sub
End Class

Public Function Main() As Integer
Dim First, Second As Point
Dim Coordinator As CoordinateSystem

Coordinator = New CoordinateSystem
First = Coordinator.GetThePoint()
Second = Coordinator.GetThePoint()

Coordinator.ShowTheLine(First, Second)
Return 0
End Function
End Module```
 Practical Learning: Returning a Class or Passing One as Argument
1. To return a class or pass it as argument, change the ElectronicStore.vb file as follows:

 ```Public Module ElectronicStore Dim DiscountAmount As Double Dim NetPrice As Double Dim Quantity As Integer Dim SaleTotal As Double Public Function GetDiscountRate() As Double Dim Discount As Double Discount = _ CDbl(InputBox("Discount Applied (Enter 0 to 100, 0 if no discount): ")) Return Discount End Function Public Function GetQuantity() As Integer Dim q As Integer q = CInt(inputbox("Enter Quantity: ")) Return q End Function Public Function Create() As StoreItem Dim ItemNumber As Long Dim Category As Char Dim Make As String Dim Model As String Dim Price As Double Dim SaleItem As StoreItem = New StoreItem ItemNumber = CLng(InputBox("Enter the Item #", "Nearson Electonics")) Category = CChar(InputBox("Category" & vbCrLf & _ "A - Audio Cables" & vbCrLf & _ "B - Instructional and Tutorials (Books)" & vbCrLf & _ "C - Cell Phones and Accessories" & vbCrLf & _ "D - Bags and Cases" & vbCrLf & _ "E - Headphones" & vbCrLf & _ "F - Instructional and Tutorials (VHS & DVD)" & vbCrLf & _ "G - Digital Cameras" & vbCrLf & _ "H - Cables and Connectors" & vbCrLf & _ "I - PDAs and Accessories" & vbCrLf & _ "J - Telephones and Accessories" & vbCrLf & _ "K - Surge Protector" & vbCrLf & _ "L - TVs and Videos" & vbCrLf & _ "Enter Your Choice:", "Nearson Electonics")) Make = InputBox("Enter Make", "Nearson Electonics") Model = InputBox("Enter Model", "Nearson Electonics") Price = CDbl(InputBox("Enter Unit Price:", "Nearson Electonics")) SaleItem.SetItemNumber(ItemNumber) SaleItem.SetCategory(Category) SaleItem.SetMake(Make) SaleItem.SetModel(Model) SaleItem.SetUnitPrice(Price) Return SaleItem End Function Public Sub ShowSaleItem(ByVal item As StoreItem) Dim discountRate As Double = GetDiscountRate() Quantity = CInt(GetQuantity()) DiscountAmount = item.GetUnitPrice() * discountRate / 100 NetPrice = item.GetUnitPrice() - DiscountAmount SaleTotal = NetPrice * Quantity MsgBox("=-= Nearson Electonics =-=" & vbCrLf & _ "Store Item Description" & vbCrLf & _ "Item Number:" & vbTab & item.GetItemNumber() & vbCrLf & _ "Category:" & vbTab & item.GetCategory() & vbCrLf & _ "Make:" & vbTab & vbTab & item.GetMake() & vbCrLf & _ "Model:" & vbTab & vbTab & item.GetModel() & vbCrLf & _ "Unit Price:" & vbTab & _ FormatCurrency(item.GetUnitPrice()) & vbCrLf & _ "Discount Rate:" & vbTab & _ FormatPercent(discountRate / 100) & vbCrLf & _ "Discount Amount:" & vbTab & _ FormatCurrency(DiscountAmount) & vbCrLf & _ "Price/Item:" & vbTab & FormatCurrency(NetPrice) & vbCrLf & _ "Quantity: " & vbTab & Quantity & vbCrLf & _ "Sale Total: " & vbTab & FormatCurrency(SaleTotal), _ MsgBoxStyle.OkOnly Or MsgBoxStyle.Information, _ "Nearson Electonics") End Sub Public Function Main() As Integer Dim Item As StoreItem = New StoreItem() Item = Create() ShowSaleItem(Item) End Function End Module```
2. Execute the application to test it
3. Enter the item information as follows:

 Item # 917305 Category e Make Sennheiser Model HD280 Pro Closed-Back Headphones Unit Price 99.95 Discount 20 Quantity 4
 Involving a Class and its Own Methods

 Passing a Class as its Own Argument

An instance of a class can be passed as an argument to one of its own methods (if you have programmed in C++, an example of this implementation is the copy constructor; although you can legitimately create a copy constructor in C#, it does not have the exact same concept as in C++, probably because C# has the Equals() method, which is actually a concept of the .NET Framework). To do this, you primarily pass the argument as if it were any class. Here is an example:

```Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub Equivalent(ByVal Same As Point)

End Sub
End Class```

Then, in the body of the method, do whatever you want. You can, or you may not, use the argument. Still, if you decide to use the argument, know that all of the other members of the class are available through the argument. Probably the simplest way to use the argument is the assign each of of its values to the equivalent member of the class. Here is an example:

```Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub Equivalent(ByVal Same As Point)
Me.x = Same.x
Me.y = Same.y
End Sub
End Class```

When calling the method, make sure you pass an instance of the class to it. You can first create and define the class, then pass it. Here is an example:

```Public Module Exercise
Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub Equivalent(ByVal Same As Point)
Me.x = Same.x
Me.y = Same.y
End Sub
End Class

Public Sub ShowPoint(ByVal Coord As Point)
MsgBox("Point Coordinate: P(" & Coord.x & ", " & Coord.y & ")")
End Sub

Public Function Main() As Integer
Dim Pt As Point = New Point

Pt.x = 4
Pt.y = 6
ShowPoint(Pt)

Dim One As Point = New Point
One.Equivalent(Pt)

ShowPoint(One)
Return 0
End Function
End Module```

This would produce:

Instead of first declaring a variable of the class and initializing it, you can create an instance of the class in the parentheses of the calling method. To do this, you may need a constructor that can specify the values of the fields of the class so the argument can be rightfully initialized. Here is an example:

```Public Module Exercise
Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub New()

End Sub

Public Sub New(ByVal XCoord As Integer, ByVal YCoord As Integer)
Me.x = XCoord
Me.y = YCoord
End Sub

Public Sub Equivalent(ByVal Same As Point)
Me.x = Same.x
Me.y = Same.y
End Sub
End Class

Public Sub ShowPoint(ByVal Coord As Point)
MsgBox("Point Coordinate: P(" & Coord.x & ", " & Coord.y & ")")
End Sub

Public Function Main() As Integer
Dim Pt As Point = New Point

Pt.x = 4
Pt.y = 6
ShowPoint(Pt)

Dim One As Point = New Point
One.Equivalent(New Point(-3, 2))
ShowPoint(One)

Return 0
End Function
End Module```

This would produce:

Instead of a formal method, you can use a constructor of the class to pass an instance of the same class. Then, in the constructor, use the argument as you see fit, knowing that all the members of the class are available. Here is an example:

```Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub New()

End Sub

Public Sub New(ByVal XCoord As Integer, ByVal YCoord As Integer)
Me.x = XCoord
Me.y = YCoord
End Sub

Public Sub New(ByVal Same As Point)
Me.x = Same.x
Me.y = Same.y
End Sub
End Class```

Obviously the purpose of passing a class to one of its own methods is not to find its equivalent. The C# language (actually the .NET Framework) can also take care of that (through the Equals() built-in method). Instead, you can create a method that takes an instance of the same class but modifies that instance. For example, for our Point class, we may want to create a new point that is distanced by one unit from the current Point object. Here is an example of doing that:

```Public Module Exercise
Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub New()

End Sub

Public Sub New(ByVal XCoord As Integer, ByVal YCoord As Integer)
Me.x = XCoord
Me.y = YCoord
End Sub

Public Sub Equivalent(ByVal Same As Point)
Me.x = Same.x
Me.y = Same.y
End Sub

Public Sub CreatePointOneUnitAway(ByVal AddUnit As Point)
End Sub
End Class

Public Sub ShowPoint(ByVal Coord As Point)
MsgBox("Point Coordinate: P(" & Coord.x & ", " & Coord.y & ")")
End Sub

Public Function Main() As Integer
Dim Pt As Point = New Point

Pt.x = 4
Pt.y = 6

Dim One As Point = New Point
One.CreatePointOneUnitAway(Pt)
ShowPoint(One)
One.CreatePointOneUnitAway(New Point(-8, -3))
ShowPoint(One)

Return 0
End Function
End Module```

This would produce:

 Returning a Class From its Own Method

You can create a method in a class that returns an instance of the class. To start, on the left side of the method, enter the name of the class. Here is an example:

```Public Class Point
Public Function MethodName() As Point

End Function
End Class```

There are various ways you can deal with the method. If you want to return a new value of the class, you can declare an instance of the class, initialize it, and then return it. Here is an example:

```Public Module Exercise
Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub New()

End Sub

Public Sub New(ByVal XCoord As Integer, ByVal YCoord As Integer)
Me.x = XCoord
Me.y = YCoord
End Sub

Public Sub New(ByVal Same As Point)
Me.x = Same.x
Me.x = Same.x
End Sub

Dim Some As Point = New Point
Some.x = 5
Some.y = 5
Return Some
End Function
End Class

Public Sub ShowPoint(ByVal Coord As Point)
MsgBox("Point Coordinate: P(" & Coord.x & ", " & Coord.y & ")")
End Sub

Public Function Main() As Integer
Dim Pt As Point = New Point

Pt.x = 4
Pt.y = 6
ShowPoint(Pt)

Dim Away5 As Point = Pt.AdvanceBy5()
ShowPoint(Away5)

Return 0
End Function
End Module```

This would produce:

Alternatively, you can declare an instance of the class, use the current values of the class combined with the those of the instance to get new values, and then return the instance.

Remember that, to call a method, if it is not static, you will need to declare an instance of the class from where you are calling the method. The second type of implementation consists of modifying the instance of the class that is calling the method. For example, you can add values to its fields or you can perform any other operation you want on the members of the calling instance. is an example:

```Public Module Exercise
Public Class Point
Friend x As Integer
Friend y As Integer

Public Sub New()

End Sub

Public Sub New(ByVal XCoord As Integer, ByVal YCoord As Integer)

Me.x = XCoord
Me.y = YCoord
End Sub

Public Sub New(ByVal Same As Point)

Me.x = Same.x
Me.x = Same.x
End Sub

REM This method adds 1 to each field of the class
REM to get a new point away North-East of the current point
Public Function CreatePointOneUnitAway() As Point
Me.x = Me.x + 1
Me.y = Me.y + 1

Return Me
End Function
End Class

Public Sub ShowPoint(ByVal Coord As Point)
MsgBox("Point Coordinate: P(" & Coord.x & ", " & Coord.y & ")")
End Sub

Public Function Main() As Integer
Dim Pt As Point = New Point

Pt.x = 4
Pt.y = 6

ShowPoint(Pt)

Dim One As Point = New Point(-8, 5)
Dim Another As Point = One.CreatePointOneUnitAway()
ShowPoint(Another)

Return 0
End Function
End Module```

This would produce:

As we have learned now, you can create a method that takes an argument that is the same type as its parent class. In the method, you can access any member of the class, including calling the other methods of the class.