Archivo de la etiqueta: Clases Base

Hablemos de Herencia (2)


Ya hemos visto en Hablemos de Herencia, los conceptos básicos de este tema.

Analicemos entonces como queda el código de lo ya definido, y algunas variantes al respecto.

Ser vivo.

Por recordar, esta era su representación gráfica.

image

Y así quedaría el código:

VB

Public MustInherit Class SerVivo
    Public Sub Nacer()
    End Sub
    Public Sub Crecer()
    End Sub
    Public Sub Reproducir()
    End Sub
    Public Sub Morir()
    End Sub
    Public MustOverride Sub GenerarEnergía()
End Class

CS

public abstract class SerVivo
{
    public void Nacer()
    {
    }
    public void Crecer()
    {
    }
    public void Reproducir()
    {
    }
    public void Morir()
    {
    }
    public abstract void GenerarEnergía();
}

Como vemos, la clase se declara como que debe heredarse (MustInherit en VB, abstract en C#), y luego se definen los distintos métodos.

El método que debe codificarse en las clases derivadas, se declara como MustOverride (VB), abstract (C#).

Presta atención que, en C#, el mismo término significa cosas distintas, dependiendo del entorno. No es muy común, pero a veces pasa.

En ambos casos, los métodos que deben codificarse en los descendientes, no tienen cuerpo (No hay End Sub en VB, ni llaves en C#, donde termina con punto y coma).

Las clases derivadas.

image

VB

Public Class Vegetal
    Inherits SerVivo
    Public Overrides Sub GenerarEnergía()
        Fotosíntesis()
    End Sub
    Private Sub Fotosíntesis()
    End Sub
End Class

CS

public class Vegetal : SerVivo
{
    public override void GenerarEnergía()
    {
        Fotosíntesis();
    }
    private void Fotosíntesis()
    {
    }
}

Como vemos, ese método “no implementado” en la clase base, se debe terminar de definir en las clases derivadas (“sobre escribirse”).

En ambos lenguajes, la definición es casi idéntica.

En Visual Studio, al definir que una clase hereda de otra, el entorno te indica “como error” que deben escribirse esos métodos y hasta se ofrece a generarte el esquema base Sonrisa

Se indica que una clase hereda por distintos mecanismos, según el idioma.

En Visual Basic, se declara taxativamente que hereda “Inherits” de otra clase.

En C#, ese concepto se “entiende” porque luego de la declaración de la clase, se sigue con dos puntos, y el nombre de la clase que se hereda.

A partir de aquí, se podrá seguir heredando para cubrir, progresivamente, mayores especializaciones y características.

Lo interesante, es que cualquier modificación de una clase base, se reflejará (en realidad, se “heredará”), en cualquiera de sus derivadas.

Esto de la herencia, en definitiva, nos permite “comprometer” que nuestro código se vea siempre de la misma forma, en todas las clases derivadas/heredadas. Aún cuando una clase heredada presente más miembros, si la “vemos” como una clase base, siempre encontraremos los mismos métodos.

Una clase vegetal vista como ser vivo

Una clase animal vista como ser vivo

Pero hay otra forma de “comprometer” tu código para cumplir un convenio.

Eso es tema de la siguiente publicación.

Incluido en el envase… (del .Net Framework)


Realizar programas es como cocinar.  (Idea que he “robado” al amigo Miguel Egea, @miguelEgea https://twitter.com/miguelEgea). Combinar distintos ingredientes para obtener un resultado novedoso.

Comenzando con las sentencias, tipos de datos, variables que hemos visto previamente, hasta componentes pre armados “listos para usar”

Sin embargo, mucho de ese código debe realizar tareas complejas, de mucho cuidado, como manipular posiciones de memoria, acceder a recursos de hardware o sencillamente, realizar operaciones complicadas.

Esos conjuntos de códigos vienen pre armados y encapsulados en el .Net Framework,

El .Net Framework.

Podríamos describir el .Net Framework como constituido por 3 partes:

  • El motor de ejecución común (CLR).
  • El Conjunto de clases base
  • Los lenguajes de programación compatibles (en realidad, no solo los lenguajes, sino también sus compiladores)

El Motor de Ejecución Común.

Diagrama del CLR

Como vemos en la imagen, hay una serie de componentes que integran el CLR de modo de implementar en forma encapsulada, las acciones de bajo nivel.

Para destacar que hay un componente responsable de “cargar” los tipos (clases) en memoria asegurándose de darles el espacio suficiente, asignarle un identificador único, etc.

O el compilador de MSIL (que merece una aclaración): Para permitir que el mismo código pueda ejecutarse en distintas configuraciones de computación, éste no se compila en código binario sino en un “lenguaje intermedio” que luego, cuando se comienza a ejecutar, se termina de compilar a código nativo.  Aunque parezca más laborioso y demorado, la realidad es que es imperceptible para el usuario. Además, si realmente es preocupante este hecho (que no se justifica realmente), existe, entre las herramientas del .Net Framework un “compilador a código nativo” que se puede ejecutar en la máquina destino, para dejarlo ya listo. (NGEN.exe).

Otra parte interesante es el GC (Garbage collector, o recolector de residuos). Una de las problemáticas  en los anteriores mecanismos de programación de C++ a Visual Basic, era la posibilidad de “descuidar” las instancias de los objetos creados, que dejaban de ser referenciados por el código del programa… pero nunca se descargaba de memoria. El GC se encarga de ver revisar cada instancia y ver si “hay algún código en ejecución que la conozca”. Si no, se encarga de eliminarla. (En realidad, si la clase utilizara recursos de bajo nivel, primero se encarga de disponer dichos recursos para que no sigan en uso, y luego, descargar la instancia de la memoria). Otra consecuencia de esto, que se debe tener en cuenta, es que si un proceso crea una instancia de una clase, es factible que se le entregue una que está “en espera” en el GC para ser destruida, que es más rápido. Por ello se recomienda que no se asuma que las variables tengan valores predeterminados.  Es importante inicializar las variables en cada creación.

La biblioteca de Clases Base.

Biblioteca de Clases Base

Son todas aquellas clases que nos permiten interactuar directa o indirectamente con los recursos electrónicos de la máquina, memoria, procesador, periféricos, disco, y otros más complejos, pero, en todos los casos, el fundamento sobre el que se basa toda la ejecución.

Por ejemplo, los tipos de datos están todos definidos allí.

Vemos que además de las BCL, existen otros conjuntos ya pre armados, de funcionalidades específicas como manejo de datos, manipulación de XML, y especializaciones para funcionalidades de alto nivel, como formularios de ventanas de Windows, aplicaciones Web, etc.

La siguiente es una lista de los conjuntos de funcionalidades más importantes incluidas en la BCL.

  • Administración de componentes Web que corren tanto en el servidor como en el cliente (ASP.NET)
  • Administración de memoria
  • Aleatoriedad
  • Auto descripción de código
  • Cifrado de datos
  • Compilación de código
  • Generación de código
  • Herramientas de despliegue de gráficos (GDI+)
  • Herramientas de seguridad e integración con la seguridad del sistema operativo
  • Interacción con el API Win32 o Windows API.
  • Interacción con los dispositivos periféricos
  • Interacción con otras aplicaciones
  • Manejo de arreglos de datos y colecciones
  • Manejo de cadenas de caracteres y expresiones regulares
  • Manejo de datos (ADO.NET)
  • Manejo de idiomas
  • Manejo de tipos de datos unificado
  • Manejo del sistema de ventanas
  • Manejo y administración de excepciones
  • Manipulación de archivos de imágenes
  • Manipulación de fechas, zonas horarias y periodos de tiempo
  • Operaciones aritméticas
  • Transmisión y recepción de datos por distintos medios (XML, TCP/IP)

Pero.. ¿Que es una clase?.

En definitiva es la plantilla que incluye variables, propiedades, métodos y eventos relacionados con una funcionalidad específica. 

Cuando necesitas usar una, creas una instancia y luego comienzas a utilizarla.

Existe además una forma especial de clases de instanciación automática, que sirven para realizar tareas. En ellas, cuando se utiliza uno de sus miembros (propiedad o método), se instancia sola y sirve para cualquier otro uso durante la ejecución del programa completo. Se denominan clases estáticas.

Espacios de Nombres. (Namespaces)

Teniendo tantas variedades y posibilidades, se podría transformar en una maraña incontrolable el conjunto de código.

Para mantener el orden, se agrupan en espacios de nombres, que además pueden ser jerárquicos.

Así, por ejemplo, las clases que permiten conectarse con un servidor de datos SQL Server están en:

System.Data.SqlClient

Esto permite además agrupar conjuntos de clases por “autor” (veremos más adelante que los permisos de ejecución de un componente pueden administrarse basados en espacios de nombres y/o ensamblados, que veremos ahora mismo.

Así, cosas que Microsoft ha hecho específicos, están dentro de un espacio de nombres que comienza precisamente por Microsoft como por ejemplo:

Microsoft.Win32.SafeHandles

… y también podremos crear los nuestros.

Ensamblados.

Ensamblado NET

Uno o más espacios de nombres, se compilan en bibliotecas de carga dinámica (archivo de extensión DLL),  que ante tantas combinatorias posibles, necesitan ser más identificables, requieren descriptores de sus contenidos, pueden utilizar textos, imágenes y otros recursos que se utilizan por las clases. El conjunto de todos esos elementos se denomina Ensamblado.

Las descripciones se contienen en un manifiesto, que describen unívocamente el ensamblado completo, y los metadatos de tipo, que contienen la descripción de cada una de las clases (recordemos, una clase es la plantilla de in Tipo), contenidas en el ensamblado.

El ensamblado completo queda entonces contenido dentro del archivo dll.

Un detalle: Nada condiciona que un espacio de nombres este contenido en un ensamblado. así, tipos distintos de un mismo espacio de nombres, pueden estar contenidos en distintos ensamblados. Eso asegura extensibilidad en la funcionalidad. Si yo necesito, digamos, un par de clases del espacio de nombres “espacio1” debo definir una referencia al ensamblado (y su correspondiente dll) que la contiene.

Luego, si necesito otra clase, puede ser que “No la encuentre” dado que su funcionalidad, más específica, se haya incluido en otro ensamblado (aunque pertenezca al mismo espacio de nombres). Deberé entonces agregar una referencia al otro ensamblado.

 

En la próxima entrega, empezaremos ya a recorrer las BCL más importantes y generar código de herramientas útiles en general.