Visual Basic 2008 9.0 .NET Examples and Ebook

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

Containment

Vorig Onderwerp

Implementation

|

Collections - Introduction

Volgend Onderwerp
An Association between Objects

An Association between Objects

Reuse of Classes and Code

Reuse of Classes and Code

Who is Responsible for Creating an Object

Who is Responsible for Creating an Object

Exercise

Exercise



An Association between Objects


Often objects of (a) (different) type(s) have an association between them.
One type of association is a "has as" relation between objects of this (different) type(s). From here on I'll refer to this type of association as "containment".

For instance : a Person has an Address.


Class Person
    Private m_Name As String
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property
    Private m_Address As Address
    Public Property Address() As Address
        Get
            Address = m_Address
        End Get
        Set(ByVal value As Address)
            m_Address = value
        End Set
    End Property
End Class
Class Address
    Private m_Street As String
    Public Property Street() As String
        Get
            Street = m_Street
        End Get
        Set(ByVal value As String)
            m_Street = value
        End Set
    End Property
    Private m_Number As String
    Public Property Number() As String
        Get
            Number = m_Number
        End Get
        Set(ByVal value As String)
            m_Number = value
        End Set
    End Property
    Private m_ZipCode As String
    Public Property ZipCode() As String
        Get
            ZipCode = m_ZipCode
        End Get
        Set(ByVal value As String)
            m_ZipCode = value
        End Set
    End Property
    Private m_City As String
    Public Property City() As String
        Get
            City = m_City
        End Get
        Set(ByVal value As String)
            m_City = value
        End Set
    End Property
End Class
Module Client1
    Sub Main()
        Dim address1 As Address = New Address
        address1.Street = "Royal Avenue"
        address1.Number = "10"
        address1.ZipCode = "90210"
        address1.City = "Beverly Hills"
        '
        Dim person1 As Person = New Person
        person1.Name = "John"
        person1.Address = address1
        '
        Print(person1)
        '
        Console.ReadLine()
    End Sub
    Sub Print(ByVal person As Person)
        Console.WriteLine(person.Name)
        If person.Address IsNot Nothing Then
            With person.Address
                Console.WriteLine(.Number & ", " & .Street)
                Console.WriteLine(.City & " " & .ZipCode)
            End With
        End If
    End Sub
End Module
Download Broncode

Output :

 John
 10, Royal Avenue
 Beverly Hills 90210

The With [object-expression] ... End With-block is useful to address the members of the object ( of the objectexpression ) without addressing the object itself.

An object of type Person can have a reference of an Address object.
By containing this reference, the Person object can remember with which Address object it is associated.

First the variable address1 in the Main procedure is filled with a reference to some new Address object. The expression address1 is then used to express which address has to be associated with object person1. This is done by injecting the address reference in the person object thru the SetAddress command.

We can avoid the use of the variable address1 when we immediately inject the Person object with some new Address instance.


Module Client2
    Sub Main()
        Dim person1 As Person = New Person
        person1.Name = "John"
        person1.Address = New Address
        person1.Address.Street = "Royal Avenue"                            ' (1)
        person1.Address.Number = "10"
        person1.Address.ZipCode = "90210"
        person1.Address.City = "Beverly Hills"
        Print(person1)
        '
        Dim person2 As Person = New Person
        person2.Name = "Jane"
        person2.Address = person1.Address                                  ' (2)
        Print(person2)
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 John
 10, Royal Avenue
 Beverly Hills 90210

Klik hier om terug naar boven te gaan.  Up



Reuse of Classes and Code


You can see how easy it is to let different Person objects ( person1 and person2 ) use the same Address object (2).
This could only be made possible by isolating the address property in its own construction ( class Address ). Had we includes the properties Street, Number, ZipCode and City in Person, then all Person objects would have their own address properties.

The client of the above example first has to make the object of type Address and can only then set the address of a person.

An alternative would be to let objects of type Person create there own associated/contained Address object. This is what happens in objects of the containing type Customer that contain an object of contained type Address (1).


Class Customer
    Private m_Name As String
    Public Property Name() As String
        Get
            Name = m_Name
        End Get
        Set(ByVal value As String)
            m_Name = value
        End Set
    End Property
    Private m_Address As Address = New Address                             ' (1)
    Public Property Address() As Address
        Get
            Address = m_Address
        End Get
        Set(ByVal value As Address)
            m_Address = value
        End Set
    End Property
End Class
Download Broncode

The field m_Address is initialized to a reference of a new Address object. Immediately when a Customer object is created, an Address object is created as well.

The client no longer has to make the contained Address object.


Module Client3
    Sub Main()
        Dim customer1 As Customer = New Customer
        customer1.Address.City = "New York"
        '
        Console.WriteLine(customer1.Address.City)
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 New York

Klik hier om terug naar boven te gaan.  Up



Who is Responsible for Creating an Object


whether or not the containing object has to be responsible for creating the contained object depends on the situation and the needed construction.

When the containing object is the only object which has to use the contained object, or in situations where the containing object know what initialization data should be used for creation the contained object, then the containing object is made responsible for creating the contained object. ( "GRASPattern Creator" ).

When multiple objects of the containing type have to share the same object of the contained type, it useless to let all containing object first create their own contained object.

Containment allows code to be reused, both Person and Custom can use the members of Address.

Other examples of containment can be : a computer has a processor, an invoice has a customer, a book has an index, ... .


Klik hier om terug naar boven te gaan.  Up


Exercise


Task :

Adjust our class Robot, created in previous topic. Let object of type Robot use an object of type Position. A Position object has a X and a Y property.


Solution :


Class Position
    Private m_X As Integer
    Public Property X() As Integer
        Get
            X = m_X
        End Get
        Set(ByVal value As Integer)
            m_X = value
        End Set
    End Property
    Private m_Y As Integer
    Public Property Y() As Integer
        Get
            Y = m_Y
        End Get
        Set(ByVal value As Integer)
            m_Y = value
        End Set
    End Property
End Class
Module PositionTextFixture
    Sub Main()
        Dim position1 As Position = New Position
        Console.WriteLine(position1.X = 0)
        Console.WriteLine(position1.Y = 0)
        '
        position1.X = 5
        Console.WriteLine(position1.X = 5)
        Console.WriteLine(position1.Y = 0)
        '
        position1.Y = 10
        Console.WriteLine(position1.X = 5)
        Console.WriteLine(position1.Y = 10)
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 True
 True
 True
 True
 True
 True

Class Robot
    Private m_Position As Position = New Position
    Public ReadOnly Property Position() As Position
        Get
            Position = m_Position
        End Get
    End Property
    Private m_Direction As Integer
    Public Sub Rotate()
        m_Direction += 1
        If m_Direction > 3 Then m_Direction = 0
    End Sub
    Public Sub PlaceStep()
        Select Case m_Direction
            Case 0 ' up
                Position.Y = Position.Y + 1
            Case 1 ' right
                Position.X = Position.X + 1
            Case 2 ' down
                Position.Y = Position.Y - 1
            Case 3 ' left
                Position.X = Position.X - 1
        End Select
    End Sub
End Class
Module RobotTestFixture
    Public Sub Main()
        Dim robot1 As Robot = New Robot
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 0)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.Rotate()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 1)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 1)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 1)
        '
        robot1.Rotate()
        robot1.PlaceStep()
        Console.WriteLine(robot1.Position IsNot Nothing)
        Console.WriteLine(robot1.Position.X = 0)
        Console.WriteLine(robot1.Position.Y = 2)
        '
        Console.ReadLine()
    End Sub
End Module
Download Broncode

Output :

 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True
 True

Objects of the containing type Robot create their own objects of the contained type Position. Each robot has to intensively use ( manipulate ) its own position on the grid.

The property position in Robot is made readonly ( only a GetPosition, no SetPosition ). In this abstraction only the command PlaceStep can manipulate the position.
When you would want an abstraction which allows clients to set the robot to a specific position, you simple have to add something like SetPosition.





This version ( published on 2008-06-24 ) is printed from http://www.studyvb.com, visit the website for more recent information.

Updated On : 2008-05-29

Download Broncode

Published On : 2008-06-24

Containment

Vorig Onderwerp

Implementation

|

Collections - Introduction

Volgend Onderwerp

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

Nederlands  Nederlands

Add to favorites (IE).