Showing posts with label Visual Basic. Show all posts
Showing posts with label Visual Basic. Show all posts

Step By Step Practical Visual Basic tutorials

Visual Basic tutorial

This is a Visual Basic tutorial. In this tutorial you will learn Visual Basic language. The tutorial is suitable for beginners.

Table of contents

Visual Basic

Visual Basic language is a high-level programming language for the .NET Framework. It is a very popular language. Currently, it is one of the top 10 popular languages in the world. It was created for the Windows platform. The Mono project has created a clone for the Linux and Mac platforms.
Continue Reading

Input And Output in Visual Basic

Input & Output

This chapter is dedicated to Input & Output in Visual Basic. The Input & Output in Visual Basic is based on streams.
Streams are objects to work with Input/Output. A stream is an abstraction of a sequence of bytes, such as a file, an input/output device, an inter-process communication pipe, or a TCP/IP socket. In Visual Basic, we have a Stream class, that is an abstract class for all streams. There are additional classes that derive from the Stream class and make the programming a lot easier.

MemoryStream

A MemoryStream is a stream which works with data in a computer memory.
Option Strict On


Imports System.IO

Module Example

Sub Main()

Dim ms As Stream = New MemoryStream(6)

ms.WriteByte(9)
ms.WriteByte(11)
ms.WriteByte(6)
ms.WriteByte(8)
ms.WriteByte(3)
ms.WriteByte(7)

ms.Position = 0

Dim rs As Integer
rs = ms.ReadByte()

Do While rs <> -1
Console.WriteLine(rs)
rs = ms.ReadByte()
Loop

ms.Close()

End Sub

End Module
We write six numbers to a memory with a MemoryStream. Then we read those numbers and print them to the console.
Dim ms As Stream = New MemoryStream(6)
The line creates and initializes a MemoryStream object with a capacity of six bytes.
ms.Position = 0
We set the position of the cursor in the stream to the beginning using the Position property.
ms.WriteByte(9)
ms.WriteByte(11)
ms.WriteByte(6)
...
The WriteByte() method writes a byte to the current stream at the current position.
Do While rs <> -1
Console.WriteLine(rs)
rs = ms.ReadByte()
Loop
Here we read all bytes from the stream and print them to the console.
ms.Close()
Finally, we close the stream.
$ ./memory.exe 
9
11
6
8
3
7
Output of the example.

StreamReader & StreamWriter

StreamReader reads characters from a byte stream. It defaults to UTF-8 encoding. StreamWriter writes characters to a stream in a particular encoding.
Option Strict On

Imports System.IO

Module Example

Sub Main()

Dim file As String
file = "languages"

Try
Dim stream As StreamReader
stream = New StreamReader(file)
Console.WriteLine(stream.ReadToEnd())
Catch e As IOException
Console.WriteLine("Cannot read file.")
End Try

End Sub

End Module
We have a file called languages. We read characters from that file and print them to the console.
Dim stream As StreamReader
stream = New StreamReader(file)
The StreamReader takes a file name as a parameter.
Console.WriteLine(stream.ReadToEnd())
The ReadToEnd() method reads all characters to the end of the stream.
$ cat languages 
Python
Visual Basic
PERL
Java
C
C#
$ ./readfile.exe
Python
Visual Basic
PERL
Java
C
C#
We have a languages file in the current directory. We print all lines of the file to the console.

In the next example, we will be counting lines.
Option Strict On

Imports System.IO

Module Example

Sub Main()

Dim file As String
Dim count As Integer

file = "languages"

Try
Dim stream As StreamReader
stream = New StreamReader(file)

While Not (stream.ReadLine() Is Nothing)
count += 1
End While

Catch e As IOException
Console.WriteLine("Cannot read file.")
End Try

Console.WriteLine("There are {0} lines", count)

End Sub

End Module
Counting lines in a file.
While Not (stream.ReadLine() Is Nothing)
count += 1
End While
In the While loop, we read a line from the stream with the ReadLine() method. It returns a line from the stream or Nothing if the end of the input stream is reached.

An example with StreamWriter follows.
Option Strict On

Imports System.IO

Module Example

Sub Main()

Dim mstream As New MemoryStream()
Dim swriter As New StreamWriter(mstream)

swriter.Write("ZetCode, tutorials for programmers.")
swriter.Flush()

Dim sreader As New StreamReader(mstream)
Console.WriteLine(sreader.ReadToEnd())
sreader.Close()

End Sub

End Module
In the preceding example, we write characters to the memory.
Dim mstream As New MemoryStream()
A MemoryStream is created.
Dim swriter As New StreamWriter(mstream)
A StreamWriter class takes a memory stream as a parameter. This way, we are going to write to memory stream.
swriter.Write("ZetCode, tutorials for programmers.")
swriter.Flush()
We write some text to the writer. The Flush()clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.
Dim sreader As New StreamReader(mstream)
Console.WriteLine(sreader.ReadToEnd())
Now we create an instance of the stream reader and read everything we have written back.

FileStream

A FileStream class uses a stream on a file on the filesystem. This class can be used to read from files, write to files, open them and close them.
Option Strict On

Imports System.IO
Imports System.Text

Module Example

Sub Main()
Dim fstream As New FileStream("author", FileMode.Append)
Dim bytes As Byte() = New UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский")

fstream.Write(bytes, 0, bytes.Length)
fstream.Close()
End Sub

End Module
We write some text in Russian azbuka to the file in the current working directory.
Dim fstream As New FileStream("author", FileMode.Append)
A FileStream object is created. The second parameter is a mode, in which the file is opened. The append mode opens the file if it exists and seeks to the end of the file, or creates a new file.
Dim bytes As Byte() = New UTF8Encoding().GetBytes("Фёдор Михайлович Достоевский")
We create an array of bytes from text in russian azbuka.
fstream.Write(bytes, 0, bytes.Length)
We write the bytes to the file stream.

XmlTextReader

We can use streams to read xml data. The XmlTextReader is the class to read xml files in Visual Basic. The class is forward-only and read-only.
We have the following xml test file.
<?xml version="1.0" encoding="utf-8" ?>
<languages>
<language>Python</language>
<language>Ruby</language>
<language>Javascript</language>
<language>C#</language>
</languages>
Option Strict On

Imports System.IO
Imports System.Xml

Module Example

Sub Main()

Dim file As String
file = "languages.xml"

Try
Dim xreader As New XmlTextReader(file)

xreader.MoveToContent()

Do While xreader.Read()
Select Case xreader.NodeType
Case XmlNodeType.Element
Console.Write(xreader.Name & ": ")
Case XmlNodeType.Text
Console.WriteLine(xreader.Value)
End Select
Loop

xreader.Close()

Catch e As IOException
Console.WriteLine("Cannot read file.")
Catch e As XmlException
Console.WriteLine("XML parse error")
End Try

End Sub

End Module
This Visual Basic program reads data from the previously specified xml file and prints it to the terminal.
Dim xreader As New XmlTextReader(file)
An XmlTextReader object is created. It takes the file name as a parameter.
xreader.MoveToContent()
The MoveToContent() method moves to the actual content of the xml file.
Do While xreader.Read()
This line reads the next node from the stream.
Case XmlNodeType.Element
Console.Write(xreader.Name & ": ")
Case XmlNodeType.Text
Console.WriteLine(xreader.Value)
Here we print the element name and element text.
Catch e As XmlException
Console.WriteLine("XML parse error")
We check for xml parse error.
$ ./readxml.exe 
language: Python
language: Ruby
language: Javascript
language: C#
Output of example.

Files and directories

The .NET framework provides other classes that we can use to work with files and directories.
A File class is a higher level class that has shared methods for file creation, deletion, copying, moving and opening. These methods make the job easier.
Option Strict On

Imports System.IO

Module Example

Sub Main()
Try
Dim sw As StreamWriter

sw = File.CreateText("cars")

sw.WriteLine("Toyota")
sw.WriteLine("Skoda")
sw.WriteLine("BMW")
sw.WriteLine("Volkswagen")
sw.WriteLine("Volvo")

sw.Close()
Catch e As IOException
Console.WriteLine("IO error")
End Try

End Sub

End Module
In the example, we create a cars file and write some car names into it.
sw = File.CreateText("cars")
The CreateText() method creates or opens a file for writing UTF-8 encoded text. It returns a StreamWriter object.
sw.WriteLine("Toyota")
sw.WriteLine("Skoda")
...
We write two lines to the stream.

Option Strict On

Imports System.IO

Module Example

Sub Main()

If File.Exists("cars")
Console.WriteLine(File.GetCreationTime("cars"))
Console.WriteLine(File.GetLastWriteTime("cars"))
Console.WriteLine(File.GetLastAccessTime("cars"))
End If

File.Copy("cars", "newcars")

End Sub

End Module
In the second example, we show other five shared methods of the File class.
If File.Exists("cars")
The Exists() method determines whether the specified file exists.
Console.WriteLine(File.GetCreationTime("cars"))
Console.WriteLine(File.GetLastWriteTime("cars"))
Console.WriteLine(File.GetLastAccessTime("cars"))
We get creation time, last write time and last access time of the specified file.
File.Copy("cars", "newcars")
The Copy() method copies the file.

The My.Computer.FileSystem is and object, which provides properties and methods for working with drives, files, and directories.
Option Strict On

Imports System.IO

Module Example

Sub Main()

Try
My.Computer.FileSystem.CreateDirectory("temp")
My.Computer.FileSystem.CreateDirectory("newdir")
My.Computer.FileSystem.MoveDirectory("temp", "temporary")
Catch e As IOException
Console.WriteLine("Cannot create directories")
Console.WriteLine(e.Message)
End Try

End Sub

End Module
We will use two methods from the above mentioned object.
My.Computer.FileSystem.CreateDirectory("temp")
The CreateDirectory() method creates a new directory.
My.Computer.FileSystem.MoveDirectory("temp", "temporary")
The MoveDirectory() method gives a specified directory a new name.

The DirectoryInfo and Directoryhave methods for creating, moving, and enumerating through directories and subdirectories.
Option Strict On

Imports System.IO

Module Example

Dim subDir As IO.DirectoryInfo
Dim dir As New IO.DirectoryInfo("../io")

Dim fileName As String

Dim files As String() = Directory.GetFiles("../io")
Dim dirs As DirectoryInfo() = dir.GetDirectories()

Sub Main()

For Each subDir In dirs
Console.WriteLine(subDir.Name)
Next

For Each fileName In files
Console.WriteLine(fileName)
Next

End Sub

End Module
We use the DirectoryInfo class to traverse a specific directory and print its contents.
Dim dir As New IO.DirectoryInfo("../io")
We will show the contents of this directory (io).
Dim files As String() = Directory.GetFiles("../io")
We get all files of the io directory using the shared GetFiles() method.
Dim dirs As DirectoryInfo() = dir.GetDirectories()
We get all directories.
For Each subDir In dirs
Console.WriteLine(subDir.Name)
Next
Here we loop through directories and print their names to the console.
For Each fileName In files
Console.WriteLine(fileName)
Next
Here we loop through the array of files and print their names to the console.
$ ./showcontents.exe 
newdir
temp
temporary
../io/append.exe
../io/append.vb
../io/append.vb~
../io/author
../io/cars
...
Output of the example.
In this chapter, we have covered Input/Output operations in Visual Basic.
Continue Reading

Visual Basic collections

Collections

In this chapter we will deal with Visual Basic collections. The .NET framework provides specialized classes for data storage and retrieval. In the previous chapter, we have described arrays. Collections are enhancement to the arrays.
There are two distinct collection types in Visual Basic. The standard collections, which are found under the System.Collections namespace and the generic collections, under System.Collections.Generic. The generic collections are more flexible and are the preferred way to work with data. The generic collections or generics were introduced in .NET framework 2.0. Generics enhance code reuse, type safety, and performance.
Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This approach, pioneered by Ada in 1983, permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication. (Wikipedia)

ArrayList

ArrayList is a collection from a standard System.Collections namespace. It is a dynamic array. It provides random access to its elements. An ArrayList automatically expands as data is added. Unlike arrays, an ArrayList can hold data of multiple data types. Elements in the ArrayList are accessed via an integer index. Indexes are zero based. Indexing of elements and insertion and deletion at the end of the ArrayList takes constant time. Inserting or deleting an element in the middle of the dynamic array is more costly. It takes linear time.
Option Strict On

Imports System.Collections

Module Example

Class Empty

End Class


Sub Main()

Dim da As ArrayList = New ArrayList()

da.Add("Visual Basic")
da.Add(344)
da.Add(55)
da.Add(New Empty)
da.Remove(55)

For Each el As Object In da
Console.WriteLine(el)
Next

End Sub

End Module
In the above example, we have created an ArrayList collection. We have added some elements to it. They are of various data type. String, integers and a class object.
Imports System.Collections
In order to work with ArrayList collection, we need to import System.Collections namespace.
Dim da As ArrayList = New ArrayList()
ArrayList collection is created.
da.Add("Visual Basic")
da.Add(344)
da.Add(55)
da.Add(New Empty)
We add five elements to the array with the Add() method.
da.Remove(55)
We remove one element.
For Each el As Object In da
Console.WriteLine(el)
Next
We iterate through the array and print its elements to the console.

List

A List is a strongly typed list of objects that can be accessed by index. It can be found under System.Collections.Generic namespace.
Option Strict On

Imports System.Collections.Generic

Module Example

Sub Main()

Dim langs As New List(Of String)
langs.Add("Java")
langs.Add("C#")
langs.Add("C")
langs.Add("C++")
langs.Add("Ruby")
langs.Add("Javascript")

Console.WriteLine(langs.Contains("C#"))

Console.WriteLine(langs(1))
Console.WriteLine(langs(2))

langs.Remove("C#")
langs.Remove("C")

Console.WriteLine(langs.Contains("C#"))

langs.Insert(4, "Haskell")

langs.Sort()

For Each lang As String In langs
Console.WriteLine(lang)
Next

End Sub

End Module
In the preceding example, we work with the List collection.
Imports System.Collections.Generic
In order to work with the List collection, we need to import the System.Collections.Genericnamespace.
Dim langs As New List(Of String)
A generic dynamic array is created. We specify that we will work with strings with the Of keyword.
langs.Add("Java")
langs.Add("C#")
langs.Add("C")
...
We add elements to the List using the Add() method.
Console.WriteLine(langs.Contains("C#"))
We check if the List contains a specific string using the Contains() method.
Console.WriteLine(langs(1))
Console.WriteLine(langs(2))
We access the second and the third element of the List using the index notation.
langs.Remove("C#")
langs.Remove("C")
We remove two strings from the List.
langs.Insert(4, "Haskell")
We insert a string at a specific location.
langs.Sort()
We sort the elements using the Sort()method.
$ ./list.exe 
True
C#
C
False
C++
Haskell
Java
Javascript
Ruby
Outcome of the example.

LinkedList

LinkedList is a generic doubly linked list in Visual Basic. LinkedList only allows sequential access. LinkedList allows for constant-time insertions or removals, but only sequential access of elements. Because linked lists need extra storage for references, they are impractical for lists of small data items such as characters. Unlike dynamic arrays, arbitrary number of items can be added to the linked list (limited by the memory of course) without the need to realocate, which is an expensive operation.
Option Strict On

Imports System.Collections.Generic

Module Example

Sub Main()

Dim nums As New LinkedList(Of Integer)

nums.AddLast(23)
nums.AddLast(34)
nums.AddLast(33)
nums.AddLast(11)
nums.AddLast(6)
nums.AddFirst(9)
nums.AddFirst(7)

Dim node as LinkedListNode(Of Integer)

node = nums.Find(6)
nums.AddBefore(node, 5)

For Each num As Integer In nums
Console.WriteLine(num)
Next

End Sub

End Module
This is a LinkedList example with some of its methods.
Dim nums As New LinkedList(Of Integer)
This is an integer LinkedList.
nums.AddLast(23)
...
nums.AddFirst(9)
We populate the linked list using the AddLast()and AddFirst() methods.
Dim node as LinkedListNode(Of Integer)

node = nums.Find(6)
nums.AddBefore(node, 5)
A LinkedList consists of nodes. We find a specific node and add an element before it.
For Each num As Integer In nums
Console.WriteLine(num)
Next
Printing all elements to the console.

Dictionary

A dictionary, also called an associative array, is a collection of unique keys and a collection of values, where each key is associated with one value. Retrieving and adding values is very fast. Dictionaries take more memory, because for each value there is also a key.
Option Strict On

Imports System.Collections.Generic

Module Example

Sub Main()

Dim domains As New Dictionary(Of String, String)

domains.Add("de", "Germany")
domains.Add("sk", "Slovakia")
domains.Add("us", "United States")
domains.Add("ru", "Russia")
domains.Add("hu", "Hungary")
domains.Add("pl", "Poland")

Console.WriteLine(domains("sk"))
Console.WriteLine(domains("de"))

Console.WriteLine("Dictionary has {0} items", _
domains.Count)

Console.WriteLine("Keys of the dictionary:")

Dim keys As Dictionary(Of String, String).KeyCollection = domains.Keys

For Each key As String In keys
Console.WriteLine("{0}", key)
Next

Console.WriteLine("Values of the dictionary:")

Dim vals As Dictionary(Of String, String).ValueCollection = domains.Values

For Each val As String In vals
Console.WriteLine("{0}", val)
Next

Console.WriteLine("Keys and values of the dictionary:")

For Each kvp As KeyValuePair(Of String, String) In domains
Console.WriteLine("Key = {0}, Value = {1}", _
kvp.Key, kvp.Value)
Next

End Sub

End Module
We have a dictionary, where we map domain names to their country names.
Dim domains As New Dictionary(Of String, String)
We create a dictionary with string keys and values.
domains.Add("de", "Germany")
domains.Add("sk", "Slovakia")
domains.Add("us", "United States")
...
We add some data to the dictionary. The first string is the key. The second is the value.
Console.WriteLine(domains("sk"))
Console.WriteLine(domains("de"))
Here we retrieve two values by their keys.
Console.WriteLine("Dictionary has {0} items", _
domains.Count)
We print the number of items by referring to the Count property.
Dim keys As Dictionary(Of String, String).KeyCollection = domains.Keys

For Each key As String In keys
Console.WriteLine("{0}", key)
Next
These lines retrieve all keys from the dictionary.
Dim vals As Dictionary(Of String, String).ValueCollection = domains.Values

For Each val As String In vals
Console.WriteLine("{0}", val)
Next
These lines retrieve all values from the dictionary.
For Each kvp As KeyValuePair(Of String, String) In domains
Console.WriteLine("Key = {0}, Value = {1}", _
kvp.Key, kvp.Value)
Next
Finally, we print both keys and values of the dictionary.
./dictionary.exe
Slovakia
Germany
Dictionary has 6 items
Keys of the dictionary:
de
sk
us
ru
hu
pl
Values of the dictionary:
Germany
Slovakia
United States
Russia
Hungary
Poland
Keys and values of the dictionary:
Key = de, Value = Germany
Key = sk, Value = Slovakia
Key = us, Value = United States
Key = ru, Value = Russia
Key = hu, Value = Hungary
Key = pl, Value = Poland
This is the output of the example.

Queues

A queue is a First-In-First-Out (FIFO) data structure. The first element added to the queue will be the first one to be removed. Queues may be used to process messages as they appear or serve customers as they come. The first customer which comes should be served first.
Option Strict On

Imports System.Collections.Generic

Module Example

Sub Main()

Dim msgs As New Queue(Of String)

msgs.Enqueue("Message 1")
msgs.Enqueue("Message 2")
msgs.Enqueue("Message 3")
msgs.Enqueue("Message 4")
msgs.Enqueue("Message 5")

Console.WriteLine(msgs.Dequeue())
Console.WriteLine(msgs.Peek())
Console.WriteLine(msgs.Peek())

Console.WriteLine()

For Each msg As String In msgs
Console.WriteLine(msg)
Next

End Sub

End Module
In our example, we have a queue with messages.
Dim msgs As New Queue(Of String)
A queue of strings is created.
msgs.Enqueue("Message 1")
msgs.Enqueue("Message 2")
...
The Enqueue() adds a message to the end of the queue.
Console.WriteLine(msgs.Dequeue())
The Dequeue() method removes and returns the item at the beginning of the queue.
Console.WriteLine(msgs.Peek())
The Peek() method returns the next item from the queue, but does not remove it from the collection.
$ ./queue.exe 
Message 1
Message 2
Message 2

Message 2
Message 3
Message 4
Message 5
The Dequeue() method removes the "Message 1" from the collection. The Peek() method does not. The "Message 2" remains in the collection.

Stacks

A stack is a Last-In-First-Out (LIFO) data structure. The last element added to the queue will be the first one to be removed. The C language uses a stack to store local data in a function. The stack is also used when implementing calculators.
Option Strict On

Imports System.Collections.Generic

Module Example

Sub Main()

Dim stc As New Stack(Of Integer)

stc.Push(1)
stc.Push(4)
stc.Push(3)
stc.Push(6)
stc.Push(4)

Console.WriteLine(stc.Pop())
Console.WriteLine(stc.Peek())
Console.WriteLine(stc.Peek())

Console.WriteLine()

For Each item As Integer In stc
Console.WriteLine(item)
Next

End Sub

End Module
We have a simple stack example above.
Dim stc As New Stack(Of Integer)
A Stack data structure is created.
stc.Push(1)
stc.Push(4)
...
The Push() method adds an item at the top of the stack.
Console.WriteLine(stc.Pop())
The Pop() method removes and returns the item from the top of the stack.
Console.WriteLine(stc.Peek())
The Peek() method returns the item from the top of the stack. It does not remove it.
$ ./stack.exe 
4
6
6

6
3
4
1
Output.
This part of the Visual Basic tutorial was dedicated to Collections in Visual Basic.
Continue Reading

Object-oriented Visual Basic tutorial

Object-oriented programming II

In this chapter of the Visual Basic tutorial, we continue description of the OOP in the Visual Basic language.

Interfaces

A remote control is an interface between the viewer and the TV. It is an interface to this electronic device. Diplomatic protocol guides all activities in the diplomatic field. Rules of the road are rules that motorists, cyclists and pedestrians must follow. Interfaces in programming are analogous to the previous examples.
Interfaces are:
  • APIs
  • Contracts
Objects interact with the outside world with the methods, they expose. The actual implementation is not important to the programmer, or it also might be secret. A company might sell a library and it does not want to disclose the actual implementation. A programmer might call a Maximize method on a window of a GUI toolkit, but knows nothing about how this method is implemented. From this point of view, interfaces are methods, through which objects interact with the outside world, without exposing too much about their inner workings.
From the second point of view, interfaces are contracts. If agreed upon, they must be followed. They are used to design an architecture of an application. They help organize the code.
Interfaces are fully abstract types. They are declared using the Interface keyword. Interfaces can only have method signatures and constants. All method signatures declared in an interface must be public. They cannot have fully implemented methods, nor member fields. A Visual Basic class may implement any number of interfaces. An interface can also extend any number of interfaces. A class that implements an interface must implement all method signatures of an interface.
Interfaces are used to simulate multiple inheritance. A Visual Basic class can inherit only from one class. A Visual Basic class can implement multiple interfaces. Multiple inheritance using the interfaces is not about inheriting methods and variables. It is about inheriting ideas or contracts, which are described by the interfaces.
There is one important distinction between interfaces and abstract classes. Abstract classes provide partial implementation for classes, that are related in the inheritance hierarchy. Interfaces on the other hand can be implemented by classes, that are not related to each other. For example, we have two buttons. A classic button and a round button. Both inherit from an abstract button class, that provides some common functionality to all buttons. Implementing classes are related, since all are buttons. Another example might have classes Database and SignIn. They are not related to each other. We can apply an ILoggable interface, that would force them to create a method to do logging.
Option Strict On


Module Example

Interface IInfo

Sub DoInform()

End Interface

Class Some
Implements IInfo

Sub DoInform() Implements IInfo.DoInform
Console.WriteLine("This is Some Class")
End Sub

End Class

Sub Main()

Dim sm As New Some
sm.DoInform()

End Sub

End Module
This is a simple Visual Basic program demonstrating an interface.
Interface IInfo
Sub DoInform()
End Interface
This is an interface IInfo. It has the DoInform() method signature.
Class Some
Implements IInfo
We use the Implements to implement from an interface.
Sub DoInform() Implements IInfo.DoInform
Console.WriteLine("This is Some Class")
End Sub
The class provides an implementation for the DoInform() method. The Implements keyword explicitly specifies which method signature we are implementing.

The next example shows, how a class can implement multiple interfaces.
Option Strict On


Module Example

Interface Device

Sub SwitchOn()
Sub SwitchOff()

End Interface

Interface Volume

Sub VolumeUp()
Sub VolumeDown()

End Interface

Interface Pluggable

Sub PlugIn()
Sub PlugOff()

End Interface

Class CellPhone
Implements Device, Volume, Pluggable

Public Sub SwitchOn() Implements Device.SwitchOn
Console.WriteLine("Switching on")
End Sub

Public Sub SwitchOff() Implements Device.SwitchOff
Console.WriteLine("Switching on")
End Sub

Public Sub VolumeUp() Implements Volume.VolumeUp
Console.WriteLine("Volume up")
End Sub

Public Sub VolumeDown() Implements Volume.VolumeDown
Console.WriteLine("Volume down")
End Sub

Public Sub PlugIn() Implements Pluggable.PlugIn
Console.WriteLine("Plugging In")
End Sub

Public Sub PlugOff() Implements Pluggable.PlugOff
Console.WriteLine("Plugging Off")
End Sub

End Class

Sub Main()

Dim o As New CellPhone
o.SwitchOn()
o.VolumeUp()
o.PlugIn()

End Sub

End Module
We have a CellPhone class that inherits from three interfaces.
Class CellPhone
Implements Device, Volume, Pluggable
The class implements all three interfaces, which are divided by a comma. The CellPhone class must implement all method signatures from all three interfaces.
$ ./interface.exe 
Switching on
Volume up
Plugging In
Running the program.

The next example shows how interfaces can inherit from multiple other interfaces.
Option Strict On


Module Example

Interface IInfo

Sub DoInform()

End Interface

Interface IVersion

Sub GetVersion()

End Interface

Interface ILog
Inherits IInfo, IVersion

Sub DoLog

End Interface

Class DBConnect
Implements ILog

Public Sub DoInform() Implements IInfo.DoInform
Console.WriteLine("This is DBConnect class")
End Sub

Public Sub GetVersion() Implements IVersion.GetVersion
Console.WriteLine("Version 1.02")
End Sub

Public Sub DoLog() Implements ILog.DoLog
Console.WriteLine("Logging")
End Sub

Public Sub Connect()
Console.WriteLine("Connecting to the database")
End Sub

End Class

Sub Main()

Dim db As New DBConnect
db.DoInform()
db.GetVersion()
db.DoLog()
db.Connect()

End Sub

End Module
We define three interfaces. We can organize interfaces in hierarchy.
Interface ILog
Inherits IInfo, IVersion
The ILog interface inherits from two other interfaces.
Public Sub DoInform() Implements IInfo.DoInform
Console.WriteLine("This is DBConnect class")
End Sub
The DBConnect class implements the DoInform() method. This method was inherited by the ILog interface, which the class implements.
$ ./interface2.exe 
This is DBConnect class
Version 1.02
Logging
Connecting to the database
Output.

Polymorphism

The polymorphism is the process of using an operator or function in different ways for different data input. In practical terms, polymorphism means that if class B inherits from class A, it doesn't have to inherit everything about class A; it can do some of the things that class A does differently. (wikipedia)
In general, polymorphism is the ability to appear in different forms. Technically, it is the ability to redefine methods for derived classes. Polymorphism is concerned with the application of specific implementations to an interface or a more generic base class.
Polymorphism is the ability to redefine methods for derived classes.
Option Strict On


Module Example

MustInherit Class Shape

Protected x As Integer
Protected y As Integer

Public MustOverride Function Area() As Integer

End Class

Class Rectangle
Inherits Shape

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

Public Overrides Function Area() As Integer
Return Me.x * Me.y
End Function

End Class


Class Square
Inherits Shape

Sub New(ByVal x As Integer)
Me.x = x
End Sub

Public Overrides Function Area() As Integer
Return Me.x * Me.x
End Function

End Class

Sub Main()

Dim shapes() As Shape = { New Square(5), _
New Rectangle(9, 4), New Square(12) }

For Each shape As Shape In shapes
Console.WriteLine(shape.Area())
Next

End Sub

End Module
In the above program, we have an abstract Shape class. This class morphs into two descendant classes, Rectangle and Square. Both provide their own implementation of the Area() method. Polymorphism brings flexibility and scalability to the OOP systems.
Public Overrides Function Area() As Integer
Return Me.x * Me.y
End Function
...
Public Overrides Function Area() As Integer
Return Me.x * Me.x
End Function
Rectangle and Square classes have their own implementations of the Area method.
Dim shapes() As Shape = { New Square(5), _
New Rectangle(9, 4), New Square(12) }
We create an array of three Shapes.
For Each shape As Shape In shapes
Console.WriteLine(shape.Area())
Next
We go through each shape and call Area method on it. The compiler calls the correct method for each shape. This is the essence of polymorphism.

NotOverridable, NotInheritable

NotOverridable methods cannot be overridden and NotInheritable classes cannot be inherited from. These keywords are a matter of a design of the application. We should not inherit from some classes and some methods should not be overridden.
Option Strict On


Module Example

Class Base

Public NotOverridable Sub Say()
Console.WriteLine("Base class")
End Sub

End Class

Class Derived
Inherits Base

Public Overrides Sub Say()
Console.WriteLine("Derived class")
End Sub

End Class

Sub Main()

Dim o As Base = New Derived
o.Say()

End Sub

End Module
This program won't compile. We get an error 'Public Overrides Sub Say()' cannot override 'Public NotOverridable Sub Say()' because it is declared 'NotOverridable'.
Option Strict On


Module Example

NotInheritable Class Math

Public Shared Function getPI() As Single
Return 3.141592
End Function

End Class

Class DerivedMath
Inherits Math

Public Sub Say()
Console.WriteLine("DerivedMath class")
End Sub

End Class

Sub Main()

Dim o As DerivedMath = New DerivedMath
o.Say()

End Sub

End Module
In the above program, we have a prototype base Math class. The sole purpose of this class is to provide some helpful methods and constants to the programmer. (In our case we have only one method for simplicity reasons.) It is not created to be inherited from. To prevent uninformed other programmers to derive from this class, the creators made the class NotInheritable. If you try to compile this program, you get the following error: 'DerivedMath' cannot inherit from class 'Math' because 'Math' is declared 'NotInheritable'.

Deep copy vs shallow copy

Copying of data is an important task in programming. Object is a composite data type in OOP. Member field in an object may be stored by value or by reference. Copying may be performed in two ways.
The shallow copy copies all values and references into a new instance. The data to which a reference is pointing is not copied; only the pointer is copied. The new references are pointing to the original objects. Any changes to the reference members affect both objects.
The deep copy copies all values into a new instance. In case of members that are stored as references a deep copy performs a deep copy of data, that is being referenced. A new copy of a referenced object is created. And the pointer to the newly created object is stored. Any changes to those referenced objects will not affect other copies of the object. Deep copies are fully replicated objects.
If a member field is a value type, a bit-by-bit copy of the field is performed. If the field is a reference type, the reference is copied but the referred object is not; therefore, the reference in the original object and the reference in the clone point to the same object. (a clear explanation from programmingcorner.blogspot.com)
The next two examples will perform a shallow and a deep copy on objects.
Option Strict On


Module Example

Class Color

Public red as Byte
Public green as Byte
Public blue as Byte

Sub New(red As Byte, green As Byte, _
blue As Byte)
Me.red = red
Me.green = green
Me.blue = blue
End Sub

End Class

Class MyObject
Implements ICloneable

Public Id As Integer
Public Size As String
Public Col As Color

Sub New(Id As Integer, Size As String, _
Col As Color)
Me.Id = Id
Me.Size = Size
Me.Col = Col
End Sub

Public Function Clone() As Object _
Implements ICloneable.Clone
Return New MyObject(Me.Id, Me.Size, Me.Col)
End Function

Public Overrides Function ToString() As String
Dim s As String
s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _
Me.Id, Me.Size, Me.Col.red, Me.Col.green, Me.Col.blue)
Return s
End Function

End Class

Sub Main()

Dim col As New Color(23, 42, 223)

Dim obj1 As New MyObject(23, "small", col)
Dim obj2 As MyObject

obj2 = CType(obj1.Clone(), MyObject)

obj2.Id += 1
obj2.Size = "big"
obj2.Col.red = 255

Console.WriteLine(obj1)
Console.WriteLine(obj2)

End Sub

End Module
This is an example of a shallow copy. We define two custom objects. MyObject and Color. The MyObject object will have a reference to the Color object.
Class MyObject
Implements ICloneable
We should implement ICloneable interface for objects, which we are going to clone.
Public Function Clone() As Object _
Implements ICloneable.Clone
Return New MyObject(Me.Id, Me.Size, Me.Col)
End Function
The ICloneable interface forces us to create a Clone() method. This method returns a new object with copied values.
Dim col As New Color(23, 42, 223)  
We create an instance of the Color object.
Dim obj1 As New MyObject(23, "small", col)
An instance of the MyObject object is created. It passes the instance of the Color object to its constructor.
obj2 = CType(obj1.Clone(), MyObject)
We create a shallow copy of the obj1 object and assign it to the obj2 variable. The Clone() method returns an Object and we expect MyObject. This is why we do explicit casting.
obj2.Id += 1
obj2.Size = "big"
obj2.Col.red = 255
Here we modify the member fields of the copied object. We increment the Id, change the Size to "big" and change the red part of the color object.
Console.WriteLine(obj1) 
Console.WriteLine(obj2)
The Console.WriteLine() method calls the ToString() method of the obj2 object, which returns the string representation of the object.
Id: 23, Size: small, Color:(255, 42, 223)
Id: 24, Size: big, Color:(255, 42, 223)
We can see, that the Ids are different. 23 vs 24. The Size is different. "small" vs "big". But the red part of the color object is same for both instances. 255. Changing member values of the cloned object (Id, Size) did not affect the original object. Changing members of the referenced object (Col) has affected the original object too. In other words, both objects refer to the same color object in memory.
To change this behaviour, we will do a deep copy next.
Option Strict On


Module Example

Class Color
Implements ICloneable

Public Red as Byte
Public Green as Byte
Public Blue as Byte

Sub New(Red As Byte, Green As Byte, _
Blue As Byte)
Me.Red = Red
Me.Green = Green
Me.Blue = Blue
End Sub

Public Function Clone() As Object _
Implements ICloneable.Clone
Return New Color(Me.Red, Me.Green, Me.Blue)
End Function

End Class

Class MyObject
Implements ICloneable

Public Id As Integer
Public Size As String
Public Col As Color

Sub New(Id As Integer, Size As String, _
Col As Color)
Me.Id = Id
Me.Size = Size
Me.Col = Col
End Sub

Public Function Clone() As Object _
Implements ICloneable.Clone
Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color))
End Function

Public Overrides Function ToString() As String
Dim s As String
s = String.Format("Id: {0}, Size: {1}, Color:({2}, {3}, {4})", _
Me.Id, Me.Size, Me.Col.Red, Me.Col.Green, Me.Col.Blue)
Return s
End Function

End Class

Sub Main()

Dim col As New Color(23, 42, 223)

Dim obj1 As New MyObject(23, "small", col)
Dim obj2 As MyObject

obj2 = CType(obj1.Clone(), MyObject)

obj2.Id += 1
obj2.Size = "big"
obj2.Col.Red = 255

Console.WriteLine(obj1)
Console.WriteLine(obj2)


End Sub

End Module
In this program, we perform a deep copy on object.
Class Color
Implements ICloneable
Now the Color class implements the ICloneableinterface.
Public Function Clone() As Object _
Implements ICloneable.Clone
Return New Color(Me.Red, Me.Green, Me.Blue)
End Function
We have a Clone() method for the Color class too. This helps to create a copy of a referenced object.
Public Function Clone() As Object _
Implements ICloneable.Clone
Return New MyObject(Me.Id, Me.Size, CType(Me.Col.Clone(), Color))
End Function
Now, when we clone the MyObject, we call the Clone()method upon the Col reference type. This way we have a copy of a color value too.
$ ./deepcopy.exe 
Id: 23, Size: small, Color:(23, 42, 223)
Id: 24, Size: big, Color:(255, 42, 223)
Now the red part of the referenced Color object is not the same. The original object has retained its previous 23 value.

Exceptions

Exceptions are designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution. Exceptions are raised or thrown, initiated.
During the execution of our application, many things might go wrong. A disk might get full and we cannot save our file. An Internet connection might go down and our application tries to connect to a site. All these might result in a crash of our application. To prevent happening this, we must cope with all possible errors that might occur. For this, we can use the exception handling.
The Try, Catch and Finally keywords are used to work with exceptions.
Option Strict On

Module Example

Sub Main()

Dim x As Integer = 100
Dim y As Integer = 0
Dim z As Double

Try
z = x \ y
Catch e As Exception
Console.WriteLine(e.Message)
End Try

End Sub

End Module
In the above program, we intentionally divide a number by zero. This leads to an error.
Try 
z = x \ y
...
End Try
Statements that are error prone are placed after the Trykeyword.
Catch e As Exception
Console.WriteLine(e.Message)
...
Exception types follow the Catchkeyword. In our case we have a generic Exception which will catch an exception of any type. There are some generic exceptions and some more specific. Statements that follow the Catch keyword are executed, when an error occurs. When an exception occurs, an exception object is created. From this object we get the Message property and print it to the console.

Any uncaught exception in the current context propagates to a higher context and looks for an appropriate catch block to handle it. If it can't find any suitable catch blocks, the default mechanism of the .NET runtime will terminate the execution of the entire program.
Option Strict On

Module Example

Sub Main()

Dim z As Double
Dim x As Integer = 100
Dim y As Integer = 0

z = x \ y

End Sub

End Module
In this program, we divide by zero. We have no custom exception handling. On Visual Basic 2008 Express we receive the following error message: 'Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.'.

Option Strict On

Imports System.IO

Module Example

Dim fs As FileStream

Sub Main()

Try
fs = File.Open("file", FileMode.OpenOrCreate)
Console.WriteLine(fs.Length)
Catch e As IOException
Console.WriteLine("IO Error")
Console.WriteLine(e.Message)
Finally
Console.WriteLine("Finally")
If fs.CanRead = True Then
fs.Close()
End If
End Try

End Sub

End Module
The statements following the Finally keyword are always executed. It is often used to clean-up tasks, such as closing files or clearing buffers.
Catch e As IOException
Console.WriteLine("IO Error")
Console.WriteLine(e.Message)
In this case, we catch for a specific IOException exception.
Finally
Console.WriteLine("Finally")
If fs.CanRead = True Then
fs.Close()
End If
These lines guarantee that the file handler is closed.

Option Strict On

Module Example

Sub Main()

Dim x As Integer
Dim y As Integer
Dim z As Double

Try
Console.Write("Enter first number: ")
x = Convert.ToInt32(Console.ReadLine())

Console.Write("Enter second number: ")
y = Convert.ToInt32(Console.ReadLine())

z = x / y
Console.WriteLine("Result: {0:D} / {1:D} = {2:D}", x, y, z)

Catch e As DivideByZeroException
Console.WriteLine("Cannot divide by zero.")
Catch e As FormatException
Console.WriteLine("Wrong format of number.")
Catch e As Exception
Console.WriteLine(e.Message)
End Try

End Sub

End Module
In this example, we catch for various exceptions. Note that more specific exceptions should precede the generic ones. We read two numbers from the console and check for zero division error and for wrong format of number.
$ ./passing.exe 
Enter first number: et
Wrong format of number.
Running the example.

Option Strict On

Module Example

Class BigValueException
Inherits Exception

Sub New(ByVal msg As String)
MyBase.New(msg)
End Sub

End Class

Sub Main()

Dim x As Integer = 340004
Const LIMIT As Integer = 333

Try
If (x > LIMIT) Then
Throw New BigValueException("Exceeded the maximum value")
End If
Catch e As BigValueException
Console.WriteLine(e.Message)
End Try

End Sub

End Module
Let's say, we have a situation in which we cannot deal with big numbers.
Class BigValueException
Inherits Exception
We have a BigValueException class. This class derives from the built-in Exception class.
Dim Const LIMIT As Integer = 333 
Numbers bigger than this constant are considered to be "big" by our program.
Sub New(ByVal msg As String)
MyBase.New(msg)
End Sub
Inside the constructor, we call the parent's constructor. We pass the message to the parent.
If (x > LIMIT) Then
Throw New BigValueException("Exceeded the maximum value")
End If
If the value is bigger than the limit, we throw our custom exception. We give the exception a message "Exceeded the maximum value".
Catch e As BigValueException
Console.WriteLine(e.Message)
We catch the exception and print its message to the console.

Properties

Properties are special kind of class members. We use predefined set and get methods to access and modify them. Property reads and writes are translated to get and set method calls. Accessing variables with a field notation (e.g. object.Name) is easier than with custom method calls.(e.g. object.GetName()). However with properties, we still have the advantage of encapsulation and information hiding.
Option Strict On


Module Example

Class Person

Private _name As String

Public Property Name() As String
Get
Return _name
End Get

Set (Byval Value As String)
_name = Value
End Set
End Property

End Class

Sub Main()

Dim p as New Person
p.Name = "Jane"

Console.WriteLine(p.Name())

End Sub

End Module
We have a simple Person class with one property.
Public Property Name() As String
...
End Property
We use the Property keyword to create properties in Visual Basic.
Get
Return _name
End Get
We use the predefined Get keyword to create an accessor method to the _name field.
Set (Byval Value As String)
_name = Value
End Set
Similarly, the Set keyword creates a mutator method for the _name field.
Dim p as New Person
p.Name = "Jane"

Console.WriteLine(p.Name())
We create an instance of the Person class. We access the member field using the field notation.
$ ./properties.exe 
Jane
This is the outcome of the program.

Delegates

A delegate is a form of type-safe function pointer used by the .NET Framework. Delegates are often used to implement callbacks and event listeners.
Option Strict On


Module Example

Public Delegate Sub NameDelegate(ByVal msg As String)

Class Person

Private FirstName As String
Private SecondName As String

Sub New(First As String, Second As String)
Me.FirstName = First
Me.SecondName = Second
End Sub

Public Sub ShowFirstName(msg As String)
Console.WriteLine(msg & Me.FirstName)
End Sub

Public Sub ShowSecondName(msg As String)
Console.WriteLine(msg & Me.SecondName)
End Sub

End Class

Sub Main()

Dim nDelegate As NameDelegate

Dim per As New Person("Fabius", "Maximus")

nDelegate = AddressOf per.ShowFirstName
nDelegate("Call 1: ")

nDelegate = AddressOf per.ShowSecondName
nDelegate("Call 2: ")

End Sub

End Module
In the example we have one delegate. This delegate is used to point to two methods of the Person class. The methods are called with the delegate.
Public Delegate Sub NameDelegate(ByVal msg As String)
The delegate is created with a Delegate keyword. The delegate signature must match the signature of the method being called with the delegate.
Dim nDelegate As NameDelegate
Here we create a variable of our custom delegate type.
nDelegate = AddressOf per.ShowFirstName
nDelegate("Call 1: ")
The AddressOf operator is used to get the reference to the ShowFirstName() method. Now that we point to the method, we can call it via the delegate.
$ ./simpledelegate.exe 
Call 1: Fabius
Call 2: Maximus
Both names are printed via the delegate.

Events

Events are messages triggered by some action. Click on the button or tick of a clock are such actions. The object that triggers an event is called a sender and the object that receives the event is called a receiver.
Option Strict On


Module Example

Public Event ValueFive()

Dim Random As Integer

Public Sub Main()

AddHandler ValueFive, AddressOf OnFiveEvent

For i As Integer = 0 To 10

Randomize()
Random = CInt(Rnd() * 7)

Console.WriteLine(Random)

If Random = 5 Then
RaiseEvent ValueFive()
End If
Next

End Sub

Public Sub OnFiveEvent()
Console.WriteLine("Five Event occured")
End Sub

End Module
We have a simple example in which we create and launch an event. An random number is generated. If the number equals to 5 a FiveEvent event is generated.
Public Event ValueFive() 
An event is declared with a Event keyword.
AddHandler ValueFive, AddressOf OnFiveEvent
Here we plug the event called ValueFive() to the OnFiveEvent() subroutine. In other words, if the ValueFive event is triggered, the OnFiveEvent() subroutine is executed.
If Random = 5 Then
RaiseEvent ValueFive()
End If
When the random number equals to 5, we raise the ValueFive event. We use the RaiseEvent keyword.
$ ./event.exe 
0
1
5
Five Event occured
2
5
Five Event occured
6
7
6
3
3
1
Outcome of the program might look like this.

Next we have a more complex example.
Option Strict On


Namespace EventSample

Public Class FiveEventArgs
Inherits EventArgs

Public Count As Integer
Public Time As Date

Public Sub New(ByVal Count As Integer, ByVal Time As Date)
Me.Count = Count
Me.Time = Time
End Sub

End Class

Public Class Five

Private Count As Integer = 0

Public Sub OnFiveEvent(ByVal source As Object, _
ByVal e As FiveEventArgs)
Console.WriteLine("Five event {0} occured at {1}", _
e.Count, e.Time)
End Sub

End Class

Public Class RandomGenerator

Public Event ValueFive(ByVal source As Object, _
ByVal e As FiveEventArgs)

Public Sub Generate()

Dim Count As Integer = 0
Dim args As FiveEventArgs

For i As Byte = 0 To 10
Dim Random As Integer

Randomize()
Random = CInt(Rnd * 6)
Console.WriteLine(Random)

If Random = 5 Then
Count += 1
args = New FiveEventArgs(Count, Now)
RaiseEvent ValueFive(Me, args)
End If
Next
End Sub

End Class

Public Class Example

Public Shared Sub Main()

Dim five As New Five
Dim gen As New RandomGenerator

AddHandler gen.ValueFive, AddressOf five.OnFiveEvent

gen.Generate()

End Sub

End Class

End Namespace
We have four classes. FiveEventArgs carries some data with the event object. The Five class encapsulates the event object. RandomGenerator class is responsible for random number generation. It is the event sender. Finally the Example class, which is the main application object and has the Main() method.
Public Class FiveEventArgs
Inherits EventArgs

Public Count As Integer
Public Time As Date
...
The FiveEventArgs carries data inside the event object. It inherits from the EventArgs base class. The Count and Time members are data that will be initialized and carried with the event.
If Random = 5 Then
Count += 1
args = New FiveEventArgs(Count, Now)
RaiseEvent ValueFive(Me, args)
End If
If the generated random number equals to 5, we instantiate the FiveEventArgs class with the current Count and Date values. The Count variable counts the number of times this event was generated. The Time value holds the time, when the event was generated. The event is sent with the RaiseEvent keyword with the sender object and event arguments.
AddHandler gen.ValueFive, AddressOf five.OnFiveEvent
We plug the ValueFive event to its handler.
$ ./event2.exe 
3
6
5
Five event 1 occured at 9/15/2010 5:06:13 PM
3
5
Five event 2 occured at 9/15/2010 5:06:13 PM
6
3
2
5
Five event 3 occured at 9/15/2010 5:06:13 PM
2
5
Five event 4 occured at 9/15/2010 5:06:13 PM
This is the ouput I got on my computer.
In this part of the Visual Basic tutorial, we continued the discussion of the object-oriented programming in Visual Basic.
Continue Reading

Object-oriented programming in Visual Basic

Object-oriented programming

In this part of the Visual Basic tutorial, we will talk about object oriented programming in Visual Basic.
There are three widely used programming paradigms there. Procedural programming, functional programming and object-oriented programming. Visual Basic supports both procedural and object-oriented programming.
Object-oriented programming (OOP) is a programming paradigm that uses objects and their interactions to design applications and computer programs. (Wikipedia)
There are some basic programming concepts in OOP:
  • Abstraction
  • Polymorphism
  • Encapsulation
  • Inheritance
The abstraction is simplifying complex reality by modeling classes appropriate to the problem. The polymorphism is the process of using an operator or function in different ways for different data input. The encapsulation hides the implementation details of a class from other objects. The inheritance is a way to form new classes using classes that have already been defined.

Objects

Objects are basic building blocks of a Visual Basic OOP program. An object is a combination of data and methods. In a OOP program, we create objects. These objects communicate together through methods. Each object can receive messages, send messages and process data.
There are two steps in creating an object. First, we create a class. A class is a template for an object. It is a blueprint, which describes the state and behavior that the objects of the class all share. A class can be used to create many objects. Objects created at runtime from a class are called instances of that particular class.
Option Strict On


Module Example

Class Being

End Class

Sub Main()

Dim b as New Being
Console.WriteLine(b.ToString())

End Sub

End Module
In our first example, we create a simple object.
Class Being

End Class
This is a simple class definition. The body of the template is empty. It does not have any data or methods.
Dim b as New Being
We create a new instance of the Being class. For this we have the Newkeyword. The b variable is the handle to the created object.
Console.WriteLine(b.ToString())
The ToString() method of the object gives some basic description of the object.
$ ./object.exe 
Example+Being
We don't get much info, since the class definition was empty. We get the object class name and the module name, where the instance of this object was created.

Object attributes

Object attributes is the data bundled in an instance of a class. The object attributes are called instance variables or member fields. An instance variable is a variable defined in a class, for which each object in the class has a separate copy.
Option Strict On


Module Example

Class Person

Public Name As String

End Class

Sub Main()

Dim p1 as New Person
p1.Name = "Jane"

Dim p2 as New Person
p2.Name = "Beky"

Console.WriteLine(p1.Name)
Console.WriteLine(p2.Name)

End Sub

End Module
In the above Visual Basic code, we have a Person class with one member field.
Class Person
Public Name As String
End Class
We declare a Name member field. The Publickeyword specifies, that the member field will be accessible outside the Class/End Class block.
Dim p1 as New Person
p1.Name = "Jane"
We create an instance of the Person class. And set the Name variable to "Jane". We use the dot operator to access the attributes of objects.
Dim p2 as New Person
p2.Name = "Beky"
We create another instance of the Person class. Here we set the variable to "Beky".
Console.WriteLine(p1.Name)
Console.WriteLine(p2.Name)
We print the contents of the variables to the console.
$ ./person.exe 
Jane
Beky
We see the output of the program. Each instance of the Person class has a separate copy of the Name member field.

Methods

Methods are functions/procedures defined inside the body of a class. They are used to perform operations with the attributes of our objects. Methods are essential in encapsulation concept of the OOP paradigm. For example, we might have a Connect method in our AccessDatabase class. We need not to be informed, how exactly the method Connect connects to the database. We only know, that it is used to connect to a database. This is essential in dividing responsibilities in programming. Especially in large applications.
Option Strict On


Module Example

Class Circle

Public Radius As Integer

Public Sub SetRadius(ByVal Radius As Integer)
Me.Radius = Radius
End Sub

Public Function Area() As Double
Return Me.Radius * Me.Radius * Math.PI
End Function

End Class

Sub Main()

Dim c As New Circle
c.SetRadius(5)

Console.WriteLine(c.Area())

End Sub

End Module
In the code example, we have a Circle class. We define two methods.
Public Radius As Integer
We have one member field. It is the Radius of the circle. The Publickeyword is an access specifier. It tells that the variable is fully accessible from the outside world.
Public Sub SetRadius(ByVal Radius As Integer)
Me.Radius = Radius
End Sub
This is the SetRadius() method. It is a normal Visual Basic procedure. The Me variable is a special variable, which we use to access the member fields from methods.
Public Function Area() As Double
Return Me.Radius * Me.Radius * Math.PI
End Function
The Area() method returns the area of a circle. The Math.PI is a built-in constant.
$ ./circle.exe 
78.5398163397448
Running the example.

Access modifiers

Access modifiers set the visibility of methods and member fields. Visual Basic has five access modifiers. Public, Protected, Private, Friendand ProtectedFriend. Public members can be accessed from anywhere. Protected members can be accessed only within the class itself and by inherited and parent classes. Friend members may be accessed from within the same assembly (exe or dll). ProtectedFriend is a union of protected and friend modifiers.
Access modifiers protect data against accidental modifications. They make the programs more robust.
Option Strict On


Module Example

Class Person

Public Name As String
Private Age As Byte

Public Function GetAge() As Byte
Return Me.Age
End Function

Public Sub SetAge(ByVal Age As Byte)
Me.Age = Age
End Sub

End Class

Sub Main()

Dim p as New Person
p.Name = "Jane"

p.setAge(17)

Console.WriteLine("{0} is {1} years old", _
p.Name, p.GetAge)

End Sub

End Module
In the above program, we have two member fields. One is declared Public, the other Private.
Public Function GetAge() As Byte
Return Me.Age
End Function
If a member field is Private, the only way to access it is via methods. If we want to modify an attribute outside the class, the method must be declared Public. This is an important aspect of data protection.
Public Sub SetAge(ByVal Age As Byte)
Me.Age = Age
End Sub
The SetAge() method enables us to change the Private Age variable from outside of the class definition.
Dim p as New Person
p.Name = "Jane"
We create a new instance of the Person class. Because the Name attribute is Public, we can access it directly. However, this is not recommended.
p.setAge(17)
The SetAge() method modifies the Age member field. It cannot be accessed or modified directly, because it is declared Private.
Console.WriteLine("{0} is {1} years old", _
p.Name, p.GetAge)
Finally, we access both members to build a string.
$ ./modifiers.exe 
Jane is 17 years old
Running the example.

Option Strict On


Module Example

Class Base

Public Name As String = "Base"
Protected Id As Integer = 5323
Private IsDefined As Boolean = True

End Class

Class Derived
Inherits Base

Public Sub Info()
Console.WriteLine("This is Derived Class")
Console.WriteLine("Members inherited:")
Console.WriteLine(Me.Name)
Console.WriteLine(Me.Id)
'Console.WriteLine(Me.IsDefined)
End Sub

End Class

Sub Main()

Dim drv As Derived = New Derived
drv.Info()

End Sub

End Module
In the preceding program, we have a Derived class, which inherits from the Base class. The Base class has three member fields. All with different access modifiers. The IsDefined member is not inherited. The Privatemodifier prevents this.
Class Derived 
Inherits Base
The class Derived inherits from the Base class.
Console.WriteLine(Me.Name)
Console.WriteLine(Me.Id)
'Console.WriteLine(Me.IsDefined)
The Public and the Protected members are inherited by the Derived class. They can be accessed. The Private member is not inherited. The line accessing the member field is commented. If we uncommented the line, it would not compile.
$ ./protected.exe 
This is Derived Class
Members inherited:
Base
5323
Running the program, we receive this output. The Public and Protected members are inherited, the Private member is not.

Method overloading

Method overloading allows the creation of several methods with the same name which differ from each other in the type of the input.
What is method overloading good for? The Qt4 library gives a nice example for the usage. The QPainter class has three methods to draw a rectangle. Their name is drawRect() and their parameters differ. One takes a reference to a floating point rectangle object, another takes a reference to an integer rectangle object and the last one takes four parameters, x, y, width, height. If the C++ language, which is the language in which Qt is developed, didn't have method overloading, the creators of the library would have to name the methods like drawRectRectF(), drawRectRect(), drawRectXYWH(). The solution with method overloading is more elegant.
Option Strict On


Module Example

Class Sum

Public Function GetSum() As Integer
Return 0
End Function

Public Function GetSum(ByVal x As Integer) As Integer
Return x
End Function

Public Function GetSum(ByVal x As Integer, _
ByVal y As Integer) As Integer
Return x + y
End Function

End Class

Sub Main()

Dim s As Sum = New Sum

Console.WriteLine(s.getSum())
Console.WriteLine(s.getSum(20))
Console.WriteLine(s.getSum(20, 30))

End Sub

End Module
We have three methods called GetSum(). They differ in input parameters.
Public Function GetSum(ByVal x As Integer) As Integer
Return x
End Function
This one takes one parameter.
Console.WriteLine(s.getSum())
Console.WriteLine(s.getSum(20))
Console.WriteLine(s.getSum(20, 30))
We call all three methods.
$ ./overloading.exe 
0
20
50
And this is what we get, when we run the example.

The constructor

A constructor is a special kind of a method. It is automatically called, when the object is created. The purpose of the constructor is to initiate the state of the object. The name of the constructor in Visual Basic is New. The constructors are methods, so they can be overloaded too.
Option Strict On


Module Example

Class Being

Sub New()
Console.WriteLine("Being is being created")
End Sub

Sub New(ByVal name As String)
Console.WriteLine("Being {0} is created", name)
End Sub

End Class

Sub Main()

Dim b As New Being
Dim t As New Being("Tom")

End Sub

End Module
We have a Being class. This class has two constructors. The first one does not take parameters, the second one takes one parameter.
Sub New(ByVal name As String)
Console.WriteLine("Being {0} is created", name)
End Sub
This constructor takes one String parameter.
Dim b As New Being
An instance of the Being class is created. This time the constructor without a parameter is called upon object creation.
$ ./constructor.exe 
Being is being created
Being Tom is created
This is the output of the program.

In the next example, we initiate data members of the class. Initiation of variables is a typical job for constructors.
Option Strict On


Module Example

Class MyFriend

Private Born As Date
Private Name As String

Sub New(ByVal Name As String, ByVal Born As Date)
Me.Name = Name
Me.Born = Born
End Sub

Public Sub GetInfo()
Console.WriteLine("{0} was born on {1}", _
Me.Name, Me.Born.ToShortDateString)
End Sub

End Class

Sub Main()

Dim name As String = "Lenka"
Dim born As Date = #5/3/1990#

Dim fr As MyFriend = New MyFriend(name, born)
fr.GetInfo()

End Sub

End Module
We have a Friend class with data members and methods.
Private Born As Date
Private Name As String
We have two variables in the class definition. The Private keyword is an access modifier. It is a form of encapsulation. The Private keyword is the most restrictive modifier. It allows only the object in question to access the variable. No descendants, no other objects.
Sub New(ByVal Name As String, ByVal Born As Date)
Me.Name = Name
Me.Born = Born
End Sub
In the constructor, we initiate the two data members. The Me variable is a handler used to reference the object variables.
Dim fr As MyFriend = New MyFriend(name, born)
fr.GetInfo()
We create a Friend object with two arguments. Then we call the GetInfo() method of the object.
./constructor2.exe 
Lenka was born on 5/3/1990

Class constants

Visual Basic enables to create class constants. These constants do not belong to a concrete object. They belong to the class. By convention, constants are written in uppercase letters.
Option Strict On


Module Example

Class Math

Public Const PI As Double = 3.14159265359

End Class

Sub Main()
Console.WriteLine(Math.PI)
End Sub

End Module
We have a Math class with a PI constant.
Public Const PI As Double = 3.14159265359
The Const keyword is used to define a constant.
$ ./classconstant.exe 
3.14159265359
Running the example.

The ToString() method

Each object has a ToString() method. It returns a human-readable representation of the object. The default implementation returns the fully qualified name of the type of the Object. Note that when we call the Console.WriteLine() method with an object as a parameter, the ToString() is being called.
Option Strict On


Module Example

Class Being

Public Overrides Function ToString As String
Return "This is Being Class"
End Function

End Class

Sub Main()

Dim b as New Being
Dim o As New Object

Console.WriteLine(o.ToString())
Console.WriteLine(b.ToString())
Console.WriteLine(b)

End Sub

End Module
We have a Being class in which we override the default implementation of the ToString() method.
Public Overrides Function ToString As String    
Return "This is Being Class"
End Function
Each class created inherits from the base Object. The ToString() method belongs to this Object class. We use the Overrides keyword to inform, that we are overriding a method.
Dim b as New Being
Dim o As New Object
We create two objects. One custom defined and one built-in.
Console.WriteLine(o.ToString())
Console.WriteLine(b.ToString())
We call the ToString() method on these two objects.
Console.WriteLine(b) 
As we have specified earlier, calling the Console.WriteLine()on the object will call its ToString() method.
$ ./override.exe 
System.Object
This is Being Class
This is Being Class
This is what we get, when we run the script.

Inheritance

The inheritance is a way to form new classes using classes that have already been defined. The newly formed classes are called derived classes, the classes that we derive from are called base classes. Important benefits of inheritance are code reuse and reduction of complexity of a program. The derived classes (descendants) override or extend the functionality of base classes (ancestors).
Option Strict On


Module Example

Class Being
Sub New()
Console.WriteLine("Being is created")
End Sub
End Class

Class Human
Inherits Being

Sub New()
Console.WriteLine("Human is created")
End Sub

End Class

Sub Main()

Dim h As New Human

End Sub

End Module
In this program, we have two classes. A base Being class and a derived Human class. The derived class inherits from the base class.
Class Human 
Inherits Being
In Visual Basic, we use the Inherits keyword to create inheritance relations.
Dim h As New Human
We instantiate the derived Human class.
$ ./inheritance.exe 
Being is created
Human is created
We can see, that both constructors were called. First, the constructor of the base class is called, then the constructor of the derived class.

A more complex example follows.
Option Strict On


Module Example

Class Being

Dim Shared Count As Integer = 0

Sub New()
Count = Count + 1
Console.WriteLine("Being is created")
End Sub

Sub GetCount()
Console.WriteLine("There are {0} Beings", Count)
End Sub

End Class

Class Human
Inherits Being

Sub New()
Console.WriteLine("Human is created")
End Sub

End Class

Class Animal
Inherits Being

Sub New
Console.WriteLine("Animal is created")
End Sub

End Class

Class Dog
Inherits Animal

Sub New()
Console.WriteLine("Dog is created")
End Sub

End Class


Sub Main()

Dim h As New Human
Dim d As New Dog
d.GetCount()

End Sub

End Module
We have four classes. The inheritance hierarchy is more complicated. The Human and the Animal classes inherit from the Being class. And the Dog class inherits directly from the Animal class and indirectly from the Being class. We also introduce a concept of a Shared variable.
Dim Shared Count As Integer = 0
We define a Shared variable. Shared members are members, that are shared by all instances of a class. In other programming languages, they are called static members.
Sub New()
Count = Count + 1
Console.WriteLine("Being is created")
End Sub
Each time the Being class is instantiated, we increase the Count variable by one. This way we keep track of the number of instances created.
Class Animal 
Inherits Being
...
Class Dog
Inherits Animal
...
The Animal inherits from the Being and the Dog inherits from the Animal. Indirectly, the Dog inherits from the Being as well.
Dim h As New Human
Dim d As New Dog
d.GetCount
We create instances from the Human and from the Dog classes. We call the GetCount() method of the Dog object.
$ ./inheritance2.exe 
Being is created
Human is created
Being is created
Animal is created
Dog is created
There are 2 Beings
The Human object calls two constructors. The Dog object calls three constructors. There are two Beings instantiated.

Abstract classes and methods

Abstract classes cannot be instantiated. If a class contains at least one abstract method, it must be declared abstract too. Abstract methods cannot be implemented, they merely declare the methods' signatures. When we inherit from an abstract class, all abstract methods must be implemented by the derived class. Furthermore, these methods must be declared with the same of less restricted visibility.
Unlike Interfaces, abstract classes may have methods with full implementation and may also have defined member fields. So abstract classes may provide a partial implementation. Programmers often put some common functionality into abstract classes. And these abstract classes are later subclassed to provide more specific implementation. For example, the Qt graphics library has a QAbstractButton, which is the abstract base class of button widgets, providing functionality common to buttons. Buttons Q3Button, QCheckBox, QPushButton, QRadioButton, and QToolButton inherit from this base abstract class.
Formally put, abstract classes are used to enforce a protocol. A protocol is a set of operations, which all implementing objects must support.
Option Strict On


Module Example

MustInherit Class Drawing
Protected x As Integer = 0
Protected y As Integer = 0

Public MustOverride Function Area() As Double

Public Function GetCoordinates() As String
Return String.Format("x: {0}, y: {1}", _
Me.x, Me.y)
End Function

End Class

Class Circle
Inherits Drawing

Private Radius As Integer

Sub New(ByVal x As Integer, ByVal y As Integer, _
ByVal r As Integer)
Me.x = x
Me.y = y
Me.Radius = r
End Sub

Public Overrides Function Area() As Double
Return Me.Radius * Me.Radius * Math.PI
End Function

Public Overrides Function ToString() As String
Return String.Format("Circle, at x: {0}, y: {1}, radius: {2}", _
Me.x, Me.y, Me.Radius)
End Function

End Class

Sub Main()

Dim c as New Circle(12, 45, 22)

Console.WriteLine(c)
Console.WriteLine("Area of circle: {0}", c.Area())
Console.WriteLine(c.GetCoordinates())

End Sub

End Module

We have an abstract base Drawing class. The class defines two member fields, defines one method and declares one method. One of the methods is abstract, the other one is fully implemented. The Drawing class is abstract, because we cannot draw it. We can draw a circle, a dot or a square. The Drawing class has some common functionality to the objects, that we can draw.
MustInherit Class Drawing
In Visual Basic, we use the MustInherit keyword to define an abstract class.
Public MustOverride Function Area() As Double
An abstract method is preceded with a MustOverride keyword.
Class Circle  
Inherits Drawing
A Circle is a subclass of the Drawing class. It must implement the abstract Area() method.
$ ./abstractclass.exe 
Circle, at x: 12, y: 45, radius: 22
Area of circle: 1520.53084433746
x: 12, y: 45
Output of the program.
This was the first part of the description of OOP in Visual Basic.
Continue Reading