In elementary school, we learned how to perform
arithmetic operations such as adding 2 to 5 to get 7. We also learned
somehow how to add letters to create a word, how to add words to create a
sentence, and how to add symbols to create abbreviations. In programming, we
learn how to create classes that are made of more than one value. When
necessary, we may want to add the values of those classes to get new values.
Unfortunately, those classes are not equipped to perform arithmetic
operations or comparisons on their objects. Fortunately, if you judge it
necessary, you can write code that makes it possible.

We know many of the operators available in the Visual
Basic language. We also reviewed some of the ways they can be used. We saw
that there are rules that must be followed when using any of those
operators.

Operator overloading consists of customizing the
behavior of a Visual Basic operator to be able to apply it on the values
of a class. This means that you must create a special behavior in your
class for a particular operator you want to use.

A class whose operators you want to overload primarily
starts like any class. You can add any members you judge necessary to it.
Make sure you provide appropriate and realistic constructors so the class
can be initialized appropriately. The other important detail you should
take care of is how the value of the class will be accessed outside.
Probably the easiest way to do this consists of overriding the
ToString() method in it.

Here is an example of a class:

Public Class Natural
Public Number As Integer
Public Sub New(ByVal N As Integer)
Number = N
End Sub
Public Overrides Function ToString() As String
Return Number.ToString()
End Function
End Class

Application:
Introducing Operator Overloading

Start Microsoft Visual Basic

To start a new application, on the Start Page, click File -> New
Project...

In the middle list, click Class Library

Change the Name to Mathematics

Click OK

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

Type Arithmetic.vb and press Enter

To save the project, on the Standard toolbar, click the Save All
button

Make a note of the location and click Save

Change the file as follows:

Public Class Arithmetic
Public Shared Function GreatestCommonDivisor(ByVal a As Long, ByVal b As Long)
Dim Remainder As Long
While b <> 0
Remainder = a Mod b
a = b
b = Remainder
End While
Return a
End Function
End Class

To create the library, in the Solution Explorer, right-click
Mathematics and click Build

To create a new project, on the main menu, click File -> New
Project...

In the middle list, click Console Application

Change the name to Algebra1

Click OK

On the main menu, click Project -> Algebra1Properties

Click the arrow of the Application Type box and select Windows
Forms Application

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

Type Algebra.vb and press Enter twice

Change the document as follows:

Module Algebra
Public Function Main() As Integer
Return 0
End Function
End Module

In the Solution Explorer, right-click Algebra1 and click Add
Reference...

Click the Browse tab

Locate the folder where the Mathematics library was created

Select Mathematics.dll

Click OK

To create a new class, in the Class View, right-click Algebra1 ->
Add -> Class...

Set the Name to Rational

Click Add

Change the file as follows:

Imports Mathematics
Public Class Rational
Private Num As Long
Private Den As Long
Public Sub New(ByVal n As Long, ByVal d As Long)
Num = n
Den = d
End Sub
Public Property Numerator() As String
Get
Return Num / Arithmetic.GreatestCommonDivisor(Num, Den)
End Get
Set(ByVal value As String)
Num = value
End Set
End Property
Public Property Denominator() As String
Get
Return Den / Arithmetic.GreatestCommonDivisor(Num, Den)
End Get
Set(ByVal value As String)
Den = value
End Set
End Property
Public Overrides Function ToString() As String
Dim Numer As Long
Dim Denom As Long
Numer = Num / Arithmetic.GreatestCommonDivisor(Num, Den)
Denom = Den / Arithmetic.GreatestCommonDivisor(Num, Den)
If Denom = 1 Then
Return Numer.ToString()
Else
Return String.Format("{0}/{1}", Numer, Denom)
End If
End Function
End Class

The Formula

To overload an operator, you must create a Shared
method using the following formula:

You can start with the Public access
modifier, followed by the Shared keyword. You can use
additional keywords and/or mechanisms to control access to the method. You
must then use the Operator keyword. This is followed by
the actual operator you want to customize. There are rules you must, and
suggestions you should, follow:

Not all operators need to be customized for all classes. For
example, while it would be feasible to add two books to get a new book
that includes all the pages on both books and their combined authors,
it may not be realistic to multiply two books (to get what?).
Therefore, you should select the right operator based on your needs

While some operators are always available to be overloaded, some
operators have restrictive rules. This means that you cannot just use
any operator anyhow

Not all operators are overloadable

After the operator, open that parentheses that must
always be used on a function. In the parentheses, you will add one or more
arguments, depending on the operator. After the closing parenthesis, you
must specify a return type. Normally, you should return the class itself.
After all, the operator will act on an object of its class type. For this
reason, the method should return a value that represents its class.

To end the method, you must use the End
Operator expression. In the body of the method, you can implement
the behavior and make sure you return a value. After defining the method,
you can call it either inside or outside the class.

Overloading an Operator

Unary Operators

A unary operator is one that acts on one value. The
Visual Basic language provides many unary operators but not all can be
overloaded. The unary operarors available for overloading are +, -,
Not, IsTrue, IsFalse,
and CType.

To overload a unary operator, pass one argument to the
parentheses of the method. In the body of the method, perform the desired
operation. Here is an example of overloading a unary operator:

Public Class Natural
Public Number As Integer
Public Sub New(ByVal N As Integer)
Number = N
End Sub
Public Shared Operator Not(ByVal Value As Natural) As Natural
Dim Nbr As Integer = Value.Number
Dim N As Integer = Not Nbr
Dim Nat As Natural = New Natural(N)
Return Nat
End Operator
Public Overrides Function ToString() As String
Return Number.ToString()
End Function
End Class

A binary operator is one that acts on two values. The
values must be of the same type. The Visual Basic language provides a rich
set of binary operators. Those used in arithmetics are: +, -, *, /, \, and
Mod.

To overloaded a binary arithmetic operator, pass two
arguments to the parentheses of the method. The first arguments must be of
the type of class in which you are working. The second argument can be
another type. Here is an example:

If you want to perform the operations on two similar
types of values, then the second argument must be of the same type as the
first, which is the class you are using.

Application:
Overloading Binary Operators

Access the Rational.vb file and change it as follows:

Imports Mathematics
Public Class Rational
Private Num As Long
Private Den As Long
Public Sub New(ByVal n As Long, ByVal d As Long)
Num = n
Den = d
End Sub
Public Property Numerator() As String
Get
Return Num / Arithmetic.GreatestCommonDivisor(Num, Den)
End Get
Set(ByVal value As String)
Num = value
End Set
End Property
Public Property Denominator() As String
Get
Return Den / Arithmetic.GreatestCommonDivisor(Num, Den)
End Get
Set(ByVal value As String)
Den = value
End Set
End Property
Public Shared Operator +(ByVal First As Rational,
ByVal Second As Rational) As Rational
Dim Top As Long
Dim Bottom As Long
Top = (First.Numerator * Second.Denominator) +
(First.Denominator * Second.Numerator)
Bottom = First.Denominator * Second.Denominator
Return New Rational(Top, Bottom)
End Operator
Public Shared Operator -(ByVal First As Rational,
ByVal Second As Rational) As Rational
Dim Top As Long
Dim Bottom As Long
Top = (First.Numerator * Second.Denominator) -
(First.Denominator * Second.Numerator)
Bottom = First.Denominator * Second.Denominator
Return New Rational(Top, Bottom)
End Operator
Public Shared Operator *(ByVal First As Rational,
ByVal Second As Rational) As Rational
Dim Top As Long
Dim Bottom As Long
Top = First.Numerator * Second.Numerator
Bottom = First.Denominator * Second.Denominator
Return New Rational(Top, Bottom)
End Operator
Public Shared Operator /(ByVal First As Rational,
ByVal Second As Rational) As Rational
Dim Top As Long
Dim Bottom As Long
Top = First.Numerator * Second.Denominator
Bottom = First.Denominator * Second.Numerator
Return New Rational(Top, Bottom)
End Operator
Public Overrides Function ToString() As String
Dim Numer As Long
Dim Denom As Long
Numer = Num / Arithmetic.GreatestCommonDivisor(Num, Den)
Denom = Den / Arithmetic.GreatestCommonDivisor(Num, Den)
If Denom = 1 Then
Return Numer.ToString()
Else
Return String.Format("{0}/{1}", Numer, Denom)
End If
End Function
End Class

To execute the application, on the main menu, click Debug -> Start
Debugging

Click OK

When requested, enter the first numerator as 128
and press Enter

Enter the first denominator as 54 and press Enter

Enter the second numerator as 88 and press Enter

Enter the second denominator as 36 and press Enter

Binary Bitwise Operators

Besides the traditional arithmetic operations, Visual
Basic support the ability to add or shift bits in the computer memory. These
operators are the bitwise conjunction operator & and its assignment
operator &=, the bitwise disjunction operator | and its assignment operator
|=, the bitwise exclusion operator ^ and its assignment operator ^=, the
left-shift operator << and its assigment operator <<=, the right-shift
operator >> and its assignment operator >>=. When necessary, overload only
the primary operator (&, |, ^, <<, >>) and its equivalent assignment
operator will be automatically provided by the compiler.

To overloaded a binary operator, pass two arguments to
the parentheses of the method. For the two bitwise shift operators, << and
>>, the first argument must be the class in which you are working and the
second argument must by a constant integer (type int). Here
is an example that overloads the left bitwise shifter <<:

Public Module Exercise
Public Function Main() As Integer
Dim Nbr As Natural
Nbr = New Natural(1248)
MsgBox("Shiftting the bits of " & Nbr.ToString() &
" to the left by 4 is " & (Nbr << 4).ToString())
Return 0
End Function
End Module

This would produce:

For the operators that join or disjoin two series of
bits:

The first argument must be the class on which you are working. The
second argument can be an integer. Here is an example:

Public Shared Operator And(ByVal Value As Natural,
ByVal Constant As Integer) As Natural
Dim Result As Integer = Value.Number And Constant
Return New Natural(Result)
End Operator

As its name implies, a comparison is used to find out
whether one of two values is higher than the other. The values must be of
the same type. Comparison operators go in pair. That is, if you want to
compare two values for equality, you must also be able to know when they are
different. For this reason, if you decide to overload a comparison operator,
you must also overload its opposite:

If you overload =, you must also overload <> and vice versa

If you overload <, you must also overload > and vice versa

If you overload <=, you must also overload >= and vice versa

If you overload IsTrue, you must also overload
IsFalse and vice versa

We know that the Object class is
equipped with a method named Equals. That method makes it
possible to find out whether one object is equal to another. And since all
classes in a Visual Basic application derive from Object,
if you decide to overload a couple of comparison operators, you should also
override the Equals() method.

Restricted Operators

Some operators either cannot be overloaded or depend on
other operators being overloaded. The following operators cannot be
overloaded: =, AddressOf, AndAlso,
AsType, GetType, Is,
IsNot, New, OrElse, and
TypeOf ... Is.