Results 1 to 15 of 15

Thread: [RESOLVED] Need more help understanding Classes

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Resolved [RESOLVED] Need more help understanding Classes

    Hi Guys

    As I said in my prior post I am trying to get to grips with Classes and how to use them "efficiently", So bearing this in mind I decided to create a small class driven application.

    I am struggling to understand how I can "use" this new instance of this user somewhere else.


    Test Data was
    Name : Joe
    username : JoeBloggs
    Password : JoesPassword

    Then

    Name : John
    Username : JohnDoe
    Password : JohnsPassword


    Now this updates the listbox with Joe and John in each row.

    The Form Code is. 3 Textboxes, 1 Button , 1 Listbox, 2Labels.

    Code:
    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            If (txtName.Text = "") Then
                MsgBox("ERROR ENTER CLASS NAME")
            Else
                'Create a new user object. I tried to create a "unique" object name by passing the txtName.text value but it throws errors getName is not member of string..
                'Dim txtName.text As New user
     
                Dim newObject As New user
                newObject.setDetails(txtUsername.Text, txtPassword.Text, txtName.Text)
                lstUsers.Items.Add(newObject.getName())
            End If
        End Sub
    
        Private Sub lstUsers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstUsers.SelectedIndexChanged
            Dim users As user
            users.getLogins(lstUsers.SelectedItem)
        End Sub
    End Class
    Which is handled by this class.
    Code:
    Public Class user
        Dim name As String
        Dim username As String
        Dim password As String
        Public Sub setDetails(ByVal argusername As String, ByVal argpassword As String, ByVal argName As String)
            name = argName
            username = argusername
            password = argpassword
        End Sub
    
        Public Function getName()
            Return name
        End Function
    
        Public Function getLogins(ByVal userObject As Object)
            Form1.Label1.Text = username
            Form1.Label2.Text = password
            Return Nothing
    
        End Function
    
    End Class
    Now this works and updates the listbox with the new instance of the user but how can I use that instance from the listBox control to retrieve that users details??

    Many Thanks Barra.

    PS If you needed clearer clarification on what i am trying to do, Please ask
    Last edited by Barrabutus; Mar 10th, 2011 at 05:54 PM.

  2. #2
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Need more help understanding Classes

    After reading it over a few times, I get what you are trying to accomplish.
    Correct me if I am wrong, but you want to have:
    - a button with textboxes to add new names with password and username
    - a listbox displaying the names
    - a way of determining what instance is selected from the listbox selection changed

    A problem with your current code is that you are not actually storing your classes.

    You only know the selected name, but no instance of the previously added item is there to evaluate with.

    To do this properly, make a single list variable in your Form1 class:
    Code:
    Private users As New List(Of user)
    Then, to "sync" it with your listbox, you add a new item to both your listbox AND your user list:
    Code:
                Dim newObject As New user()
                newObject.setDetails(txtUsername.Text, txtPassword.Text, txtName.Text)
                lstUsers.Items.Add(newObject.getName())
                users.Add(newObject)
    Now you can access your "already added info" from the selected index:
    Code:
    Private Sub lstUsers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstUsers.SelectedIndexChanged
          Dim selecteduser As user = users(lstUsers.SelectedIndex)
          'do some stuff with this class, like setting your textboxes or labels
    End Sub
    Important is to keep some sort of "back buffer" with your data in the background, and not to store your info in a control. I made the same mistake before, adding all my information to a listview control. But it makes it hard to use your stored data.

    EDIT

    In case you want some sort of global storage, you can add a shared list member to your user class:
    Code:
        Public Class user
            Private Shared users As New List(Of user)
            Public Shared Function GetUser(ByVal name As String) As user
                For Each u As user In users
                    If u.getName = name Then Return u
                Next
                Return Nothing
            End Function
    
            Public Shared Sub AddUser(ByVal u As user)
                users.Add(u)
            End Sub
    Last edited by bergerkiller; Mar 10th, 2011 at 06:08 PM.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    Aha!

    You sir are a Genius!

    I have been developing applications using modules for too long and have now decided to take the leap of faith and try to utilise classes instead of "reusing" modules but i have never been too sure about how you can pass an instance of an object around in your code.

    I have been using SQL databases with some applications ive done in VB but they are all almost module based with 0 classes. So i dont intend to use a control to store an object this was just a learning test for me to try to get to grips with how i can pass an object around in code.

    Because in the start I thought you always had to use a "name" for a new instance of a class

    Example :
    Dim myBike as new Bike
    Dim theirBike as new Bike
    Dim myOtherBike as new Bike

    Then as i understand you can get the values from

    myBike.getGears()

    Which as you can imagine appears to start bloating the code out if you need a unique name for each instance created.

    But now I guess you can use a Generic name and use a Name within the class properties to retrieve details from a specific class.

    Next stop to try and add an Inheritance to the user Class so a user could have a email address. lol

    Many Many Thanks !

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    This code confuses me to an extreme that i could not comprehend...
    I have quoted out what i think it is doing but im not sure.

    Quote Originally Posted by bergerkiller View Post
    In case you want some sort of global storage, you can add a shared list member to your user class:
    Code:
       
    'Base user Class
    Public Class user
            ' I dont understand the (Of user) part within this.
            'Declare a new list named users (Of user) 
            Private Shared users As New List(Of user)
            'Method for getUsers(expects a name to be sent as a string) returns a User Object
            Public Shared Function GetUser(ByVal name As String) As user
                'For each <something> as <object> in <list>
               For Each u As user In users
                    'Puzzled here.....
                    'If u.getName = name ??
                    If u.getName = name Then Return u
                Next
                Return Nothing
            End Function
    
            Public Shared Sub AddUser(ByVal u As user)
                users.Add(u)
            End Sub

    Many thanks for the help and trying to guide me into classes instead of always using modules for coding.

    Regards Barra.

  5. #5
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Need more help understanding Classes

    Well, there are two types of "arrays" used most inside vb .NET.
    The first is the fixed array:
    Code:
    Dim a(<Count>) as <Type>
    Count is the amount of items to preserve, and the <Type> is the type of variable (String, Integer, current class name).

    The other is the generic array, or list array.
    This is a single "variable" containing lots of "items" of a certain type:
    Code:
    Dim a As New List(Of <Type>)
    You can not set the amount to reserve, this is because the generic list type can change in size dynamically. For example, you can add or remove items:
    Code:
                Dim a As New List(Of String)
                a.Add("a new item")
                a.Remove("a new item")
                a.Add("index item")
                a.RemoveAt(0)
    In your case, you do not have a type of "String" but of type "user". So you have to declare a new list of type "user".

    Code:
        Public Sub routine()
            Dim a As New List(Of user)
            Dim item As New user
            item.name = "name"
            item.username = "username"
            item.password = "pass"
            a.Add(item)
        End Sub
    
        Public Class user
            Public name As String
            Public username As String
            Public password As String
        End Class
    I added a "public" keyword so I could access the members directly. If you want to keep it "protected", keep them dimmed or private and add getter/setter routines.

    The for loop is basically a loop that searches for the given name in the collection. Since the list contains items of type "user", you can not do this:
    Code:
    If u = "name" Then ...
    You have to access the "name" member in the class:
    Code:
    if u.name = "name" Then ...
    You can use the "Return value" statement to exit the function with a certain value. For example:
    Code:
        Public Function test(ByVal testvalue As String) As String
            If testvalue = "value" Then Return "Value"
            Return testvalue
        End Function
    Just don't forget there are a lot of different type of variables now, and not just variables with type "String".

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Need more help understanding Classes

    Just for grins, a module IS a class with all shared members.

    The (Of User) is there because List (of T) is a generic type. Generic types are interesting animals. They are defined with an unknown type T. When you create an instance of the generic, you have to give it a specific type (User, in this case). The code that the compiler generates is specific to that type such that if you create a List (of User), you can't add an Integer to that list, because the list only accepts instances of User. Without generics, there would have to be an IntegerList, UserList, DoubleList, and even ArrayList (there is one of those, actually, which is pretty much a List (of Object), and was the only option prior to framework 2.0).

    Not sure what part is puzzling you in the second part. That loop is going through all of the User instances in the List of users, and if the name member equals the name argument passed to the sub, that particular instance of user is returned, but that seems unlikely to be the question you had.
    My usual boring signature: Nothing

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    Ahh yes i get it now, The same way that you pass an argument to a module

    I understood the loop part after i posted it , You was just passing the argument from the listbox to the method

    I am currently trying to add an inheritance this user Class so a user can have an email

    @ Shaggy Hiker : I tend to use ArrayList quite a lot to be honest when im passing multiple values from a module back to a form and want to loop them for a COmboBox or Listbox or something similar.

    Many Thanks for all the replys, I will keep updating this thread as i progress through this class example.

    I tried to look online for better class explanations but i managed to find was tutorials like i explained above, Using classes as named instances (Dim myBike as new Bike, Dim theirBike as New Bike...Etc)

    I understood all of this part already but this way didnt seem too efficient to me because you had to create a new named instance of the class for each Bike.

    BTW : This forum is awesome, So many helpful people and quick responses.

    Regards Barra.

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    Hmm I am completely stuck now....

    Code:
    Public Class email
        Inherits user
    
        'This class inherits username and password and name from user class.
        'So that the user instance can now have an email address.
        Dim email As String
        Public Sub setEmail(ByVal argEmail As String)
            email = argEmail
        End Sub
    
        Public Function getEmail()
            Return email
        End Function
    End Class
    You can see that now i have declared a email class which inherits from user.
    But.... I am sooo lost as to how i assign the instanced user an email address from the user class above.

    Please look in my first post for the user class and how the users are being instantiated. (didnt see the point to repost all the code)

    How would i go about performing this please?

    Many Thanks Barra.

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    AHHHHH I get it now!!

    So inheritance is an extension to the base class along with all the inherited methods that are associated with the new class in this case email.

    Code:
    Public Class user
    'Each user can now have an email address too...
        Inherits email
    So i was able to use newObject.setEmail(txtEmail.text) when i created a new instance using the newObject and it was assigned to that object.

    I think classes are becoming slowly clearer to me now.

    I think i will try to create something simple using classes such as a calculator(Im guessing that would be a good start )

    I,ll post my calculator class here for inspection by the experts in case im doing something wrong

    Many Many Thanks!

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Need more help understanding Classes

    There is never a reason to use the ArrayList anymore. The List has entirely replaced it since its introduction with framework 2.0 (VB2005).
    My usual boring signature: Nothing

  11. #11
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Need more help understanding Classes

    I think you're confusing a few things now. Let me try to explain how I think you want to do it.


    1. The User class
    The User class should have properties like Name and Password. You should not use separate get and set methods, using an actual property has many advantages. In this case, the base of your User class would look like so:
    vb.net Code:
    1. Public Class User
    2.  
    3.    Private _Name As String
    4.    Public Property Name As String
    5.       Get
    6.          Return _Name
    7.       End Get
    8.       Set(ByVal value As String)
    9.          _Name = value
    10.       End Set
    11.    End Property
    12.  
    13.    Private _Password As String
    14.    Public Property Password As String
    15.       Get
    16.          Return _Password
    17.       End Get
    18.       Set(ByVal value As String)
    19.          _Password = value
    20.       End Set
    21.    End Property
    22.  
    23. End Class
    You can now create instances of the User class and set these properties like so:
    vb.net Code:
    1. Dim u1 As New User()
    2. u1.Name = "Nick Thissen"
    3. u1.Password = "abcdefg"
    4.  
    5. Dim u2 As New User()
    6. u2.Name = "Test user"
    7. u2.Password = "e9c03k"

    2. Displaying Users in a ListBox (or other type of control)
    A ListBox can do more than you might expect at first sight. It seems like you can only add strings to it, but you can actually add complete User objects to it (or any other kind of object for that matter). However, by default the ListBox does not know how to display a User object so it displays 'garbage' (the project + class name), which is not very useful. There are actually two ways to solve this, the most common and best one is databinding. This extends on the idea that someone else already provided: you add your User objects to a List(Of User). Instead of also adding the names of the users to the ListBox separately, you can now DataBind the entire List(Of User) to the ListBox. You can then finally tell the ListBox which property (this is why we need properties!) of the User to display, via the DisplayMember property.
    Example:
    vb.net Code:
    1. 'Create a new list of users
    2. Dim users As New List(Of User)
    3.  
    4. 'Add the users we created before (u1, u2)
    5. users.Add(u1)
    6. users.Add(u2)
    7. 'etc...
    8.  
    9. 'Now instead of adding them also to the Listbox separately, we just databind the listbox to the users list:
    10. ListBox1.DataSource = users
    11.  
    12. 'And we tell it to display the Name of the user:
    13. ListBox1.DisplayMember = "Name"  
    14. ' "Name" in this case corresponds to the property that should be displayed: Name.
    15. ' you could choose Password as well, but we don't want that ;)

    The advantage of this is that the ListBox now actually contains a list of Users, instead of just their names. To retrieve a User from the listbox all you need to do is get it from the Items collection (by index), or if you want the selected user you use the SelectedItem property. This returns an Object, which is actually an instance of your User class. One technicality is required here: while you know that the ListBox contains Users (as it is bound to a list of them, and not to a list of cows), you know that the Object the SelectedItem property returns is a User. However, VB cannot know that (because you might as well bind a list of cows!), so it returns the selected item (and any other item) as type Object, which is the base class for all other classes (everything is an Object). All you need to do to be able to use the selected item (user) is cast it to a User. This does actually nothing, all it does is tell VB "hey, this is actually a User, and not a cow", so you can then use it like a User.

    This works as follows:
    vb.net Code:
    1. 'Get the selected item
    2. Dim obj As Object = ListBox1.SelectedItem
    3.  
    4. 'Tell VB that this is a User
    5. Dim user As User = DirectCast(obj, User)
    6.  
    7. 'And then use it
    8. MessageBox.Show("The password of user " & user.Name & " is " & user.Password)

    That's it! No more 'syncing' between your users list and the listbox is required, the Listbox actually holds the User instances and you can retrieve them whenever you want.


    3. The Email
    I see you want your users to have an Email, and you tried to solve this by having a class Email inherit User (or vice versa). That is not the correct way. Inheritance is an 'IS-A' relation. When A inherits B then A is a B. For example, a cow is an animal, so Cow inherits Animal.

    A User is not an Email address (nor vice versa), so inheritance is not correct here. What you need is a 'HAS-A' relation. A User has an Email address. That is solved by letting the User class have a property Email. The type of this property is commonly just a String (just the email address), but you might want to store some more information (like the email provider, or even the password, I dunno). In that case you can indeed make a class Email (with the properties Address and Password for example). The Email property in the User class is then of type Email.
    vb.net Code:
    1. Public Class Email
    2.  
    3.    Private _Address As String
    4.    Public Property Address As String
    5.       Get
    6.          Return _Address
    7.       End Get
    8.       Set(ByVal value As String)
    9.          _Address = value
    10.       End Set
    11.    End Property
    12.  
    13.    Private _Password As String
    14.    Public Property Password As String
    15.       Get
    16.          Return _Password
    17.       End Get
    18.       Set(ByVal value As String)
    19.          _Password = value
    20.       End Set
    21.    End Property
    22.  
    23. End Class

    Updated User class:
    vb.net Code:
    1. Public Class User
    2.  
    3.    Private _Name As String
    4.    Public Property Name As String
    5.       Get
    6.          Return _Name
    7.       End Get
    8.       Set(ByVal value As String)
    9.          _Name = value
    10.       End Set
    11.    End Property
    12.  
    13.    Private _Password As String
    14.    Public Property Password As String
    15.       Get
    16.          Return _Password
    17.       End Get
    18.       Set(ByVal value As String)
    19.          _Password = value
    20.       End Set
    21.    End Property
    22.  
    23.    Private _Email As Email = New Email()   'Note!
    24.    Public ReadOnly Property Email As Email
    25.       Get
    26.          Return _Email
    27.       End Get
    28.    End Property
    29.  
    30. End Class
    Another technicality here is that I made the Email property read-only. That means you cannot assign a different Email, you can only change the email properties Address and Password. Also, the 'backing field' (_Email) is assigned a New instance immediately, otherwise you could never set it.

    Usage now:
    vb.net Code:
    1. Dim u As New User()
    2. u.Name = "Nick Thissen"
    3. u.Password = "abcdefg"
    4. u.Email.Address = "[email protected]"
    5. u.Email.Password = "xyz"

    That's it.

    I hope this helps. The most important bit to remember when working with classes is that they almost always relate exactly to reality. Each 'thing' in reality gets a class. The properties of that thing get properties in that class. If two things are related via an 'IS-A' relation (a cow is an animal, a car is a form of transport, a house is a building, etc) then you can use inheritance. The idea of inheritance is that the more specific class (cow, car, house) inherits properties and methods from its parent:
    - Every animal has legs, so the Animal class could have a collection of legs and the Cow class simply inherits this collection, no more Legs property needed in the Cow class.
    - Every form of transport has a way to move, so the Transport class could have a Move method, which the Car class then inherits (and possible overrides, or 'changes').
    - Every building has an entrance, so a house simply inherits that.

  12. #12

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    Awesome Post Nick !

    Thanks for the explanation, I will have to re-read that a few times to get to grips with it as you can see how I was getting rather frustrated by trying to use Classes instead of Module based applications and how inheritance was confusing.

    The only downside I see to your Code is in the instantiation of the classes

    Dim u1 as new user
    Dim u2 as new user

    Bearing in mind this is a learning thing for me so 2 users is fine.
    But say in the real-world, I have an application which accepts information from a form to go into a database I wouldnt have a
    Dim u1 as new User
    Dim u2 as new User

    Maybe could use just
    Dim newUser as new User

    Say for example when a user clicks Register Me or something

    This is where I was getting really confused with classes because all the tutorials I found didnt really explain how you can use classes within a Dynamic environment, But with all the recent posts within this thread, Classes are slowly becoming clearer to me and even more appealing

    I hope maybe that by keeping this thread updated that it may even answer some other people like me who can use modules no problem at all but when it comes to true OOP based programs, Sometimes we get lost in it all.

    Many Thanks Barra.

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,106

    Re: Need more help understanding Classes

    Any time you use the New word, you are creating a new instance. The variable u1 or u2 doesn't actually hold the user object, it just holds the address of the object in memory. Therefore, if you were to do this:

    Dim u1 as New User

    you have created a new User object in memory, and the address of that object has been put into the variable u1. If you then do this:

    u1 = New User

    then you are creating yet another User object in memory, and sticking the address of it into the variable u1. So what happens to the other User that you created? Nothing. It is still in memory, but now there isn't a variable that has the address for it. Therefore, it is unreachable, and will eventually be deleted and recovered by the garbage collector. So you can keep creating new User objects dynamically and doing whatever you want with them. Quite often you will need only one user object variable, regardless of the number of User objects you will create or dispose of over the course of the program. Of course, this is much like the way any other variable works, if you think about it.
    My usual boring signature: Nothing

  14. #14
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Need more help understanding Classes

    In a typical environment you would have a list of users somewhere globally (outside of any methods, for example in your main form). When someone is registering a new user, you merely create a new User object, set its properties to what the user entered, and add it to the list of users. Then you can forget about it. If your list of users is bound to controls (grids, lists, etc) then you can update them and the new user would be displayed.
    vb.net Code:
    1. Dim u As New User()
    2. u.Name = txtName.Text
    3. u.Password = txtPassword.Text
    4.  
    5. users.Add(u)
    6.  
    7. Me.UpdateUsersGrid()  'some function that updates a grid to display the new list of users which now has an extra entry

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Jan 2011
    Posts
    132

    Re: Need more help understanding Classes

    After much reading through this, I finally understand the use of Objects in .NET and have managed to use them in a fully functional program i created to generate reports from CSV files.

    I would like to thank everyone who posted a reply to this post and the key thing i was missing to utilise the Objects was the List (Of MyClass)

    I have added reputation points to all who posted a reply to this thread.

    That tip was the vital part that i was missing when trying to use objects in a program.

    Many thanks and muchly appreciated

    Barra

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width