467,915 Members | 1,201 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,915 developers. It's quick & easy.

Basic OOP Collections Question

Hello,

I'm trying to get a better handle on OOP programming principles in VB.NET.
Forgive me if this question is sort of basic, but here's what I want to do.
I have a collection of Employee objects that I can iterate through
relatively easily. I've included code at the bottom of this message.

I can pretty easily iterate through my employee objects like so:

Dim theEmployees As Employees = New Employees

For Each Emp As Employee In theEmployees
Response.Write(Emp.Name & ": " & FormatCurrency(Emp.Salary, 2) & "<br
/>")
Next

My question is, let's say I want to create a new method...GetRichEmployees,
which returns a set of employee objects whose salary is >= 100,000. How
would I implement this? I know it's basic, but the answer to this will
probably help me solidify some of the more basic OOP priniciples in my head.
Still learning here, thanks!

Scott

Imports Microsoft.VisualBasic
Imports System.Data.SqlClient
Imports Microsoft.ApplicationBlocks.Data

Public Class Employee
Private sName As String
Private dSalary As Double

Public Property Name() As String
...
Public Property Salary() As String
...

Public Sub New()
sName = ""
dSalary = 0
End Sub

Public Sub New(ByVal sn As String, ByVal ds As Double)
...
End Sub

Public Sub Save()
SqlHelper.ExecuteNonQuery(ConfigurationManager.App Settings("ConnString"),
Data.CommandType.Text, "INSERT INTO Employees ([Name], Salary) VALUES ('" &
sName & "', " & dSalary & ");")
End Sub
End Class

Public Class Employees
Implements IEnumerable, IEnumerator
Private iIndex As Integer 'index of the array
Private iCount As Integer 'count of the elements
Private oEmp As ArrayList = New ArrayList 'array of employee objects

Public Sub New()
'any employees?
Dim objReader As SqlDataReader =
SqlHelper.ExecuteReader(ConfigurationManager.AppSe ttings("ConnString"),
Data.CommandType.Text, "SELECT * FROM Employees;")
iCount = -1

While objReader.Read
Dim oE As Employee = New Employee
oE.Name = objReader("Name").ToString
oE.Salary = objReader("Salary")
oEmp.Add(oE)
iCount += 1
End While

objReader.Close()
iIndex = -1
End Sub

Public Function GetEnumerator() As IEnumerator Implements
IEnumerable.GetEnumerator
Return Me 'returns an IEnumerator
End Function

Public ReadOnly Property Current() As Object Implements
IEnumerator.Current
Get
Return oEmp(iIndex) 'return the current object at index iIndex
End Get
End Property

Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
If iIndex < iCount Then
iIndex += 1
MoveNext = True
Else
MoveNext = False
End If
End Function

Public Sub Reset() Implements IEnumerator.Reset
iIndex = -1
End Sub
End Class

Aug 22 '08 #1
  • viewed: 1690
Share:
3 Replies
I suggest a function in the Employees class like this:

public function RichEmployees As Employees
dim emps as New Employees
' loop over Me adding Employee objects that meet your critera to emps
return emps
end function

I would have used a Collection rather than an ArrayList in the Employees
class, but that is just my preference.
"Scott Stark" wrote:
Hello,

I'm trying to get a better handle on OOP programming principles in VB.NET.
Forgive me if this question is sort of basic, but here's what I want to do.
I have a collection of Employee objects that I can iterate through
relatively easily. I've included code at the bottom of this message.

I can pretty easily iterate through my employee objects like so:

Dim theEmployees As Employees = New Employees

For Each Emp As Employee In theEmployees
Response.Write(Emp.Name & ": " & FormatCurrency(Emp.Salary, 2) & "<br
/>")
Next

My question is, let's say I want to create a new method...GetRichEmployees,
which returns a set of employee objects whose salary is >= 100,000. How
would I implement this? I know it's basic, but the answer to this will
probably help me solidify some of the more basic OOP priniciples in my head.
Still learning here, thanks!

Scott

Imports Microsoft.VisualBasic
Imports System.Data.SqlClient
Imports Microsoft.ApplicationBlocks.Data

Public Class Employee
Private sName As String
Private dSalary As Double

Public Property Name() As String
...
Public Property Salary() As String
...

Public Sub New()
sName = ""
dSalary = 0
End Sub

Public Sub New(ByVal sn As String, ByVal ds As Double)
...
End Sub

Public Sub Save()
SqlHelper.ExecuteNonQuery(ConfigurationManager.App Settings("ConnString"),
Data.CommandType.Text, "INSERT INTO Employees ([Name], Salary) VALUES ('" &
sName & "', " & dSalary & ");")
End Sub
End Class

Public Class Employees
Implements IEnumerable, IEnumerator
Private iIndex As Integer 'index of the array
Private iCount As Integer 'count of the elements
Private oEmp As ArrayList = New ArrayList 'array of employee objects

Public Sub New()
'any employees?
Dim objReader As SqlDataReader =
SqlHelper.ExecuteReader(ConfigurationManager.AppSe ttings("ConnString"),
Data.CommandType.Text, "SELECT * FROM Employees;")
iCount = -1

While objReader.Read
Dim oE As Employee = New Employee
oE.Name = objReader("Name").ToString
oE.Salary = objReader("Salary")
oEmp.Add(oE)
iCount += 1
End While

objReader.Close()
iIndex = -1
End Sub

Public Function GetEnumerator() As IEnumerator Implements
IEnumerable.GetEnumerator
Return Me 'returns an IEnumerator
End Function

Public ReadOnly Property Current() As Object Implements
IEnumerator.Current
Get
Return oEmp(iIndex) 'return the current object at index iIndex
End Get
End Property

Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
If iIndex < iCount Then
iIndex += 1
MoveNext = True
Else
MoveNext = False
End If
End Function

Public Sub Reset() Implements IEnumerator.Reset
iIndex = -1
End Sub
End Class

Aug 22 '08 #2
User EmployeesCollection Class as AmercerSaid. This class must be
inherited from CollectionBaseClass.
And add other functionality as you want.
Imports System
Imports System.Collections

Public Class EmployeesCollection
Inherits CollectionBase
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Add Definition

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Add(ByVal obj As Employees)
Try
List.Add(obj)

Catch ex As Exception
'Exception Block
End Try
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'IndexOf Definition

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function IndexOf(ByVal obj As Employees) As Integer
Try
Return List.IndexOf(obj)

Catch ex As Exception
'Exception Block
End Try
End Function
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Insert Definition

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Insert(ByVal index As Integer, ByVal obj As Employees)
Try
List.Insert(index, obj)

Catch ex As Exception
'Exception Block
End Try
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Remove Definition

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Remove(ByVal obj As Employees)
Try
List.Remove(obj)
Catch ex As Exception
'Exception Block
End Try
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Contains Definition

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function Contains(ByVal value As Employees) As Boolean
Try
' If value is not of type Int16, this will return false.
Return List.Contains(value)
Catch ex As Exception
'Exception Block
End Try
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''''''
'Item Definition

'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''''''
Default Public Property Item(ByVal index As Integer) As Employees
Get
Return CType(List(index), Employees)
End Get

Set(ByVal value As Employees)
Try
List(index) = value

Catch ex As Exception
'Exception Block
End Try
End Set
End Property
End Class
Aug 23 '08 #3
Scott Stark wrote:
Hello,

I'm trying to get a better handle on OOP programming principles in
VB.NET. Forgive me if this question is sort of basic, but here's what
I want to do. I have a collection of Employee objects that I can iterate
through
relatively easily. I've included code at the bottom of this message.
My question is, let's say I want to create a new
method...GetRichEmployees, which returns a set of employee objects
whose salary is >= 100,000. How would I implement this? I know it's basic, but
the answer to this will
probably help me solidify some of the more basic OOP priniciples in
my head. Still learning here, thanks!

Scott
There is a pitfall in your implementation of an enumerator for your Employees
class, which is that you store the index directly in the collection class. This
means you can have only one enumerator at any time. It won't be long before that
gives you some unwanted results.

For instance, if you needed a list of employees that appeared in the list more
than once, you might write something like
Dim Duplicated As New ArrayList
For Each A As Employee In MyEmployees
Dim N As Integer = 0
For Each B As Employee In MyEmployees
If A.Name = B.Name Then
N += 1
End If
Next B
If N 1 Then
Duplicated.Add A
End If
Next A

This would fail, because it uses two enumerators on the same collection.

Also, since you put the database read code in New(), you can't create an empty
collection for other uses. Better to put the "fill from DB" code in an explicit
sub of its own.

- - - - -

One good principle of OOP is to use the best tools you have for a job. In your
case, using List(Of Employee) would make the most sense. The generic List(Of
<T>) takes care of lots of issues with typed collections for you.

To use List(Of Employee), you can ditch having an Employees class altogether.
The only question is then where do you put the database fill code, etc.? They
can go lots of places, but a good solution is to make them shared methods of the
Employee class. Shared methods are not specific to an instance, and are more
like methods in a module somewhere.

So you could add two shared methods to Employee:

Public Shared Sub FillFromDB(Emps As List(Of Employee))
' your database code goes here...
' add them using Emps.Add(oE)
End Sub

Public Shared Function IsRichGuy(ByVal Emp As Employee) As Boolean
' a shared Predicate of Employee for use with FindAll...
Return (Emp.Salary >= 100000)
End Function

You can now write something like

Dim MyEmployees As New List(Of Employees)

' used shared method in Employee to fill it...
Employee.FillFromDB(MyEmployees)

' use shared predicate to filter the list...
Dim RichGuys As List(Of Employees) = _
MyEmployees.FindAll(AddressOf Employee.IsRichGuy)

Have fun with OOP! :)
Aug 23 '08 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

11 posts views Thread by fremenusul | last post: by
6 posts views Thread by Chua Wen Ching | last post: by
7 posts views Thread by jason | last post: by
5 posts views Thread by WebSnozz | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.