{ WillyXoft .NET }

Blog de Willy Mejía sobre Microsoft .NET Framework y temas relacionados...

<December 2008>
SuMoTuWeThFrSa
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910


Navigation

e-Grupos / Foros

Web/Blog Amigos

INETA & MUGs

Subscriptions

News

WillyXoft

Post Categories

Article Categories



POO con Visual Basic .NET Parte 2 Rated Good [4 out of 5].

Programación Orientada a Objetos con Visual Basic .NET
Parte II

Por Willy Mejía [WillyXoft]

POO con VB.NET

En primer lugar debemos tener en cuenta que todo en el .NET Framework, y por ende en Visual Basic .NET, puede ser tratado como un objeto. Por ejemplo el tipo Integer ahora posee propiedaes y métodos, tales como MaxValue que regresa el valor máximo que puede contener:

Dim i as Integer
MsgBox(i.MaxValue)

Con VB.NET observamos que tipos "básicos" como Integer se tratan de objetos. Del mismo modo, entidades tales como los formularios y controles son todos instancias de alguna clase, es decir: objetos. Por ende una de las primeras cosas que debemos tomar en cuenta es que el modo de tratar a éstos tipos a cambiado con respecto a VB6 y versiones anteriores.

No obstante que todo puede ser tratado como un objeto, existen tipos por valor y por referencia. Los tipos por valor como Integer no devuelven una referencia sino sólo el valor que contiene, y sus método en lugar de modificar su estado o el valor contenido, sólo devuelven el valor modificado.

Definiendo Clases

Dado que los objetos se crean a partir de clases, son las clases las que tenemos que diseñar y construir. Para ellos debemos recordar que las clases se componen de los siguientes elementos o miembros:

  • Atributos: Representan la información que contiene un objeto (estado).
  • Métodos: Representan acciones que un objeto puede realizar.

Adicionalemente las clases puede definir Eventos, que son notificaciones que un objeto recibe de, o transmite a, otros objetos, cuando se produce un acontecimiento específico.

También existen los miembros compartidos de clase, que pueden utilizarse en instancias de una clase y en variables de objeto declaradas como tipo de la clase. En otras palabras, no requieren una instancia de clase en específico para realizar su cometido.

VB5 introdujo el concepto de módulo de clase en el cual podían definirse clases simples, una por cada múdulo. Con VB.NET se pueden crear cualquier número de clases en un mismo archivo, no obstante es una buena práctica el definir clases en archivos separados. Para definir una clase se emplea, como entonces, la palabra clave Class:

Class CCliente
    'TODO: Miembros de clase
End Class
Si se requiere, también se pueden crear clases anidadas, es decir, clases dentro de otras clases. Que resulta útil cuando cierto objeto va a ser utilizado al interior de otro y nunca fuera del mismo.

Ahora como experimento abra el entorno de Visual Studio (o bien su Visual Basic .NET Standard ó VB2005 Express) y genere una nueva Aplicación Windows. Despues abra el archivo de código fuente del formulario y observe que inicia con algo como:

Public Class Form1

Lo cual implica que el formulario se construye a partir de una Clase.

Incluso ahora los Modulos de código son clases, la única diferencia es que se trata de Clases estáticas con mienbros compartidos.

Ahora pasemos a definir los miembros de la clase: los atributos y métodos

Atributos

Los atributos de clase se representan mediante Campos o Propiedades. Los Campos se implementan mediante variables públicas que se pueden leer y establecer directamente desde el exterior de la clase.

Public Nombre As String

Mientras que las Propiedades se recuperan y establecen como los Campos, pero se implementan mediante procedimientos Property Get y Property Set. El acceso a los atributos mediante procedimientos proporciona un mayor control sobre la forma en que se establecen o se devuelven los valores de los atributos; esto ayuda a aislar los datos y permite validar valores antes de ser asignados o recuperados.

Por ello también podriamos ver a las Propiedades como métodos de clase ya que encajan en la definición y propósito de los mismos. De hecho en lenguajes como Java no existen las propiedades y las operaciones de asignación (Set) y obtención (Get) del valor de los atributos se realizan mediante métodos.

Se puede definir una propiedad de la siguiente manera:

' Ahora el atributo es Privado
Private strNombre As String
' Para ser accesible mediante la Propiedad
Property Nombre() As String
    Get
        Return strNombre
    End Get
    Set(ByVal Value As String)
        strName = Value
    End Set
End Property

El procedimiento Get devuelve el valor de la propiedad, mientras que el procedimiento Set le asigna el valor a la propiedad. Observe que dado que todo en .NET es un objeto ya no es necesario la sentencia Let, así como que ambos procedimientos están contenidos dentro una sola sentencia Property, lo cual hace mas fácil de manipular y mantener el código de la Propiedad.

En aplicaciones de N-capas las clases generalmente se diseñan sin estado, es decir sin propiedades.

Métodos

Los métodos de una clase en VB.NET se implementan mediante procedimientos o subrutinas (Sub) y funciones (Function) declarados dentro de una clase, de la misma manera como se realizaba anteriormente. No obstante ahora para devolver el valor desde una función se utiliza la palabra clave Return en lugar del nombre de la misma, el cual además se puede utilizar en los diferentes puntos de salida de la función:

Function Hola() As String
    If Nombre <> "" Then
        Return "Hola " & Nombre
    Else
        Return "Hola Mundo"
    End If
End Function
Aún se puede seguir utilizando, por compatibilidad hacia atrás, el nombre de la función para devolver el valor. Mas es recomendable utilizar Return dado que tiene un comportamiento más estructurado.

Constructores y Destructores

Los constructores y destructores son métodos especiales que como su nombre indica, se emplean para la inicialización del objeto durante su construcción, y la limpieza del mismo durante su destrucción.

En VB5 y VB6 las tareas de inicialización se implementan en el procedimiento Initialize. Este procedimiento no permite el paso de parámetro alguno, lo cual dificulta establecer el estado inicial del objeto durante su creación. Visual Basic .NET sin embargo introduce verdaderos constructores que se defininen con el procedimiento New:

Sub New()
    'Código de Inicializacion
End Sub
Esta es la definición del constructor por omisión, la cual será agregada por VB si no se define de manera explícita constructor alguno en una clase.

Dicho procedimiento permite la definicón de parámetros, lo que significa que pueden crearse constructores parametrizados.

Sub New(Nombre String)
    strNombre = Nombre
End Sub
Con VB6 y anteriores los parámetros por omisión eran de paso por referencia, con VB.NET ahora son por valor.

Y aun hay más, una clase puede tener cualquier cantidad de constructores, siempre y cuando tengan diferente tipo y/o número de parámetros.

Sub New()
...
Sub New(Nombre As String)
...
Sub New(Nombre As String, Edad As Integer)
A ésta característica se le conoce como sobrecarga de métodos de clase, por lo que se dice del método que emplea la misma que es un método sobrecargado, y en el caso de una clase con más de un constructor se dice que tiene un constructor sobrecargado.

En cuanto al destructor, Visual Basic .NET lo provee mediante el procedimiento Finalize que no puede ser sobrecargado, es decir, que únicamente puede existir un sólo destructor Finalize en cada clase.

Overrides Protected Sub Finalize()

Finalize está protegido (detalles sobre ésto mas adelante en Encapsulación) lo que implica que no puede invocarse de manera directa por el consumidor de la clase. La ejecución del código del destructor corre a cargo del Colector de Basura del .NET Framework (GC: Garbage Collector) una vez que el objeto pase a ser inaccesible. La excepción a la regla obedece al hecho que todas las implementaciones de Finalize en una clase derivada deben llamar a la correspondiente implementación de Finalize de la clase base (eso implica Overrides que veremos más adelante en Herencia). Este es el único caso en el que se permite al código de la aplicación llamar a Finalize.

Hay que tener mucho cuidado con las operaciones de Finalize, dado que su ejecución corre a cargo del GC tienen las siguientes limitaciones:

  • No se garantiza la liberación de recursos en un momento concreto; y
  • No se garantiza que los finalizadores de dos objetos se ejecuten en un orden determinado, aunque un objeto haga referencia al otro.
Por ello aquellas clases que requieran la liberación controlada de recursos deben implementar la interface IDisposable e implementar el método Dispose() con el código necesario para la liberación de los recursos. A diferencia de Finalize, Dispose si puede invocarse de manera manual. Se abordará el tema de Dispose mas adelante.

Creando y Destruyendo Objetos

Para crear un objeto, seguimos utilizando la cláusula New:

Private mCliente As CCliente
mCliente = New CCliente()
Observe que ya no se utiliza más la palabra Set al asignar la variable al objeto, dado que ahora todo es un objeto ya no es necesaria la diferenciación y se excluido del lenguaje.

También, como antes, se pueden realizar ambas operaciones en la misma línea:

Private mCliente As CCliente = New CCliente()

O incluso de la manera abreviada:

Private mCliente As New CCliente()
Aquí existe otra diferencia, con VB6 y anteriores este tipo de asignación inicializaban el objeto en Nothing y creaba el objeto sólo hasta que era utilizado, con VB.NET el objeto es creado desde el primer momento, cuando se utiliza la cláusula New. Por ello se recomienda dejar de lado ésta práctica y crear el objeto cuando se vaya a utilizar.

Si el constructor admite parámetros se colocan entre los paréntesis:

mCliente = New CCliente("Luz", 18)

Como hemos visto la destrucción del objeto corre a cargo del Recolector de Basura (GC) por lo que no podemos destruir un objeto manualmente. Pero lo que sí podemos hacer una vez utilizado el objeto, es invocar el método Dispose, si está disponible en el objeto.

mCliente.Dispose()
No se confunda, al momento de invocar el método Dispose sólo se liberan los recursos utilizados por el objeto, mas el objeto no es destruido.

Eventos

Se pueden utilizar los eventos para notificar a los objetos sobro la ocurrencia de alguna situación especial. Los eventos se agregan a una clase con la instrucción Events. La declaración incluye el nombre del evento y los argumentos que utiliza.

Event MiEvento(ByVal sender As System.Object, _ 
   ByVal NumEvento As Integer)

Y al igual que antes, para conseguir que se produzca el evento, se debe utilizar la instrucción RaiseEvent.

RaiseEvent MiEvento(Me, NumEvento)
Los eventos deben producirse dentro del ámbito en el que se han declarado. Por ejemplo, una clase derivada no puede producir eventos heredados de una clase base.

A diferencia de VB6 y anteriores, para consumir un evento se necesita asociar de manera explícita el evento a un método (procedimiento) controlador de evento (event handler) para lo cual se utiliza la cláusula Handles en combinación con WithEvents.

Friend WithEvents Button1 As System.Windows.Forms.Button
Protected Sub Button1_Click(ByVal sender As System.Object, _ 
   ByVal e As System.EventArgs) Handles Button1.Click
End Sub

También se puede asociar un evento a un método controlador de evento con la instrucción AddHandler que permite que un evento pueda asignarse a cualquier número de controladores de eventos.

AddHandler MyObject.Event1, AddressOf Me.MyEventHandler

Además, los métodos que controlan determinados eventos pueden modificarse de manera dinámica, si se utiliza en conjunto con la instrucción RemoveHandler, que remueve la asociación entre un evento y su controlador.

RemoveHandler MyObject.Event1, AddressOf Me.MyEventHandler

Tanto AddHandler y RemoveHandler toman dos argumentos: el nombre del evento, y una expresión que evalúa a un Delegado con la instrucción AddressOf, la cual devuelve una referencia (apuntador) de un Delegado. Pero eso se verá con detalle más adelante, por el momento sólo pruebe el siguiente ejemplo:

Public Class ClasePublicadora
   Public Event ElEvento()
   Sub ProduceEvento()
      RaiseEvent ElEvento()
   End Sub
End Class
Public Class ClaseConsumidora
   Sub TestEvento()
      Dim Obj As New ClasePublicadora()
      ' Asociamos el evento con un controlador.
      AddHandler Obj.ElEvento, AddressOf ControladorEvento
      ' Provocamos que se produzca el evento...
      Obj.ProduceEvento()
      ' Removemos el controlador.
      RemoveHandler Obj.ElEvento, AddressOf ControladorEvento
      ' Ya no pasa nada...
      Obj.ProduceEvento()
   End Sub
   Sub ControladorEvento()
      System.Windows.Forms.MessageBox.Write("Evento controlado.")
   End Sub
End Class

Para mayor información al respecto léa:  Los delegados y el operador AddressOf.

Continuar con POO con Visual Basic .NET Parte 3

posted on Monday, November 14, 2005 9:14 PM by vbpuntonet





Powered by Dot Net Junkies, by Telligent Systems