Visual Basic 2008 9.0 .NET Examples and Ebook
  Home

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

|

New in Visual Basic 2008 - 9.0

Volgend Onderwerp

Properties

Vorig Onderwerp

Introduction to Object Oriented Programming

|

Implementation

Volgend Onderwerp
Getter ( Get ) and Setter ( Set )

Getter ( Get ) and Setter ( Set )

Access Modifiers for Getters and Setters

Access Modifiers for Getters and Setters

ReadOnly Property

ReadOnly Property

ReadOnly Fields

ReadOnly Fields

WriteOnly Property

WriteOnly Property



Getter ( Get ) and Setter ( Set )


Some object orientated programming languages have Property-constructions.
These are a replacement for get-functions and set-procedures.


Namespace Example1
    Class Person
        Private m_Name As String
        Public Property Name() As String
            Get                                                            ' (1)
                Name = m_Name
            End Get
            Set(ByVal value As String)                                     ' (2)
                m_Name = value
            End Set
        End Property
    End Class
    Module Client
        Sub Main()
            Dim person1 As Person = New Person
            person1.Name = "John"                                          ' (3)
            Console.WriteLine(person1.Name)                                ' (4)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 John

The getter (1) of a property is executed when the property is read(4). The setter (2) is executed when the property is assigned a value (3). The value ( here String-literal "John" ) is assigned to the argumentvariable value of the setter.

As you can see the implementation of the getter and setter is identical to the implementations of the get-function and set-procedure of previous topic.
The client has to be changed. The client can address the property the same way it would address a public field.
Assigning a value to this property happens the same way a value would be assigned to a String variable.
When reading out this property (4) a String expression is formed, just like a call to the corresponding get-function of previous topic. A String expression is returned in the implementation of the getter of this property.

By default the identifier of the argument variable of the setter is value, this can be changed, although there usually is no reason to change this identifier. The role of this argument is always the "value" to set.

The type referred to in the type specifier of signature of the property and in the type specifier of the argument declaration of the signature of the setter of this property, always have to be the same. In the above example both are As String.

A public field would result in a identical manner of use for the client.


Namespace Example2
    Class Book
        Public Title As String
    End Class
    Module Client
        Sub Main()
            Dim book1 As Book = New Book
            book1.Title = "Some Title"
            Console.Write(book1.Title)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 Some Title

The advantage of working with Property-constructions ( or corresponding get-functions and set-procedures ) is that validation can happen. The assigned value can be manipulated before being stored by the setter ( or set-procedure ), and manipulated before being returned by the getter ( or get-function ).
When addressing a public field no code/implementation can be executed.

Field are rarely made public. These are usually only necessary for the holding states. Holding as state is an implementation matter. And implementation matters are usually encapsulated.

Up till version 2005 there are few differences between Property constructions on the one hand and set-procedures and get-functions on the other hand.
Properties in contrary to methods can be made default. Methods in contrary to properties can be pointed to with a delegate. Both default properties and delegates are rather rarely used in applications, so the choice between a Property construction and on the other hand a get-function and/or set-procedures was mainly a matter of person preference.
Since Visual Basic 2008 the use of properties gives us some new advantages, one of them is the With construct in the object initializer.
Some coding guidelines suggest to use a Property when the implementation consists of accessing a field. Setprocedures and getfunctions are suggested if a more complex implementation is needed.

Usually the identifier for a Property is a noun, for instance Name. In contrary to identifiers of methods, which are usually a verb or a combination of a verb and a noun, for instance SetName and GetName.


Klik hier om terug naar boven te gaan.  Up


Access Modifiers for Getters and Setters


It's possible to restrict the access modifier of the getter or the setter of a 'Property'.

For instance the setter can be scoped Private when the Property itself is Public. In that case only the getter is publicly available, the setter is encapsulated.

Following examples illustrates a Counter class with a Public Value property with a Private setter.


Namespace Example3
    Class Counter
        Private m_Value As Integer
        Public Property Value() As Integer
            Get
                Value = m_Value
            End Get
            Private Set(ByVal value As Integer)                            ' (1)
                m_Value = value
            End Set
        End Property
        Public Sub Raise()
            Value = Value + 1                                              ' (2)
        End Sub
    End Class
End Namespace
Download Broncode

Only within the class Counter Value can be set.

The following client can only read out the Value property. Setting this property is not allowed outside the class (3).


Namespace Example3
    Module Client
        Sub Main()
            Dim counter1 As Counter = New Counter
            Console.WriteLine(counter1.Value)
            '
            counter1.Raise()
            Console.WriteLine(counter1.Value)
            '
            counter1.Raise()
            Console.WriteLine(counter1.Value)
            '
            'counter1.Value = 5            ' impossible, no available setter (3)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 0
 1
 2

Abstraction wise this makes the property Value readonly for the clients.

Encapsulating the getter and allowing public access to the setter is rarely done, after all it wouldn't make much sense.


Klik hier om terug naar boven te gaan.  Up


ReadOnly Property


Derived properties of a concept usually are only queryable and not settable.
Base ( state ) properties on the other hand usually can be set and queried.

A Product can have base ( state ) properties like Price and TaxPercentage and a derived property PriceIncludingTax.

The properties Price and TaxPercentage have a getter and setter. The Property-construction for PriceIncludingTax can be made ReadOnly.

A ReadOnly Property only has a getter.


Namespace Example4
    Class Product
        Private m_Price As Decimal
        Public Property Price() As Decimal
            Get
                Price = m_Price
            End Get
            Set(ByVal value As Decimal)
                m_Price = value
            End Set
        End Property
        Private m_TaxPercentage As Decimal
        Public Property TaxPercentage() As Decimal
            Get
                TaxPercentage = m_TaxPercentage
            End Get
            Set(ByVal value As Decimal)
                m_TaxPercentage = value
            End Set
        End Property
        Public ReadOnly Property PriceIncludingTax() As Decimal
            Get
                PriceIncludingTax = Price * (1 + (TaxPercentage / 100))
            End Get
        End Property
    End Class
    Module Client
        Sub Main()
            Dim product1 As Product = New Product
            product1.Price = 100
            product1.TaxPercentage = 8
            'product1.PriceIncludingTax = 108 ' impossible ( ReadOnly Property )
            Console.WriteLine(product1.PriceIncludingTax)
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 108

Above 'Client' can't assign a value to property 'PriceIncludingTax'.

When we would make this property settable, what should then happen to Price and TaxPercentage when a PriceIncludingTax is set ?
Should we adjust the TaxPercentage based on the old Price and the new PriceIncludingTax ? Or should we adjust Price based on the old TaxPercentage and the new PriceIncludingTax ?
Both options are technically possible, but also abstraction wise illogical.
It's better to first decide which states/properties are settable, and then to make all derived states/properties readonly.

If you're implementing a members and you have the option to chose between addressing a public accessible property and an encapsulated field ( which can reflect the same value ) chose to address the public accessible property.
For instance you should be certain that 'TaxPercentage' delivers what it's stating to deliver, after all it is 'Public', so clients expect what it states. After setting 'TaxPercentage' to some value, clients expect that 'TaxPercentage' delivers that same value when reading this property.
The encapsulated field to hold the property value ( in this case
m_TaxPercentage ) on the other hand can hold any value, for any possible way of implementation. For instance it could hold value 40 or 0.4 for 40%, depending on what implementation is used. Nowhere is defined how this field ( in this m_TaxPercentage ) should represent the value for its corresponding property.
This is why the getter of PriceIncludingTax uses TaxPercentage instead of m_TaxPercentage.

An alternative for using the ReadOnly Property is the use of a getfunction, this is also what the coding guidelines suggest in case the implementation is doing more than retrieving a value from a field :


Namespace Example5
    Class Product
        Private m_Price As Decimal
        Public Property Price() As Decimal
            Get
                Price = m_Price
            End Get
            Set(ByVal value As Decimal)
                m_Price = value
            End Set
        End Property
        Private m_TaxPercentage As Decimal
        Public Property TaxPercentage() As Decimal
            Get
                TaxPercentage = m_TaxPercentage
            End Get
            Set(ByVal value As Decimal)
                m_TaxPercentage = value
            End Set
        End Property
        Public Function GetPriceIncludingTax() As Decimal
            GetPriceIncludingTax = Price * (1 + (TaxPercentage / 100))
        End Function
    End Class
    Module Client
        Sub Main()
            Dim product1 As Product = New Product
            product1.Price = 100
            product1.TaxPercentage = 8
            'product1.GetPriceIncludingTax = 108       ' impossible ( Function )
            Console.WriteLine(product1.GetPriceIncludingTax())
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Download Broncode

Output :

 108,00

Klik hier om terug naar boven te gaan.  Up


ReadOnly Fields


Also fields can be declared ReadOnly.

These fields can only be assigned a value in the constructor.

This is used for frozen states. Don't confuse frozen states with constants. A frozen state can ( in contrary to constants ) be set at runtime ( although only in the constructor ). After setting its value, the 'ReadOnly' field never change ( just like constants ).

For more details about constructors and ReadOnly field, have a look at the topic about constructors.


Klik hier om terug naar boven te gaan.  Up


WriteOnly Property


It is possible to make a Property WriteOnly.

'WriteOnly' Properties have no getter. It's value can only be set.

Abstraction wise there are no situations in which this can be used.
Why would a client be allowed to set a property to a certain ( for the client known ) value, but be disallowed to query the value it already knows ?


Updated On : 2008-09-25

Download Broncode

Published On : 2008-11-06

Properties

Vorig Onderwerp

Introduction to Object Oriented Programming

|

Implementation

Volgend Onderwerp

Object Oriented Programming

Vorig Onderwerp

Procedures and Functions

|

New in Visual Basic 2008 - 9.0

Volgend Onderwerp
  Home  
Nederlands
Nederlands

Add to favorites (IE).


No printable version available.