Colaboraciones en el Guille

Ideología y Desarrollo de Clases .net

[primera entrega]

 

Fecha: 25/Dic/2005 (25-12-05)
Autor: Percy Reyes Paredes - bigpercynet@hotmail.com

percy's blog - percy's artículos



Objetivo

Muchos hemos escuchado hablar de clases, herencia, polimorfismos, pero pocos sabemos trabajar con ellos correctamente. Pues bien, el objetivo de este artículo es enseñarle cuándo, cómo, porqué, dónde y para qué deben trabajarse con clases al momento en que usted se plantea desarrollar un proyecto.

Visual Basic .NET, un lenguaje orientado a objetos

[...y muy poderoso con características realmente avanzadas]

Antes de que me enrolara en esto de la programación orientada a objetos, siempre solía programar en mi "pantallita azul", es decir en C, y como quien no queriendo la cosa eh !, me echaba a programar durante horas en el lenguaje engreído de Microsoft, Visual Basic 5.0 y 6.0, pero bueno, esos fueron tiempos en donde la forma de desarrollar aplicativos, a partir de la versión 6.0, estaba dando un giro tremendo. Cuando empecé a entrarle a la  POO, me gustó lo que ahora se llama herencia. Bueno, sabiendo esto, yo podía crear una clase plantilla, y a partir de este, ir creando mis clases personalizadas, que como veremos más adelante son divertidas de manejar y nos permite aumentar nuestra producción al momento de desarrollar. La programación en C es programación estructurada, mientras que Visual Basic es programación basada en objetos.

En la programación basada en objetos, pueden trabajarse con clases y objetos, pero no existe el concepto de herencia, y es esto, lo que le hace que sea limitado, pues la programación orientada a objetos se apoya en la herencia para ser calificada como tal. Entre los mejores lenguajes del mundo orientado a objetos tenemos a Visual Basic .NET, junto con el resto de lenguajes de la familia de Visual Studio .NET; Visual Basic .NET no es un simple upgrade; es un cambio realmente profundo y radical, que lo convierte en uno de los lenguajes mas poderosos de la actualidad, con características avanzadas, como verdadera orientación a objetos, multi-threading, y la posibilidad de crear Web Services, por nombrar solo tres aspectos. Por cierto, todos aquellos que todavía tengan la idea equivocada de que Visual Basic es un lenguaje para principiantes, finalmente tendrán que callar y agachar sus cabezas.

Puntos a explicar

Algunos de los temas a tratar en este artículo son por ejemplo, Interfaces, Herencia, Polimorfismo, y cómo desarrollar clases abstractas y marcando diferencias con las Interfaces. Además hablaremos de cuando será conveniente trabajar con Interfaces Múltiples, o cuando es necesario desarrollar clases abstractas, o cuál es la importancia de nuestra majestad "Herencia" y sus diversos tipos, cómo también cómo "enrolarnos" en el polimorfismo haciendo uso de la herencia.

¿ cómo entender esto ?

"si no entiendes algo, no permitas que te confundan, entiéndelo a tu modo, pero entiéndelo correctamente. Cuando crees que no lo harás, cree que todo es posible." [Aquí te cuento una historia de mi vida que me hizo entenderlo ...! ]

Generalmente cuando alguien empieza a programar en un lenguaje orientado a objetos, suele confundirse con tantos conceptos que a veces desalientan a seguir. Por ejemplo, si eres programador en Pascal o en C, tal vez te costó algo de trabajo, asimilar todo estos locos conceptos de clases, polimorfismo, herencia, objetos, clases abstractas, sobrecarga... bla, bla, bla !... y más aún si recién estás empezando a programar, y has decidido empezar con algún lenguaje orientado a objetos, de seguro que te estás comiendo o comiste alguna vez la cabeza tratando de entender todo el modelo de programación. Por ejemplo, yo decía en aquellos tiempos cuando mi profesor dictaba la clase, "me laten que las cosas con esto de POO, están consumiendo mi paciencia..", pues todo parece que me había confundido,...y muy repentinamente algo en mi ser me exhortó: mira, esto del modelo POO, es más sencillo de comprender que cualquier otra cosilla, por ejemplo, tu vives en un apartamento verdad ?, salió a la luz una pregunta desde mi interior; yo le contesté: así es. Y continuó... cuando llegues a "tu casa", pide prestado el plano correspondiente, obsérvala muy bien, estúdiala, y analízala, algo más, verifica si es que lo que está dicho en el plano está construido en su totalidad.

Bueno, terminó la clase y salí corriendo hacia mi casa, llegué algo desesperado, y pensé... "espera, un momentito Percy", (quería verificar si es que estaba bien de la cabeza, pues esto de hacerle caso a alguien que te habla desde tu interior, era cosa de locos..), ¿estás bien ? - me pregunté - y me respondí: creo que sí... sin dudarlo más pedí prestado el plano de la casa. Pero antes el dueño, no quizo hacerlo, pues creía que era una especie de raro, un agente secreto o algo así...o que iba a negociarla oscuramente.. luego dijo, para que quieres el plano ?, yo le contesté, "para mover el mundo", el tío se agarró de la cabeza y murmuró: "este rayado se ha fumado de la buena !" - y en eso le sugerí algo, le dije: "Quiere pasar a la historia ?, o prefiere ser olvidado ?", y éste se sonrió diciendo: "en verdad, no, no tengo necesidad"... plop ! plop!, rápidamente, le dije: ¿y si le agregamos un aumento de 10% a la mensualidad del mes?...y este sonrió exclamando: "lo hubieses dicho antes eh !" (todo lo que hacemos por dinero, verdad ? je, je,...). Bueno, creo que el tío estaba comprendiendo que yo estaba loco, y yo comprendía me había rayado el cerebro por no entender dicha clase de  POO ...  cuando derrenpente, dijo: voy a confiar en ti, entró en busca del plano y me la entregó.

Subí a mi cuarto, hice lo que debía hacer, analizar dicho plano. Cuando estaba en el proceso de análisis, apareció ese "yo interior", y comenzó relatar: "Las clases son representaciones abstractas de objetos. Así como un plano puede utilizarse para crearse varios edificios, una única clase puede utilizarse para crear tantos objetos como sea necesario. De la misma manera que un plano define qué partes de un edificio son accesibles a la personas que lo utilizan, las clases también pueden controlar el acceso de los usuarios a los elementos de objetos a través de la encapsulación." Por ejemplo - siguió este "yo interior" -,  en esta casa tú tan sólo tienes acceso a tu habitación, al baño, y al patio, pero no puedes acceder a las habitaciones de las hijas del dueño sin previo permiso o invitación, o como también no puedes acceder al baño de las chicas que se hospedan en esta casa... a lo que voy es a que, tu  espacio de acción está limitado, y no puedes infringirlo. Bueno, esto me bastó para entender. Terminó diciendo: "espero que hayas captado la idea en la que apoya todo este modelo de POO, y échale ganas, y verás que nada es imposible... si necesitas más ayuda, llámame - y de esta manera este yo misterioso desapareció".

Con el pasar del tiempo estuve mejorando mucho, pues han pasado muchísimos años desde que era un nene, y ahora soy un tipo raro y obsesionado por la informática, de la misma manera deseo de corazón que este pequeña historieta de mi vida, te haya ayudado a entender lo que explicaré a "detalle" todo este loco modelo POO. Ahh por cierto !, desde que ese "yo interior" me ayudó, pues más noticias no tuve de él, estuve investigando para saber quien era el tipo, ... hasta que por fin me enteré consultando documentos en la red, que era este señor: el tao de la programación, si no has escuchado hablar de él pues te aconsejo que aprendas de sus paradigmas, es de gran ayuda, y si en verdad darías tu vida por la programación, quedarás agradecido después de informarte al respecto. El tao de la programación es toda una filosofía de un verdadero programador y creo que todo aquel que desea ser un verdadero programador, debe beber de esta agua antes de sumergirse al mar de código... éxitos !.

Un tema muy tocado en los foros

Por otra parte, es común encontrar en los foros preguntas acerca de la personalización de clases, ya sea implementando interfaces o aplicando polimorfismo. Bueno,  este artículo está orientado a todos aquellos amigos que necesitan ayuda al respecto, y al terminar de leer este artículo, usted estará desarrollando sus clases e implementándolos a partir de interfaces predefinidas por el usuario, que como verá más adelante, son mucho más que útiles e importantes, y por cierto son explicados  paso a paso.

Las clases: el "corazón" de .NET y la razón de la POO

Prácticamente todo en .NET está basado en clases, aunque pueden manejarse funciones y variables globales de manera independiente, aconsejo que trate de embeberlos dentro de clases, pues le permitirá administrarlo más fácilmente. Algo a entender es que las clases son la cosa más simple en .NET,  pues en una clase se puede encapsular propiedades, eventos y métodos que usaremos para definir y reutilizar funcionalidades,  aprovechándolos para llevar acabo ciertas tareas de manera sencilla.

Si no hay clases no hay objetos, si no hay clases no es posible la herencia, se definen clases hijas si existen clases de donde heredar, pues si no hay herencia entonces no hay programación orientada a objetos, si no hay programación orientada a objetos entonces estaremos "muertos", así de fácil, muertos ?... bueno, casi muertos debido al agotamiento causado por la no reutilización de funcionalidades que nos brindan las clases.

Déjate de "rodeos", y explícame cómo crear una clase en .NET

Calma eh...!, que ahora te explico.

Una clase es esencialmente una plantilla, a partir del cual puede crear tantos objetos como sea necesario. Una clase define las características de un objeto, incluyendo las propiedades que definen los tipos de datos que ese objeto puede contener y los métodos que describen el comportamiento del objeto. Estas características determinan la manera en que otros objetos pueden acceder y trabajar con los datos que se incluyen en el objeto.

Para definir una clase, se coloca la palabra clave Class antes del nombre de su clase, y después se insertan los miembros de la clase (datos y métodos) entre la definición del nombre de la clase y la instrucción End Class. Si incluye los métodos, entonces el código de cada método también se debe incluir entre la declaración del método y el final del mismo. Una manera de agregar una clase en tu proyecto actual es la siguiente... que tal si te guías de la imagen ?... y así me evito de teclear más, je, je, je.

Creando una clase

luego de darle click en Add Class, debes cambiarle el nombre a  Persona.vb, ...finalmente click en Open y tendremos la clase creada.

Clase Persona.vb

vamos con un ejemplo

El siguiente ejemplo define una nueva clase, Persona (creada más arriba), con dos partes de información relevante asociadas: el nombre de la persona, su fecha de nacimiento y un Método que calcula la edad de la persona. A pesar de que la clase Persona se define en el ejemplo, no existe aún el objeto Persona. Deberán ser creados. Cada parte de la clase serán explicadas más adelante.

Public Class Persona

    'variables de propiedad
    Private _Nombre As String
    Private _FechaNacimiento As Date

    'función que devuelve la edad 
    Public Function Edad() As Integer

        Dim TempEdad As String 'variable temporal
        TempEdad = Microsoft.VisualBasic.DateDiff(DateInterval.Year, _FechaNacimiento, Now())
        Return TempEdad 'devuelve la edad real

    End Function

    'propiedad para manejar la variable _Nombre
    Public Property Nombre() As String

        Get
            Return _Nombre 'devuelve _Nombre
        End Get
        Set(ByVal Value As String)
            _Nombre = Value 'setea _Nombre
        End Set
    End Property

    'Declarar el procedimiento Property para la propiedad FechaNacimiento
    Public Property FechaNacimiento() As Date

        'bloque Get para  devolver el valor de la propiedad FechaNacimiento
        Get
            Return _FechaNacimiento
        End Get

        'bloque Set para asignar valor a la propiedad
        Set(ByVal Value As Date)
            _FechaNacimiento = Value
        End Set

    End Property

End Class


Una clase es un tipo definido por el usuario en contraposición a un tipo proporcionado por el sistema. Al definir una clase, en realidad crea un nuevo tipo en su aplicación. Más arriba hemos dicho que aún no existe el objeto Persona, ya que este debe ser creado o instanciado, debemos generar el objeto. Esto aprenderemos a continuación.

Pero antes, definiremos un objeto

Un objeto es la instancia de una clase. Una clase es la representación abstracta de un concepto en el mundo real, y proporciona la base a partir de la cual creamos instancias de objetos específicos. Como ejemplo, hemos creado una clase que define a un Persona.  Para poder crear un objeto de la clase Persona, debe crear una nueva instancia basada en esa clase. Por ejemplo:

Public PersonaEstudiante As Persona
PersonaEstudiante = new Persona

Cada objeto es un elemento único de la clase en la que se basa. Si una clase es como un molde, entonces un objeto es lo que se crea a partir del molde. La clase es la definición de un elemento; el objeto es el elemento. El molde para una figura de cerámica en particular, es como una clase; la figura es el objeto. Después puede crear una nueva instancia de la clase Persona tendremos un objeto utilizable de este tipo. Anteriormente hemos instanciado un objeto, esta no es la manera más eficiente de hacerlo, aunque sea válida, pues esto no ayudará a la performance del aplicativo en la que se usa. Pues se hace una especia de doble trabajo, primero se crea la referencia, y luego se instancia el objeto. Esto no es aconsejable, salvo en otros escenarios que por ahora no vienen al caso. Bueno, otra de la formas de crearlo es la siguiente:

Public PersonaEstudiante as Persona = New Persona()

Si bien es cierto, hasta ahora es posible crear objetos a partir de nuestra clase Persona, pero no lo es menos, el hecho que podemos usarlos, es decir, nuestra clase persona contiene código funcional que podemos aprovechar, y esto se explicará más adelante.  

Esta sería la manera más eficiente de instanciar un objeto:

Public PersonaEstudiante as New Persona()

 

Miembros de la clase y su ámbito

Los elementos de una clase que contienen sus datos y definen su comportamiento, es decir, las propiedades y métodos, reciben el nombre de miembros de la clase, término que usaremos a partir de ahora. Existen dos formas de almacenar los datos o información en una clase: a través de campos de clase y de propiedades. La diferencia entre un campo y una propiedad son concernientemente a preservar la ocultación o encapsulación  del código de la clase.

La accesibilidad para métodos y variables depende en primera instancia de la accesibilidad a la clase a la que pertenecen. Si la clase nos es accesible entonces depende en segunda instancia de la accesibilidad de variables y métodos, que no son más que aquella accesibilidad que depende de los siguientes modificadores que se ponen (o no) delante de la variable en su declaración o del método en su definición.

Public

Da accesibilidad completa a la variable, se puede ver desde la propia clase, dentro y fuera del mismo. Creo que esto no necesita de ejemplificar debido a que es sencillo de entender.

Private

Solo se puede acceder desde la propia clase. Esto viene a ser las variables internas que serán manejadas por la propiedades y métodos de la clase, pero tan sólo dentro de ella. Por ejemplo, las variables de propiedad  _Nombre, _FechaNacimiento tan sólo pueden accederse dentro de la clase Persona. Si usted hereda una clase a partir de esta, se dará cuenta que no tendrá acceso a estas variables debido a que son de ámbito privado.

Protected

Se puede acceder desde la propia clase, y desde cualquier clase heredada. Para ilustrar la funcionalidad, agregaremos a la clase persona que hemos creado anteriormente, una variable protegida _especialidad, la cual podrá ser accedida por la clase derivada.

Public Class Persona

    'variables de propiedad
    Private _Nombre As String
    Private _FechaNacimiento As Date

    'variable protegida
    Protected _especialidad As String

    '....resto de propiedades

    Public Overridable ReadOnly Property Especialidad()
        Get
            Me._especialidad = "Sin especialidad"
        End Get
    End Property

End Class

'de esta clase podremos acceder a la variable protegida _especialidad
Public Class Estudiante : Inherits Persona

    Public Overrides ReadOnly Property Especialidad()
        Get 
'acceso a la variable protegida...
Me._especialidad = "Ingeniería de Sistemas" End Get End Property End Class

 

Friend

La palabra clave Friend proporciona acceso de tipo amigo a uno o varios elementos de programación declarados. Los elementos de tipo amigo son accesibles desde dentro del programa que contiene su declaración  y desde otra sección dentro del mismo ensamblado. Para ejemplificar esto, haga lo siguiente. Usted debe crear una librería de clases, en este debe definir una variable con accesibilidad Friend. Se dará cuenta que después de crear el objeto _objClass1 a partir de la clase Class1, usted podrá tener acceso a la variable amiga _saludo.

accesibilidad Friend

mientras que desde otro proyecto no sería posible, mejor dicho el acceso esta limitado dentro del ensamblado. Para demostrar esto, agregue la referencia para la Librería de clases ClassLibrary1.dll (la cual debe generarlo usted) en el proyecto donde creo la clase  Persona.vb,

ClassLibrary1.dll

luego, copie este código dentro del proyecto.  Pues como verá, usted no tiene acceso a la variable amiga _Saludo, debido a que ya se está saliendo de los limites del ensamblado LibraryClass1.dll.

sin acceso a la variable amiga _Saludo

 

Protected Friend

Esta combinación proporciona acceso de tipo amigo y protegido sobre los elementos declarados, para que sean accesibles desde el mismo ensamblado, desde su propia clase y desde una clase derivada. Creo que ejemplificar esto, queda como tarea para usted, si entendió lo anterior, entonces esta parte supongo que también.

Creación de campos para la clase

Un campo de una clase no es otra cosa que una variable, generalmente con ámbito público, accesible desde el interior de la clase. Citando nuestra clase Persona, podremos observar que contiene dos propiedades y método que manejan el nombre, la fecha de nacimiento y la edad. La manera de manipular la variables de propiedad es sencillo, debemos instanciar un objeto Persona, a continuación de la variable que lo contiene situar un punto (.), y finalmente el nombre de la propiedad o método a manipular.

Dim PersonaEstudiante As New Persona
PersonaEstudiante.Nombre = "Arbis Percy"
Me.TextBox1.Text = PersonaEstudiante.Edad()
Me.TextBox2.Text = PersonaEstudiante.Nombre

 

Creación de propiedades para la clase

Una propiedad en una clase se define, por normal general, mediante dos elementos: una variable de propiedad y un procedimiento de propiedad. La variable de propiedad, tal y como su nombre indica, es una variable con ámbito privado a nivel de la clase, que se encarga de guardar el valor de propiedad. Por su parte el procedimiento de propiedad o Property, es el encargado de actuar de puente entre el código cliente y la variable de propiedad, realizando las operaciones de acceso y asignación de valores a dicha variable.

Por lo tanto, para crear una propiedad en nuestra clase, declararemos en primer lugar una variable Private, y en segundo lugar un procedimiento de tipo Property, que consta de dos bloques: Get, para devolver el valor de la variable de la propiedad (podemos usar la palabre clave Return para devolver el valor); y Set, para asignárselo (aquí debe usar un parámetro con el nombre Value, que contiene el valor para asignárselo). La sintaxis a emplear se muestra en el siguiente código fuente.

Public Class Persona

    'variables de propiedad
    Private _Nombre As String
    Private _FechaNacimiento As Date

    'función que devuelve la edad 
    Public Function Edad() As Integer

        Dim TempEdad As String 'variable temporal
        TempEdad = Microsoft.VisualBasic.DateDiff(DateInterval.Year, _FechaNacimiento, Now())
        Return TempEdad 'devuelve la edad real

    End Function

    'propiedad para manejar la variable _Nombre
    Public Property Nombre() As String

        Get
            Return _Nombre 'devuelve _Nombre
        End Get
        Set(ByVal Value As String)
            _Nombre = Value 'setea _Nombre
        End Set
    End Property

    'Declarar el procedimiento Property para la propiedad FechaNacimiento
    Public Property FechaNacimiento() As Date

        'bloque Get para  devolver el valor de la propiedad FechaNacimiento
        Get
            Return _FechaNacimiento
        End Get

        'bloque Set para asignar valor a la propiedad
        Set(ByVal Value As Date)
            _FechaNacimiento = Value
        End Set

    End Property

End Class

 

Cuando declaramos un procedimiento Property, debemos, al igual que una función, tipificarlo, ya que una de sus labores consiste en la devolución de una valor. Para nuestro ejemplo anterior, se observa que, la propiedad Edad devuelve un valor entero y la propiedad FechaNacimiento devuelve una valor Date. La manera de crear un objeto a partir de esta clase y usarlo, se muestra en el siguiente ejemplo:

Module Demo
Public Sub Main() Dim oPersona As New Persona oPersona.FechaNacimiento = #2/9/1983# Console.WriteLine("La edad es: {0} años", oPersona.Edad.ToString) Console.ReadLine()
End Sub
End Module

el resultado, sencillamente, será: "La edad es 22 años". Te habrás dado cuenta que no hemos realizado "gran cosa", lo único que pretendo es darte un visión clara y sencilla de toda esta parte de las clases .net .

Hemos terminado de explicar esta primera parte. Nos vemos en la siguiente entrega.

MCP Percy Reyes

Microsoft Certified Professional
Estudiante Ing. de Sistemas
Universidad Nacional de Trujillo

Saludos desde Trujillo - Perú

Por favor, califica este artículo en Panoramabox, así me animarás a continuar colaborando contigo.


ir al índice principal del Guille