martes, mayo 30, 2006

Herencia

Mexicali, Baja California a 26 de Mayo de 2006.
¿Qué es la herencia?
Azumamos que necesitamos modelar y programar un sistema de Recursos Humanos (RH), el cual maneja empleados de la compañía y clientes, entre otras entidades. La aproximación basada de lo que conocemos hoy en día sería diseñar dos clases: una para los empleados y otra para los clientes. Esto se vería como en el diagrama siguiente e implementado de la siguiente manera.

Empleado
-nombre: String
-fechanac: Date
-email: String
-Salario: Decimal

+New (nombre : String)

Cliente
-nombre: String
-fechanac: Date
-email: String
-compañia : String
+New (name : String)

La implementación de la clase empleada seria de la siguiente manera.
Public Class Empleado
Private m_nombre As String
Private m_fechanac As Date
Private m_email As String
Private m_salario As Decimal

Public Property nombre() As String
Get
Return m_nombre
End Get
Set(ByVal Value As String)
m_nombre = Value
End Set
End Property

Public Property fechanac() As Date
Get
Return m_fechanac
End Get
Set(ByVal Value As Date)
m_fechanac = Value
End Set
End Property

Public Property email() As String
Get
Return m_email
End Get
Set(ByVal Value As String)
m_email = Value
End Set
End Property
Public Property salario() As Decimal
Get
Return m_salario
End Get
Set(ByVal Value As Decimal)
m_salario = Value
End Set
End Property
End Class


Public Class cliente
Private m_nombre As String
Private m_fechanac As Date
Private m_email As String
Private m_compania As String

Public Property nombre() As String
Get
Return m_nombre
End Get
Set(ByVal Value As String)
m_nombre = Value
End Set
End Property

Public Property fechanac() As Date
Get
Return m_fechanac
End Get
Set(ByVal Value As Date)
m_fechanac = Value
End Set
End Property

Public Property email() As String
Get
Return m_email
End Get
Set(ByVal Value As String)
m_email = Value
End Set
End Property

Public Property compania() As String
Get
Return m_compania
End Get
Set(ByVal Value As String)
m_compania = Value
End Set
End Property

End Class


Como habrás notado que una gran parte del código se repite, los campos y las propiedades para nombre, fecha de nacimiento y correo electrónico.

Puntos que observar:
• El código se repite
• Costo en mantenimiento
• Realización de Rutinas muy parecidas para implementar cada clase

Public Sub EnviarFelicitacionesE(ByVal empleado() As Empleado)
Dim e As Empleado
If e.fechanac = Now Then
Console.WriteLine("Se le enviara una tarjeta de felicitacion")
End If
End Sub
Public Sub EnviarFelicitacionesC(ByVal cliente() As cliente)
Dim c As cliente
If c.fechanac = Now Then
Console.WriteLine("Se le enviara una tarjeta de felicitacion")
End If
End Sub


No podemos reutilizar el primer procedimiento para el objeto cliente porque son de tipo diferente como el objeto empleado. Entonces necesitamos un segundo procedimiento. Entre mas clases tengamos que compartan código común, requeriremos mas procedimientos. Como consecuencia el programa se vuelve más complejo.

La herencia resuelve ambos puntos:
• Permite que exista código común en un solo lugar y que no sea duplicado en todas las clases que lo comparten. Esto tambien resuelve el problema de mantenimiento, porque estando en un solo lugar, el código puede ser cambiado. El cambio se verá reflejado en la clase que lo utilice.
• Permite a las clases que comparten un subset de propiedades y métodos que puedan ser tratados en la misma manera.

Entonces, ¿qué es la herencia? Herencia es definida como el proceso de extender la funcionalidad de una clase añadiendo nuevas propiedades y métodos y creando de esta manera una nueva clase. La nueva clase (conocida como una derivada o una clase especializada) contiene todos los métodos y propiedades de la clase original (conocida como la clase base), mas un set de propiedades y métodos que le pertenecen. De la nueva clase se dice que hereda de la clase base. Todos estos términos son equivalentes y pueden ser usados intercambiadamente.

Si tuviéramos una clase llamada Carro el cual representa el concepto general de un carro(un objeto que nos permite transportarnos de un lugar a otro) podríamos subcategorizarlo: Carros compactos, Suburvans, camiones, carros voladores. Todos estos están compartiendo todas las propiedades de un carro, y tienen algunas otras características diferentes y propias.

El proceso recursivo de ir de lo particular a lo general (conocido como generalización, o abstracción) busca un set de clases y determina propiedades y comportamientos similares. Estas propiedades comunes y comportamientos son utilizados para construir una nueva clase. La cual es la generalización o abstracción de las clases particulares.

HERENCIA SIMPLE
¿Cómo es resuelve la herencia el punto de los empleados y los clientes? Bien, Podemos aplicar el proceso de generalización y movernos de lo particular a lo general. En ejemplo vimos que tres de las propiedades eran iguales en las dos clases. Eso significa que podemos tener una clase base llamada Persona, por ejemplo.

Public Class Persona
Private m_nombre As String
Private m_fechanac As Date
Private m_email As String

Public Property nombre() As String
Get
Return m_nombre
End Get
Set(ByVal Value As String)
m_nombre = Value
End Set
End Property


Public Property fechanac() As Date
Get
Return m_fechanac
End Get
Set(ByVal Value As Date)
m_fechanac = Value
End Set
End Property

Public Property email() As String
Get
Return m_email
End Get
Set(ByVal Value As String)
m_email = value
End Set
End Property


End Class

Clase Empleado
Public Class Empleado_h
Inherits Persona

Private m_salario As Decimal

Public Property salario() As Decimal
Get
Return m_salario
End Get
Set(ByVal Value As Decimal)
m_salario = Value
End Set
End Property

End Class


Clase Cliente
Public Class Cliente_h
Inherits Persona

Private m_compania As String
Public Property compania() As String
Get
Return m_compania
End Get
Set(ByVal Value As String)
m_compania = Value
End Set
End Property


End Class

Module Module1

Sub Main()
Dim e As New Empleado_h
e.nombre = "Guillermo"
e.fechanac = #1/1/1950#
e.email = "Guille_50@hotmail.com"
e.salario = 45000

Dim c As New Cliente_h
c.nombre = "Ana"
c.fechanac = #5/5/1982#
c.email = "ana_82@hotmail.com"
c.compania = "la nueva CO"


Console.WriteLine("nombre: {0}, fecha: {1} email: {2} salario: {3}", e.nombre, e.fechanac, e.email, e.salario)
Console.WriteLine("nombre: {0}, fecha: {1} email: {2} compañia: {3}", c.nombre, c.fechanac, c.email, c.compania)
Console.ReadLine()

End Sub

End Module



Bibliografia VB .NET by Example p .306-312