Muchos lenguajes de programación orientado a objetos acceden a sus atributos a través de métodos. Esto lo vimos en el concepto anterior cuando accedíamos al atributo monto de un cliente:
Public Sub Depositar(ByVal m As Integer)
monto = monto + m
End Sub
Public Function RetornarMonto() As Integer
Return monto
End Function
Vimos que luego llamamos a dichos métodos con la sintaxis:
cliente3.Depositar(200) cliente3.Extraer(150)
En Visual Basic .Net normalmente este tipo de problemas se lo resuelve implementado una propiedad. Veamos el mismo problemas resolviéndolo utilizando propiedades.
El problema era : Un banco tiene 3 clientes que pueden hacer depósitos y extracciones. También el banco requiere que al final del día calcule la cantidad de dinero que hay depositada.
Module Module1
Class Cliente
Private _nombre As String
Private _monto As Integer
Public Property nombre() As String
Get
Return _nombre
End Get
Set(ByVal value As String)
_nombre = value
End Set
End Property
Public Property monto() As Integer
Get
Return _monto
End Get
Set(ByVal value As Integer)
_monto = value
End Set
End Property
Public Sub Imprimir()
Console.WriteLine(nombre & " tiene depositado la suma de " & monto)
End Sub
End Class
Public Class Banco
Private cliente1, cliente2, cliente3 As Cliente
Public Sub New()
cliente1 = New Cliente()
cliente1.nombre = "Juan"
cliente1.monto = 0
cliente2 = New Cliente()
cliente2.nombre = "Ana"
cliente2.monto = 0
cliente3 = New Cliente()
cliente3.nombre = "Pedro"
cliente3.monto = 0
End Sub
Public Sub Operar()
cliente1.monto = cliente1.monto + 100
cliente2.monto = cliente2.monto + 150
cliente3.monto = cliente3.monto + 200
End Sub
Public Sub DepositosTotales()
Dim t As Integer = cliente1.monto + cliente2.monto + cliente3.monto
Console.WriteLine("El total de dinero en el banco es:" & t)
cliente1.Imprimir()
cliente2.Imprimir()
cliente3.Imprimir()
End Sub
End Class
Sub Main()
Dim banco1 = New Banco()
banco1.Operar()
banco1.DepositosTotales()
Console.ReadKey()
End Sub
End Module
Lo más importante es entender que una propiedad es una forma de acceder al contenido de un atributo, tanto para consultar su valor como modificarlo.
Class Cliente
Private _nombre As String
Private _monto As Integer
Public Property nombre() As String
Get
Return _nombre
End Get
Set(ByVal value As String)
_nombre = value
End Set
End Property
Public Property monto() As Integer
Get
Return _monto
End Get
Set(ByVal value As Integer)
_monto = value
End Set
End Property
Los atributos los llamamos _nombre y _monto. Las propiedades las llamamos nombre y monto. Las propiedades no almacenan valores sino que normalmente acceden a los atributos para modificarlos o consultarlos.
La propiedad Nombre mediante el modificador set inicializa el atributo _nombre con el valor que llega del objeto:
cliente1.nombre = "Juan"
Como vemos donde definimos el objeto cliente1 accedemos a la propiedad mediante el operador punto y le asignamos un valor (en este caso un String porque la propiedad es de tipo String)
Si queremos consultar el atributo nombre lo podemos hacer mediante la propiedad Nombre. Es común definir el nombre que le damos al atributo con el mismo nombre que tiene la propiedad pero agregando el caracter _:
'atributo _monto
Private _monto As Integer
'propiedad monto
Public Property monto() As Integer
Get
'valor devuelto por la propiedad
Return _monto
End Get
Set(ByVal value As Integer)
'value indica el valor que se le asigna a la propiedad
_monto = value
End Set
End Property
Podemos observar que la sintaxis para acceder a las propiedades donde definimos objetos es mucho mas intuitiva y sencillas, por ejemplo para saber cuanto dinero hay en el banco la sintaxis con propiedades es:
Dim t As Integer = cliente1.monto + cliente2.monto + cliente3.monto
Y como la vimos anteriormente por medio de un método que retorna el monto tenemos la siguiente sintaxis:
Dim t As Integer = cliente1.RetornarMonto() +
cliente2.RetornarMonto() +
cliente3.RetornarMonto()
Lo primero que nos viene a la mente es porque no definir los atributos con el modificador Public :
Public _monto as Integer
Para luego poder consultarlos y/o modificarlos con la sintaxis:
dim t as Integer = cliente1._monto + cliente2._monto + cliente3._monto
Ahora veamos que cuando consultamos o inicializamos una propiedad en realidad lo que está sucediendo es la ejecución de un método (Set o Get) donde podemos disponer código donde validar el valor asignado. Por ejemplo si disponemos la restricción que el Monto siempre debe ser positivo para que se almacene, luego debemos codificar la propiedad con la siguiente sintaxis:
Public Property monto() As Integer
Get
Return _monto
End Get
Set(ByVal value As Integer)
If (value > 0) Then
_monto = value
Else
Console.WriteLine("No se puede tener un monto negativo.")
End If
End Set
End Property
Es decir si el valor que le asignamos a la propiedad Monto es negativo luego no se inicializa el atributo _monto con dicho valor.
Si ejecutamos este código luego debe mostrar un mensaje indicando que "No se puede tener monto negativo":
cliente1.Monto = -100
Plantear un programa que permita jugar a los dados. Las reglas de juego son: se tiran tres dados si los tres salen con el mismo valor mostrar un mensaje que "gano", sino "perdió".
Module Module1
Public Class Dado
Private _valor As Integer
Public Property valor() As Integer
Get
Return _valor
End Get
Private Set(value As Integer)
_valor = value
End Set
End Property
Private Shared aleatorio As Random
Public Sub New()
aleatorio = New Random()
End Sub
Public Sub Tirar()
valor = aleatorio.Next(1, 7)
End Sub
Public Sub Imprimir()
Console.WriteLine("El valor del dado es:" & valor)
End Sub
End Class
Public Class JuegoDeDados
Private dado1, dado2, dado3 As Dado
Public Sub New()
dado1 = New Dado()
dado2 = New Dado()
dado3 = New Dado()
End Sub
Public Sub Jugar()
dado1.Tirar()
dado1.Imprimir()
dado2.Tirar()
dado2.Imprimir()
dado3.Tirar()
dado3.Imprimir()
If dado1.valor = dado2.valor And dado1.valor = dado3.valor Then
Console.WriteLine("Ganó")
Else
Console.WriteLine("Perdió")
End If
Console.ReadKey()
End Sub
End Class
Sub Main()
Dim j = New JuegoDeDados()
j.Jugar()
End Sub
End Module
El atributo _valor se lo accede por medio de la propiedad valor:
Private _valor As Integer
Public Property valor() As Integer
Get
Return _valor
End Get
Set(value As Integer)
_valor = value
End Set
End Property
Luego cuando queremos consultar el valor del dado desde el jugo de dados por medio de la sintaxis siguiente podemos comparar si los tres dados tienen el mismo número:
If dado1.valor = dado2.valor And dado1.valor = dado3.valor Then
Console.WriteLine("Ganó")
Else
Console.WriteLine("Perdió")
End If
Algo importante es poder restringir la ejecución del set o get desde fuera de la clase, por ejemplo en este caso queremos evitar que desde la clase JuegoDeDados se puede cambiar el valor del dado con la siguiente sintaxis:
dado1.Valor=7
La línea anterior provocará un error ya que sección del set de la propiedad la hemos definido de tipo Private (con esto hacemos que solo los métodos de la clase puedan ejecuta el Set). La sintaxis para acceder a la propiedad Valor desde la clase es:
Public Sub Tirar()
valor = aleatorio.Next(1, 7)
End Sub
Esto es correcto ya que el método Tirar pertenece a la clase Dado y por lo tanto puede asignarle un dato a la propiedad valor (cuando se asigna un valor a una propiedad se ejecuta el Set)
En las últimas versiones de Visual Studio .Net podemos generar el código fuente de una propiedad en forma automática, para ello disponemos el cursor sobre el atributo de la clase y seleccionamos del lado izquierdo la opción:

Luego de esto tenemos generado en forma automática el código fuente de la definición de la propiedad:

Podemos luego modificar el código generado y agregar validaciones por ejemplo.
Module Module1
Public Class Socio
Private _nombre As String
Private _antiguedad As Integer
Public Property Nombre() As String
Set(ByVal value As String)
_nombre = value
End Set
Get
Return _nombre
End Get
End Property
Public Property Antiguedad() As Integer
Set(ByVal value As Integer)
If value >= 0 Then
_antiguedad = value
Else
Console.Write("No se puede asignar aun valor negativo a la antiguedad")
End If
End Set
Get
Return _antiguedad
End Get
End Property
End Class
Public Class Club
Private socio1, socio2, socio3 As Socio
Public Sub New()
socio1 = New Socio()
socio1.Nombre = "Juan"
socio1.Antiguedad = 7
socio2 = New Socio()
socio2.Nombre = "Ana"
socio2.Antiguedad = 3
socio3 = New Socio()
socio3.Nombre = "Martin"
socio3.Antiguedad = 25
End Sub
Public Sub MayorAntiguedad()
If socio1.Antiguedad > socio2.Antiguedad And
socio1.Antiguedad > socio3.Antiguedad Then
Console.WriteLine("Socio com mayor antiguedad:" & socio1.Nombre)
Else
If socio2.Antiguedad > socio3.Antiguedad Then
Console.WriteLine("Socio com mayor antiguedad:" & socio2.Nombre)
Else
Console.WriteLine("Socio com mayor antiguedad:" & socio3.Nombre)
End If
End If
End Sub
End Class
Sub Main()
Dim club1 As New Club()
club1.MayorAntiguedad()
Console.ReadKey()
End Sub
End Module