Clases con Clase (C#, nosecuántos)

Hoy vamos a hablar un poco de las clases. Como todo el mundo sabe la herencia sin polimorfismo no es herencia y el polimorfismo sin virtualización, tampoco. Pero puede ocurrir que malinterpretemos cierto comportamiento si no tenemos clara la estructura jerárquica de las mismas, ya que dependiendo del lenguaje que utilicemos la declaración de las mismas podría resultar confusa en algunas situaciones. C# viene en nuestra ayuda forzando nos en cierta medida a especificar el tipo de clase que queremos.


Si queremos crear una clase abstracta, es decir, aquella de la que no se puede instanciar y que meramente nos sirva de base polimórfica, debemos definirla con la palabra abstract; de esta forma el compilador sabe que no debe instanciar de ella y a nosotros nos resulta mucho más fácil identificar el tipo de clase.


También podríamos querer una clase de la cual no se pueda heredar, característica que no suele estar disponible habitualmente en otros lenguajes. En este caso tenemos que sellarla mediante la palabra reservada sealed.


Y todavía tenemos un nuevo tipo de clases cuya finalidad es la de definir un interfaz común. En lenguajes más tradicionales esto se hace teniendo lo que se llama una clase virtual pura, es decir, una clase cuyos miembros están todos asignados a cero. Pero el Net nos lo pone mucho más fácil, ya que nos permite declarar un tipo de clase llamado interfaz mediante la palabra reservada Interface.


Cuando utilizamos la herencia también nos deshacemos de las posibles confusiones a la hora de ocultar o redefinir un método mediante el modificador new, evitando así la posibilidad de tener un nombre de método que queremos nuevo pero que ya existe en alguna clase base. Si sobrescribimos algún método existente sin colocar el modificador el compilador nos avisará, y también lo hará si lo colocamos y dicho método no está en ninguna clase base. Y de igual manera que podemos ocultar un método miembro existente también podemos ocultar el nombre de una clase anidada utilizando el mismo modificador. Si queremos acceder al método culto desde nuestra clase simplemente debemos cualificarlo con su firma completa.


Es típico que la accesibilidad de una clase o de un método sea público, protegido o privado, pero el Net nos amplía las posibilidades añadiendo el acceso a interno y cambiando en cierta medida la definición de acceso público. Ahora un acceso público significa que dicho elemento o clase estará disponible globalmente tanto en el ensamblado en el cual está definida como en cualquier otro ensamblado siempre y cuando incluyamos su espacio de nombre, y el acceso interno indica que dicho elemento sólo estará disponible dentro del ensamblado actual. También podemos definir la accesibilidad protegida e interna simultáneamente.


Nombres de miembro reservados


Como cosa curiosa tenemos que decir algo sobre las propiedades, los eventos y los indexadores. Cuando definimos una propiedad que se llama, por poner un ejemplo, nombre, automáticamente quedan reservados dos nombres de método, a saber, get_hola y set_hola, independientemente de sea dicha propiedad es de sólo lectura o sólo escritura. En C++/CLI la cosa está mucho más clara y nítida, ya que somos nosotros los que directamente definimos los métodos get y set.


Lo mismo ocurre en con los indexadores, y también con los eventos. En el caso de estos últimos los dos nombres de miembros reservados son add_<nombre> y remove<nombre>. También está reservada la firma void Finalize(); utilizada en aquellas clases que dispongan de destructor.


Constantes, elementos estáticos y volátiles


El uso de un elemento estático para que sea compartido entre todas las instancias de la misma clase es ya conocido y ampliamente utilizado, pero dadas las características especiales del C# el uso de este tipo de elementos también se suele utilizar en sustitución de las constantes en aquellas situaciones en las que el uso de un elemento constante en no está definido.


Porque disponemos de elementos definidos como constantes (mediante la palabra reservada const) siempre y cuando éstos sean tipos básicos o clases-valor, y no está permitido el uso de clases referencia constantes. Esto es una limitación del motor de ejecución Net, limitación que podemos soslayar utilizando campus de solo lectura y campos estáticos de solo lectura, aunque me queda por determinar si dichos valores realmente se sustituyen en el código como números mágicos (que es el efecto deseado) o llevan consigo toda la parafernalia de la verificación de tipos en tiempo de ejecución.


Un tipo de solo lectura se declara mediante la palabra reservada readonly y debe ser inicializado en su declaración, aunque hay ciertos tipos que no podrán serlo. En este caso debemos definirlos como estáticos y de solo lectura mediante el uso de las palabras reservadas static readonly, y en este caso podemos realizar su inicialización en el constructor estático o directamente durante la declaración.


Personalmente opino que todo lo de arriba no es más que una deficiencia del lenguaje C#, que muy bien podría haberse solucionado ampliando el uso del preprocesador o la inclusión de las características pertinentes dentro del motor Net.


En contrapartida con todo lo anterior disponemos de las variables volátiles, que deben ser utilizadas para los tipos básicos que sean modificados por varios hilos, evitando así toda la parafernalia de objetor de sincronización y semáforos.


Pasó de un número variable de argumentos


Tradicionalmente se ha permitido que lenguajes de muy alto nivel (y también de muy bajo nivel) permitan alguna forma de pasar un número variable de argumentos en un método. El C# lo soluciona de forma elegante aunque a mi modo de ver bastante limitada.


Si queremos que un método pueda recibir un número variable de argumentos tan sólo debemos especificar en su firma que va a recibir un array de una sola dimensión. La implementación de dicho método deberá recorrer todos y cada uno de sus elementos de la matriz y realizar las acciones oportunas con cada uno de ellos. Dadas las características polimórficas del C# si pasamos un array de objetos podremos convertir fácilmente estos a su tipo real mediante reflexión.


A la hora de llamar a este método podremos hacerlo tanto mediante el uso de un array como por el número de parámetros adecuado como se muestra en el fragmento de código siguiente.


void HazAlgo(params object[] args)
{
  
foreach(object o in args)
    

}

Object[] o=new object[]={1.»dos»,3,»cuatro»};
HazAlgo(o);
HazAlgo(1,»dos»,3,»cuatro»);

Un comentario sobre “Clases con Clase (C#, nosecuántos)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *