martes, mayo 09, 2006

Constructores y Sobrecargos

Constructores de Clases

Te puedes encontrar con casos en el que después de haber creado un objeto, después tengas que cambiar un valor casi inmediatamente. Por ejemplo, si continuamos usando el código de la clase Horse:
Module Module1
Sub Main ()
Sub Main()
Dim h As New Horse
With h
.m_color = "White"
.m_name = "Bucefalo"
.m_height = 1.9
End With
Console.WriteLine("Nombre {0}", h.m_name)
Console.WriteLine("Color {0}", h.m_color)
Console.WriteLine("Altura {0}", h.height)
Console.ReadLine()
End Sub
End Module

El ejemplo es muy común: Crear un objeto y cambiarle los valores para estos campos. Esta tarea se vuelve tediosa, especialmente para las clases con un gran numero de campos. Esa es una de las razones por la cual se utilizan los constructores de clases ( o constructores ) y fueron introducidos en los lenguajes Orientados a Objetos. Un constructor es un procedimiento Sub Especial, el cual se llama con New , el cual permite a un nuevo objeto ser inicializado de una cierta manera. El siguiente ejemplo nos muestra la clase Horse con un constructor.

Public Class Horse
Public m_name As String
Public m_color as String
Friend m_height As Single = 1.5

Public Sub New (ByVal name As String, ByVal color As String, ByVal height As Single)
m_name = name
m_color = color
m_height = height
End Sub
End Class

El Constructor es un procedimiento Sub normal, excepto que tiene una palabra especial llamada (New), y debe de ser declarada como parte de la clase. Los procedimientos de las Clases y las funciones son usualmente conocidos como Métodos de las Clases (o Métodos). Es por eso, que los constructores son un tipo especial de método. Lo puedes declarar con cualquier argumento que creas apropiado para la clase. El constructor será llamado cuando construyas un nuevo objeto al cual le pasaras los parámetros que coincidan con la lista de argumentos.


Module Module1
Sub Main ()
Dim h as Horse = New Horse (“Lightning”, ”Brown”, 1.9)
Console.WriteLine("Nombre {0}", h.m_name)
Console.WriteLine("Color {0}", h.m_color)
Console.WriteLine("Altura {0}", h.height)
Console.ReadLine()
End Sub
End Module


Dim h as Horse
h = New Horse (“Lightning”, ”Brown”, 1.9)


El constructor se ejecutará en ambos casos, con los argumentos enviados. Un constructor es un Sub Procedimiento regular, y puede contener otros enunciados que pueden ser parte de un procedimiento. Si quisiéramos evaluar un valor para la altura dentro de los limites rasonables (por lo menos un metro y en el ultimo de los casos 2.5 metros de alto). Podriamos modificar el codigo de la siguiente manera.

Public Class Horse
Public m_name As String
Public m_color As String
Public m_height As Single = 1.5

Public Sub New(ByVal name As String, ByVal color As String, ByVal height As Single)
m_name = name
m_color = color
If 1 <= height And height <= 2.5 Then
m_height = height
End If
End Sub
End Class


Si son estas condiciones (la altura entre 1 y 2.5) el campo m_height será cambiado al del parametro; de otra manera tendra los valores por default de 1.5.

En UML se representaría el método de la clase (conocida en UML como operación) en el tercer compartimiento de la clase como se muestra.

Horse
+m_name: String
+m_color: String
m_height: Single
+New ()

Que pasaria en nuestro ejemplo si quisiéramos construir un Objeto llamado Horse y algunas veces mandarle solo 2 argumentos y otras 3. Tenemos dos opciones:

• Podríamos usar un constructor con argumentos opcionales
• Podríamos tener mas de un constructor

Los dos ejemplos serán ilustrados;


Public Class Horse
Public m_name As String
Public m_color As String
Public m_height As Single = 1.5

Public Sub New(ByVal name As String, Optional ByVal color As String = "", Optional ByVal height As Single = 0)
m_name = name
m_color = color
If 1 <= height And height <= 2.5 Then
m_height = height
End If
End Sub
End Class

En este caso declaramos los dos ultimos argumentos opcionales, podriamos llamar al constructor como:
Dim h As Horse = New Horse("Lightning")
Dim h As Horse = New Horse("Lightning", , 2.4)
Dim h As Horse = New Horse("Lightning", "Brown")
Dim h As Horse = New Horse("Lightning", "Brown", 2.4)

La segunda solución de este problema envuelve el uso de Metodos sobrecargo. Metodos Sobrecargo son metodos que tienen el mismo nombre pero que tienen un código diferente. Cuando uno de estos metodos sobrecargados es llamado, el compilador determinará cual de ellos llamar, basado en el código (numero, orden, y tipo de los parámetros que son enviados)

Si tienes dos constructores con el mismo nombre debes especificar Sobrecargo para ambos, de otra manera el programa no se compilara.

Public Class Horse
Public m_name As String
Public m_color As String
Friend m_height As Single = 1.5

Public Sub New(ByVal name As String, ByVal color As String, ByVal height As Single)
m_name = name
m_color = color
If 1 <= height And height <= 2.5 Then
m_height = height
End If
End Sub
*********************************
Public Sub New(ByVal name As String, ByVal color As String)
m_name = name
m_color = color
End Sub
End Class
************************************
Module Module1
Sub Main()
Dim h As Horse
h = New Horse("nombre", "Black", 1.8)
MsgBox(h.m_height)
End Sub
End Module


Bibliografia VB .NET by Example p .246-250