Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Clases
Clases.
Introduccin
La Programacin Orientada a Objetos permite realizar grandes programas mediante la
unin de elementos ms simples, que pueden ser diseados y comprobados de manera
independiente del programa que va a usarlos. Muchos de estos elementos podrn ser
reutilizados en otros programas.
A estas piezas, mdulos o "componentes", que interactan entre s cuando se
ejecuta un programa, se les denomina objetos. Los objetos contienen datos y funciones
que actan sobre esos datos.
Durante la ejecucin de un programa, los objetos interactan entre s pasndose
mensajes y devolviendo respuestas a estos mensajes. Es fundamental darse cuenta de
que un objeto no necesita conocer el funcionamiento interno de los dems objetos para
poder interactuar con ellos (igual que el hombre no necesita conocer cmo funciona el
motor de su coche, el televisor o un ordenador para poder utilizarlos), sino que le es
suficiente con saber la forma en que debe enviarle sus mensajes y cmo va a recibir la
respuesta (al hombre le puede ser suficiente para utilizar el coche saber cmo conducir
acelerar, utilizar el volante, etc...-, cmo funcionan el interruptor, el dial del volumen y
los botones de cambio de canal para utilizar un televisor, etc).
Sucede a menudo que hay que utilizar varios ejemplares anlogos de un determinado
tipo (por ejemplo varias ventanas en la pantalla del PC, varios usuarios, varios clientes,
varias cuentas corrientes de un banco, etc.). La definicin genrica de estos objetos
anlogos se realiza mediante la clase. As, una clase contiene una completa y detallada
descripcin de la informacin y de las funciones que contendr cada objeto de esa clase.
Los objetos son las variables concretas que se crean de una determinada clase. A veces
se llaman tambin instancias. As, se habla de crear un objeto o instancia de una clase.
Las clases son verdaderos tipos de datos definidos por el usuario o por el sistema y
pueden ser utilizados de igual manera que los tipos de datos simples, tales como int,
float, etc.
Un objeto tiene su propio conjunto de datos o variables miembro, aunque no de
funciones, ya que las que se aplican a un objeto concreto son propias de la clase a la que
pertenece el objeto.
Para proteger a las variables de modificaciones no deseadas se introduce el concepto de
encapsulacin, ocultamiento o abstraccin de datos. De ordinario una clase ofrece un
conjunto de mtodos pblicos a travs de los cuales se puede actuar sobre los datos, que
sern privados. Estas funciones o mtodos pblicos constituyen la interfaz de la clase,
es decir, el elemento que el programador puede utilizar para comunicarse con los
objetos. . De esta forma se garantiza que se hace buen uso de los objetos, manteniendo
la coherencia de la informacin. Esto sera imposible si se accediera libre e
independientemente a cada variable miembro. Al usuario le es suficiente con saber
1/35
Clases
Objetos
Un objeto o instancia es un ejemplar concreto de una clase. En realidad, los objetos son
variables de tipo clase.
Es importante comprender muy bien la diferencia entre clase y objeto. Clase es la propia
definicin de un tipo de dato, realizada por el programador o proporcionada por el
sistema. Es una abstraccin lgica. Sin embargo, el objeto es un ejemplar de una clase,
que tiene una existencia fsica ya que est fsicamente en memoria, de la misma forma
que una variable de un tipo valor es un ejemplar del tipo de la variable. Por ejemplo:
2/35
Clases
int unaVariable = 7;
Montn
Pila
unRect
Referencias a objetos de la
clase Rectngulo
doRect
3/35
ancho
5.0
largo
7.0
ancho
23.0
largo
347.0
Objetos
Clases
Figura 5.1
En la figura 5.1 puede verse dos referencias unRect y doRect a objetos de la clase
Rectngulo.
Habitualmente, estos dos pasos se reducen a uno slo:
Rectngulo unRect = new Rectngulo(5,7);
En C# slo se permite herencia simple, es decir, slo puede heredarse desde una clase.
Sin embargo, como en Java, se puede implementar ms de una interface.
4/35
Clases
Los posibles modificadores que puede tener una clase son new, public, protected,
internal, private, abstract y sealed.
Los modificadores public, protected, internal y private son modificadores de
control de acceso a la clase. Estos modificadores determinan la visibilidad de los
miembros de una clase. Se realizar una explicacin detallada de los modificadores, ms
adelante, en este mismo captulo.
Aunque se volver a recalcar al hablar de los tipos de acceso, en este libro se seguirn la
recomendaciones de Microsoft respecto a cmo escribir los nombres de los miembros
de una clase.
Los miembros pblicos, las clases, etc, se escriben con maysculas. Por
ejemplo:
class MiClase{}
namespace MiNamespace;
Constructores
Destructores
Constantes
Campos
Mtodos
Propiedades
Indexadores
Operadores
5/35
Clases
Por ejemplo:
class Matemticas
{
public const double PI=3.141592;
}
Una constante es un valor que no puede ser cambiado y no se le puede asignar ningn
valor. Por eso es imprescindible inicializarla en la propia clase. Esto significa que no
podra haberse incluido en la clase anterior una lnea como la siguiente:
public
const double E;
Campos.
Los campos de una clase almacenan informacin del objeto de la clase que se ha creado.
Son aqullas caractersticas que diferencian dos objetos de una misma clase y
determinan su apariencia o estado. El acceso a los campos o miembros dato puede ser
directo o bien a travs de mtodos o propiedades, dependiendo de la visibilidad de los
campos es decir, de los modificadores de cada variable.
Los campos de un objeto se invocan con el operador punto (.).
C# permite definir como campos tanto tipos valor como tipos referencia. En el primer
caso, los objetos que se creen almacenarn una copia de las variables de tipo valor y en
el segundo, una referencia a los objetos. Tambin permite definir otra clase de
miembros como propiedades, delegates, etc...
Los campos de una clase se denominan a veces, campos o variables de instancia o de
objeto en contraposicin a las variables estticas o de clase. Se llaman as porque cada
instancia u objeto contiene su propia copia de cada campo o variable. Los datos de un
objeto son propios y estn separados incluso fsicamente- de los datos de otro objeto.
Por esta razn, los cambios que se realicen en los campos de un objeto no afectan para
nada a los campos de los dems objetos, aunque sean del mismo tipo de clase. Esto no
sucede as con los campos de clase, porque todos los objetos comparten la misma
variable fsicamente. Por ejemplo:
using System;
6/35
Clases
7/35
Clases
Mtodos.
Forma general
Los mtodos de una clase son porciones o bloques de cdigo a los que los objetos de esa
clase pueden llamar para que sean ejecutados. Generalmente operan sobre los campos.
Las clases no tiene limitacin en cuanto al nmero de mtodos. Los mtodos pueden
tener parmetros y devolverlos.
Si un mtodo no devuelve nada, se utiliza la palabra void.
La estructura general de un mtodo es:
[modificadores] tipo_de_retorno nombreDelMetodo (Parmetros_opcionales)
{
//cuerpo del mtodo
}
Miembros estticos
Hay ocasiones en los que un miembro de una clase, ya sea campo o mtodo, hace ms
referencia a la clase es decir, a todos los objetos de la clase- que a cada objeto en
concreto. Suponga por ejemplo- que se desea llevar una cuenta del nmero de objetos
de una determinada clase en un programa. C# proporciona un camino para crear un
miembro que pueda utilizarse por s mismo sin referirse a una instancia u objeto
especfico. Para ello, en su definicin, el miembro ha de ir precedido por el modificador
static.
Cuando se declara un miembro como esttico, se puede acceder a l sin haber creado
ningn objeto en particular. Esto es lo que sucede con el mtodo Main() que debe ser
declarado como static porque tiene que ser invocado al inicio del programa, es decir,
cuando todava no se ha creado ningn objeto de ninguna clase. Al tener este
modificador, el mtodo Main() puede ser invocado sin necesidad de crear previamente
ningn objeto.
Los campos declarados como static son variables globales. Cuando se crean objetos
de una clase que tiene un campo static, no se hace ninguna copia de l. Todos los
objetos de esa clase comparten una nica copia del mismo campo. Si uno de ellos lo
modifica, quedar modificado para todos ellos. por esta razn, este tipo de miembros se
denominan campos o mtodos estticos o de clase o , en contraposicin a los mtodos o
campos de objeto o de instancia.
8/35
Clases
Fuera de la clase en la que han sido definidos, los mtodos y campos estticos se pueden
utilizar independientemente de cualquier objeto. nicamente es necesario especificar el
nombre de la clase seguido del operador punto y del nombre del miembro, de la forma:
NombreDeLaClase.metodoStatic( );
NombreDeLaClase.campoStatic;
A continuacin se propone un ejemplo que puede servir para aclarar este concepto:
Se trata de disear una clase Alumno en la cual se incluya la nota media para ingresar en
la universidad y que tenga en cuenta la nota de corte para entrar como alumno en la
escuela de ingeniera industrial.
using System;
namespace ConsoleApplication3
{
public class Alumno
{
double nota;
public static double notaIngenieros=6;
public Alumno(double nota)
{
this.nota=nota;
}
public bool estaAdmitido()
{
return (nota>=notaIngenieros);
}
public void ImprimirResultado(string nombre)
{
if(estaAdmitido())
Console.WriteLine("{0} est admitido",nombre);
else
Console.WriteLine("{0} no est admitido",nombre);
}
}
class MiClase
{
static void Main(string[] args)
{
Alumno juan=new Alumno(6.5);
Alumno jorge=new Alumno(5.2);
Console.WriteLine("Nota de corte:{0}",
Alumno.notaIngenieros);
juan.ImprimirResultado("Juan");
jorge.ImprimirResultado("Jorge");
Console.WriteLine("\n");
Alumno.notaIngenieros=7;
Console.WriteLine("Nota de corte:{0}",
Alumno.notaIngenieros);
juan.ImprimirResultado("Juan");
jorge.ImprimirResultado("Jorge");
}
}
9/35
Clases
Puede verse que para llamar al miembro esttico, al ser un miembro de clase, hay que
invocarlo a travs del nombre de la clase. En C# no puede llamarse a un mtodo o
campo esttico a travs del nombre del objeto como en Java-, porque dara error. As,
notaIngenieros se manipula en la lnea:
Alumno.notaIngenieros=7;
Una vez ejecutada esta sentencia, el miembro esttico cambia. Y lo hace en todos los
objetos. Hay una sola copia de este miembro, aunque todos los objetos lo tengan y
puedan utilizarlo.
En este ejemplo, puede verse la diferencia entre un miembro de clase y uno de instancia,
como nota. nota es diferente para cada alumno cada objeto Alumno tiene su propia
copia de su nota, y por ello, cambiar a un alumno la nota no modifica la nota del resto
de los alumnos- mientras que notaCorteIngenieros tiene el mismo valor para todos
los objetos o instancias.
Los miembros estticos deben inicializarse en la propia clase aunque si no se hace as,
se inicializarn con los valores por defecto.
Los mtodos declarados como static tienen algunas restricciones:
a) Slo pueden llamar a mtodos static.
b) Solamente pueden acceder a campos static.
c) No pueden referirse a this.
En resumen: aunque las clases se definen para poder crear objetos a partir de ella, una
clase puede contar con miembros estticos y ser usada directamente, sin crear objeto
alguno. Mediante el uso de miembros estticos es posible mantener informacin
compartida entre todos los objetos de una clase. Dichos miembros no pertenecen a un
objeto en particular, sino que son compartidos por todos. Por lo tanto, este miembro se
crea con el primer objeto y es compartido por todos.
10/35
Clases
reservada. Dicha palabra se debe utilizar tanto en la definicin del mtodo como cuando
se invoca al mtodo. A continuacin se van a estudiar las distintas posibilidades:
Paso por valor: El mtodo recibe una copia del valor almacenado en la
variable original. En su cdigo, el mtodo trabaja con la copia -puede
transformarla o modificarla- y pero no puede cambiar la variable original.
Este es el nico de los cuatro tipos de paso de parmetros que no se
identifica por ninguna palabra reservada.
Por ejemplo:
Control de acceso
Un programador no necesita conocer el funcionamiento interno de una clase para
utilizarla, de igual forma que para utilizar un coche no es necesario conocer el
funcionamiento interno del motor y basta con saber cmo comunicarse con el coche
acelerar para aumentar la velocidad, girar el volante para cambiar de direccin, etc-. Le
es suficiente con saber cmo utilizar un objeto de esa clase (es decir, cmo comunicarse
con l) para utilizarlo.
Para proteger a los miembros de una clase de modificaciones no deseadas y para
garantizar que tomen valores lgicos y acordes con la naturaleza misma de los datos, se
introduce el concepto de encapsulacin de los datos. Por esta razn, los miembros de
una clase van precedidos de un modificador que define la visibilidad, el modo de
acceso al miembro de la clase.
11/35
Clases
En lneas muy generales, se puede decir que la encapsulacin consiste en definir los
campos de datos como privados para protegerlos y los mtodos como pblicos para que
puedan manipular los datos. En general, la encapsulacin es una manera comn de
escribir el cdigo de una clase. Se mantienen los datos ocultos al exterior de la clase
para que no se puedan utilizar desde el exterior y se escriben una serie de miembros
pblicos que pueden manipular cualquier campo de esa clase- que permitan al
programador manipular esos datos o algunos datos- desde el exterior, desde su
programa.
En general, el interfaz no el interface- de una clase est constituido por el conjunto
de mtodos pblicos de una clase y es el medio por el que el programador puede
comunicarse con los objetos de esa clase: puede modificar y manipular los datos,
cambiar sus campos, enviarle mensajes, etc. No es necesario que el programador tenga
acceso a los detalles de implementacin de la clase. Le es suficiente con conocer cmo
se utilizan los mtodos pblicos: qu mensajes se pueden enviar al objeto a travs de
ellos, y cmo responden los objetos a un determinado mensaje, es decir, qu devuelven.
En resumen, le basta con conocer el interfaz de la clase..
Los modificadores de acceso a los miembros de una clase permiten ocultar, proteger y
encapsular los datos de una clase. Aunque posteriormente se hablar del resto de los
modificadores, ahora se explica el acceso a los miembros pblicos y privados de una
clase.
Un miembro que no tiene un modificador de acceso es, por defecto, private.
Por ejemplo:
public class UnaClase
{
int a;
private int b;
public int c;
public void Imprimir()
{
Console.WriteLine("a={0}, b={1},C={2}",a,b,C);
}
}
class MiAplicacion
{
static void Main(string[] args)
{
UnaClase clase=new UnaClase();
//Los objetos de UnaClase no pueden acceder
//a los miembros privados de UnaClase.
//las dos siguientes lneas darn error al compilar
clase.a = 10;
clase.b = 11;
//Los objetos de UnaClase pueden acceder
//a los miembros pblicos de UnaClase.
//Solo se puede llamar desde el exterior de una clase
//a sus miembros publicos
clase.c = 12;
clase.Imprimir();
12/35
Clases
}
}
Las lneas
clase.a = 10;
clase.b = 11;
no pueden compilarse deben ser comentadas para que el proceso de compilacin las
omita- porque no se puede invocar un miembro privado desde el exterior de la propia
clase; ni siquiera los objetos de la clase UnaClase pueden hacerlo. Esos miembros slo
se pueden manipular, invocar o llamar desde el mismo cdigo de definicin de la clase.
Se puede decir que las funciones miembro de la clase UnaClase pueden acceder a
miembros pblicos y privados de la clase.
Los objetos de la clase UnaClase pueden acceder slo a miembros pblicos de
UnaClase, como puede verse en las siguientes lneas:
clase.c = 12;
clase.Imprimir();
Sin embargo los miembros de la clase pueden acceder a los miembros pblicos y
privados de la clase, pero siempre desde el interior desde el propio cdigo de
definicin- de la clase. Por ejemplo, vemos que el mtodo Imprimir() puede acceder
sin problemas a los miembros de la clase.
La salida del programa es a=0,b=0, c=12;
Sobrecarga de mtodos
Muchas veces se ha utilizado en este libro la sobrecarga de mtodos pero sin decirlo
explcitamente. Por ejemplo, para imprimir en pantalla un valor entero, se puede hacer
algo parecido a:
int x = 6;
Console.WriteLine(x};
Clases
Console.WriteLine("Abs({0})={1}",unEntero,Abs(unEntero));
Console.WriteLine("Abs({0})={1}",unDouble,Abs(unDouble));
}
}
}
14/35
Clases
En este ejemplo se observa cmo el compilador puede distinguir el cdigo que debe
utilizar porque el tipo de argumento es diferente en los dos mtodos. En el siguiente
ejemplo, el compilador puede distinguirlos porque el nmero de argumentos que utiliza
en las llamadas es diferente aunque en este caso tambin el tipo-.
using System;
namespace UnNamespace
{
public class MiClaseApp
{
public static void Imprimir(string str)
{
Console.WriteLine("La cadena es {0}",str);
}
public static void Imprimir(int x, double y)
{
Console.WriteLine("x={0},y={1}",x,y);
}
static void Main(string[] args)
{
int x=8;
double y=9.34;
string unaCadena="Hola Mundo";
Imprimir(x,y);
Imprimir(unaCadena);
}
}
}
Constructores.
El constructor es un mtodo especial que permite inicializar un objeto de una clase en el
momento que ste se est creando. Es decir, da unos valores iniciales a los distintos
campos del objeto en el momento en que se crea.
Un constructor debe:
a) Tener el mismo nombre de la clase
b) Ser pblico
c) No tener ningn retorno ni siquiera void-.
Realmente, lo que ocurre es que inmediatamente despus de que se crea el objeto, el
compilador invoca al constructor. El funcionamiento es igual que un mtodo. En el
ejemplo de la clase Rectngulo, ya se ha utilizado un constructor de la clase.
public Rectngulo (double w, double h)
{
15/35
Clases
x = 0;
y = 0;
ancho = w;
largo = h;
}
Esta sentencia, despus de reservar memoria para el objeto para cada uno de sus
campos- ejecuta el cdigo del constructor. Inicializa los campos x, y, ancho y largo
con los valores 0,0, 55 y 44 respectivamente.
Adems se puede distinguir entre los constructores de instancia y los constructores
estticos (static).
Los constructores de instancia implementan las acciones necesarias para inicializar las
instancias de la clase, es decir, los objetos. Los constructores estticos (static):
implementan las acciones necesarias para inicializar la clase en s.
Sobrecarga de un constructor
Un constructor puede estar sobrecargado. De esta manera se proporciona una gran
flexibilidad a la hora de inicializar los objetos de una clase cualquiera.
La sobrecarga de un constructor es muy parecida a la sobrecarga de un mtodo. Se
puede escribir para una clase tantos constructores como se desee. Sin embargo, los
constructores deben diferenciarse entre s o en el nmero de parmetros o al menos, en
el tipo de parmetro. El compilador en tiempo de ejecucin diferenciar entre ellos y
utilizar el que se ajuste en nmero y tipo al constructor que se utilice en el programa.
En el siguiente ejemplo se ilustra esta idea:
using System;
namespace Matematicas
{
class Rectangulo
{
int x0;
int y0;
int ancho;
int largo;
public Rectangulo()
{
x0=y0=0;
ancho=10;
largo=10;
}
public Rectangulo(int x0,int y0,int ancho,int largo)
{
this.x0=x0;
16/35
Clases
this.y0=y0;
this.ancho=ancho;
this.largo=largo;
}
public Rectangulo(int ancho,int largo)
{
x0=0;
y0=0;
this.ancho=ancho;
this.largo=largo;
}
public Rectangulo(int lado)
{
x0=0;
y0=0;
ancho=lado;
largo=lado;
}
public void Imprimir(string nombreDelRectangulo)
{
Console.WriteLine("Datos del Rectangulo{0}"
,nombreDelRectangulo);
Console.WriteLine("x0={0},y0={1},ancho={2},largo={3}"
,x0,y0,ancho,largo);
Console.WriteLine();
}
}
class ClaseApp
{
static void Main(string[] args)
{
Rectangulo rect1=new Rectangulo();
rect1.Imprimir("Primer Rectangulo");
Rectangulo rect2=new Rectangulo(100);
rect1.Imprimir("Segundo Rectangulo");
Rectangulo rect3=new Rectangulo(100,200);
rect1.Imprimir("Tercer Rectangulo");
Rectangulo rect4=new Rectangulo(20,30,200,400);
rect1.Imprimir("Cuarto Rectangulo");
}
}
}
17/35
Clases
Figura 5.2
Hay que tener en cuenta que si se define un constructor cualquiera para una clase, el
constructor por defecto queda anulado. As, en el anterior ejemplo no hubiera sido
posible utilizar Rectngulo() si no se hubiera sobrecargado.
using System;
public class Persona
{
18/35
Clases
Referencia this
Si una variable local tiene el mismo nombre que un miembro de una clase entonces lo
oculta. Para estas ocasiones, o para otras en la que por diversas circunstancias interesa
referirse en el cdigo de una clase al propio objeto, se utiliza this, que es una
referencia implcita al propio objeto.
Por ejemplo:
class Rectngulo
{
int ancho;
int largo;
public Rectngulo(int ancho, int largo)
19/35
Clases
{
this.ancho=ancho;
this.largo=largo;
}
}
En este ejemplo, los parmetros ancho y largo del constructor ocultan los campos de la
propia clase porque tienen el mismo nombre. Para evitar este problema y que muchas
veces permite que el cdigo sea ms legible, se utiliza this.
Los atributos son opcionales. El nombre debe coincidir con el de la clase, pero debe ir
precedido del smbolo ~ (ALT+126)
El funcionamiento de los destructores no se parece al de C++. Realmente, es el cdigo
que se ejecuta cuando un objeto se destruye. Es muy parecido al mtodo finalize de
Java. El destructor es llamado por el recolector de basura cuando el objeto va a ser
destruido. De hecho es un alias del mtodo finalize. Se mantiene por comodidad al
migrar.
Propiedades.
Las propiedades constituyen una importante aportacin de C# y de uno de los autores
de este lenguaje, Anders Hejlsberg. Probablemente, algunos lectores que hayan
utilizado Delphi o C++ Builder de Borland, el concepto de propiedad les resultar
familiar, ya que Hejlsberg es el diseador de la VCL que es la librera en la que se
apoyan estos dos estupendas herramientas visuales de programacin.
Las propiedades permiten acceder a los campos privados de una clase de una manera
controlada y sencilla. Esto resulta especialmente til, ya que es importante no permitir
que un determinado campo pueda adquirir valores no deseados. Adems, las
propiedades permiten dotar a los campos de la caracterstica de ser de lectura o escritura
nicamente.
Las propiedades definen atributos con nombre (campos, realmente) y las acciones
asociadas con la lectura y escritura de esos atributos.
Antes de proseguir con el concepto de propiedad, es importante que el lector comprenda
bien los dos procesos distintos accesos- que pueden llevarse a cabo en un campo de
una clase: el proceso de lectura y el proceso de escritura.
20/35
Clases
Por ejemplo:
using System;
namespace Propiedades
{
class Rectangulo
{
public int Ancho;
public int Largo;
}
class MiAplicacion
{
static void Main(string[] args)
{
Rectangulo unRect=new Rectangulo();
unRect.Ancho=10;
unRect.Largo=25;
Console.WriteLine("Ancho={0},
Largo={1}",unRect.Ancho,unRect.Largo);
}
}
}
En este programa se puede observar cmo se asignan valores 10 y 25- a los campos
pblicos Ancho y Largo del objeto unRect. La asignacin se puede considerar como un
proceso de escritura en el campo. Sin embargo, en la sentencia en la que se imprimen
los datos se est consultando un campo o en un proceso de lectura del campo. En este
ejemplo se han considerado dos campos pblicos para ganar en sencillez. Sin embargo y
como ya se ha explicado en varias ocasiones no es lo ideal, porque los campos deben
tener un acceso restringido, tanto de lectura como de escritura. Piense el lector, por
ejemplo, si se hubiera dado una de las dos dimensiones con un valor negativo. No
tendra sentido.
El hecho de controlar los procesos de lectura y escritura es muy importante. Se puede
hacer escribiendo mtodos apropiados y de hecho, en los lenguajes orientados a objetos
se vena haciendo as hasta ahora. Sin embargo, esto puede ser, en ocasiones, tedioso.
Las propiedades constituyen una manera fcil y elegante de hacerlo.
La declaracin de una propiedad consta de una parte donde se define el proceso de
lectura denominado acceso get- y otra en la que se define el proceso de escritura o
acceso set.
El acceso get contiene el cdigo que se ha de ejecutar en la consulta o lectura de la
propiedad y por lo tanto del campo. Debe terminar siempre con la sentencia return o
throw. Adems el flujo de control no puede salir del cuerpo del acceso.
Por ejemplo:
private string nombre;
public string Nombre
{
get
// Campo nombre
// Propiedad Nombre
21/35
Clases
{
return nombre;
}
}
Para utilizarlo:
Persona unaPersona = new Persona();
...
Console.Write(unaPersona.Nombre);
// Se invoca el acceso get.
22/35
Clases
if(value<0)
ancho=0;
else
ancho=value;
}
}
public int Largo
{
get
{
return largo;
}
set
{
if(value<0)
largo=0;
else
largo=value;
}
}
}
class MiAplicacion
{
static void Main(string[] args)
{
Rectangulo unRect=new Rectangulo(13,26);
unRect.Ancho=10;
unRect.Largo=25;
Console.WriteLine("Ancho={0}, Largo={1}",
unRect.Ancho,unRect.Largo);
}
}
}
23/35
Clases
class Persona
{
string nombre;
string direccion;
public Persona(string str)
{
nombre=str;
}
public string Direccion
{
get
{
return direccion;
}
set
{
direccion=value;
}
}
//Definimos una propiedad de slo lectura
public string Nombre
{
get
{
return nombre;
}
}
}
class AccesosApp
{
static void Main(string[] args)
{
Persona p=new Persona("Patricia");
//ERROR en la siguiente lnea.
//El campo es de solo lectura
//unaPersona.Nombre="Juan";
p.Direccion="Gran Va 66";
Console.WriteLine("Nombre={0}, Direccion={1}",
p.Nombre,p.Direccion="Gran Va 66");
}
}
}
La lnea
unaPersona.Nombre="Juan";
est comentada porque es una propiedad de slo lectura. No puede escribirse ningn
dato en la propiedad. Slo se puede hacer al crear el objeto, a travs del constructor.
A continuacin se proponen una serie de ejemplos que tienen que ver con la herencia y
con la sobrecarga. Si el lector no conoce estos dos temas, es mejor que los deje para una
lectura posterior.
Ejemplo
using System;
public class ClaseBase
24/35
Clases
{
private string nombre;
public string Nombre
{
get
{
return nombre;
}
set
{
nombre = value;
}
}
}
public class ClaseDerivada : ClaseBase
{
private string nombre;
// importante: se utiliza el modificador new
// mas adelante se explica el significado de este modificador
public new string Nombre
{
get
{
return nombre;
}
set
{
nombre = value;
}
}
}
public class ClasePrincipal
{
public static void Main()
{
ClaseDerivada d = new ClaseDerivada ();
d.Nombre = "Germn"; // Propiedad de la clase derivada
Console.WriteLine("Nombre en la clase derivada: {0}",d.Nombre);
((ClaseBase)d).Nombre="Itxaso"; // Propiedad de la clase base
Console.WriteLine("Nombre en la clase base: {0}",
((ClaseBase)d). Nombre);
}
}
Ejemplo 2:
using System;
namespace Accesos
{
abstract class Figura
{
public abstract double Area
{
get;
set;
}
25/35
Clases
}
class Cuadrado: Figura
{
public double lado;
// Constructor:
public Cuadrado(double s)
{
lado = s;
}
// Propiedad Area
public override double Area
{
get
{
return lado * lado;
}
set
{
// Dado el area, se calcula el lado
lado = Math.Sqrt(value);
}
}
}
class Cubo: Figura
{
public double lado;
// Constructor:
public Cubo(double s)
{
lado = s;
}
// Propiedad Area
public override double Area
{
get
{
return 6*lado*lado;
}
set
{
// Dado el area, calcula el lado
lado = Math.Sqrt(value/6);
}
}
}
public class ClasePrincipal
{
public static void Main()
{
// Introducir el lado:
Console.Write("Introduce el lado: ");
string ladoString = Console.ReadLine();
double lado = double.Parse(ladoString);
26/35
Clases
Indexadores.
Permiten indexar las instancias de una clase o estructura del mismo modo que un array.
Un indexador es una variante de una propiedad que admite un ndice. Normalmente se
utiliza para asociar cada elemento de la clase o estructura a la que pertenece con cada
posible valor del ndice. No obstante, se puede programar como se desee la respuesta
que se de al uso del indexador.
Supngase una clase PuntoEspacial cuya definicin es:
class PuntoEspacial
{
public int x, y, z;
...
...
...
}
27/35
Clases
y
punto1[2] = 10; equivalga a hacer punto1.x = 10;
(El
ndice
(El
ndice
que quiere decir que es una propiedad pblica, que recibe un ndice y puede recibir
(set) o devolver un entero (get). En realidad, excluyendo el hecho de que recibe un
ndice, el indexador es una propiedad normal. Si se utiliza para una asignacin (value
representa el valor asignado) se ejecuta set y si se utiliza para obtener el valor de un
elemento de la clase se ejecuta el mtodo get.
28/35
Clases
Operadores.
Los operadores se han venido utilizando hasta ahora, se pueden sobrecargar, de tal
manera que si, por ejemplo, z1 y z2 son dos nmeros complejos, de manera automtica
el compilador entienda que z1 + z2 es la suma de dos nmeros complejos y por lo
tanto debe sumar de una manera diferente.
Los operadores que se pueden sobrecargar son:
+ - ! ~ ++ -- True False
+ - * / % & | ^ << >> == != > < >= <=
29/35
Clases
Modificadores de clase.
Los modificadores de una clase pueden ser:
new
abstract
sealed
public
protected
internal
private
new.
Es posible definir una clase en el interior de otra. Esto es til muchas veces para
ocultarla o bien porque nos interesa utilizarla como miembro de la clase que la contiene.
Esto es muy habitual en la programacin visual.
El modificador new slo se permite en clases anidadas. Indica que la clase oculta un
miembro heredado con el mismo nombre que aquel al que afecta new. En una
declaracin de clase se permite declarar un miembro con el mismo nombre y parmetros
que otro heredado. En tal caso se dice que el miembro derivado esconde al miembro
de la clase base. Ante la situacin comentada el compilador muestra un aviso o
warning. Si se quiere evitar tal aviso ha de precederse la declaracin del nuevo
miembro con el modificador new.
Ejemplo:
30/35
Clases
Modificador
public
protected
Visibilidad
Acceso Total.
El acceso est permitido a la clase que contiene al miembro y a
sus tipos derivados.
31/35
Clases
internal
Tipo
enum
class
public
private
interface
struct
public
private
None
public
protected
internal
private
protected internal
None
public
internal
private
Tabla 5.2
Por ejemplo:
using System;
namespace MiEspacioDeNombres
{
public class T1
{
public static int unEnteroPublico;
internal static int unEnteroInternal;
private static int unEnteroPrivado = 0;
public class M1
{
public static int unEnteroPublico;
internal static int unEnteroInternal;
private static int unEnteroPrivado = 0;
}
private class M2
{
public static int unEnteroPublico= 0;
internal static int unEnteroInternal = 0;
private static int unEnteroPrivado = 0;
}
}
public class MainClass
{
public static int Main()
{
// Acceso a los campos de T1
32/35
Clases
T1.unEnteroPublico=1;
// Acceso ilimitado
T1.unEnteroInternal=2; // Accesible solo en proyecto actual
// T1.unEnteroPrivado=3;// Error:inaccessible fuera de T1
// Acceso a los campos de M1
T1.M1.unEnteroPublico= 1;
// Acceso ilimitado
T1.M1.unEnteroInternal=2;
//Acceso slo en el proyecto
//actual
//T1.M1.unEnteroPrivado=3; // Error: inaccesible fuera de M1
//Acceso a los campos de M2
//T1.M2.unEnteroPublico=1; // Error: inaccesible fuera de T1
//T1.M2.unEnteroInternal=2; // Error: inaccesible fuera de T1
//T1.M2.unEnteroPrivado=3; // Error: inaccesible fuera de M2
return 0;
}
}
}
abstract.
Se denomina clase abstracta a aqulla que contiene uno o ms miembros abstractos.
Este modificador indica que no se pueden crear instancias u objetos de esa clase, porque
no est totalmente implementado. Habitualmente se utilizan para definir el interfaz que
deben heredar todas sus subclases, ya que todas las clases que derivan de ella deben
implementar, de manera obligatoria, todos los mtodos que son abstractos en la clase
base. Pueden crearse objetos de clases derivadas de una clase abstracta.
Para definir una clase como abstracta, debe ir precedida de la palabra abstract
Por ejemplo:
abstract class MiClaseBase
{
//codigo con algun miembro abstracto
}
Entonces, la sentencia
MiClaseBase unaClaseBase=new MiClaseBase();
33/35
Clases
O bien:
MiClaseBase unaRefBase = new MiClaseDerivada();
En el siguiente ejemplo se ha definido una clase abstracta, con una propiedad abstract.
Cuando se sobrescribe un miembro abstracto, basta con precederlo de la palabra
override. Es decir, para sobrescribir un miembro, ste debe ir precedido o modificado
por las palabras reservadas abstract si es que no lo implementa- o virtual si lo
implementa-. Esto es lo que sucede con el miembro MiMetodo().
Ejemplo:
using System;
abstract class MiClaseBase
// Clase Abstracta
{
protected int x = 100;
protected int y = 150;
public abstract void MiMetodo();
// Metodo abstracto
public abstract int GetX
{
get;
}
//Propiedad abstracta
// Propiedad abstracta
}
class MiClaseDerivada: MiClaseBase
{
public override void MiMetodo()
{
x++;
y++;
}
public override int GetX
{
get
{
return x+10;
}
}
// overriding property
// overriding property
34/35
Clases
get
{
return y+10;
}
}
public static void Main()
{
MiClaseDerivada mC = new MiClaseDerivada ();
mC.MiMetodo();
Console.WriteLine("x = {0}, y = {1}", mC.GetX, mC.GetY);
}
}
sealed.
El modificador sealed hace que la clase a la que modifique no pueda ser derivada.
Algunas clases que se suministran con la librera .NET utilizan este modificador.
Ejemplo:
using System;
sealed class MiClaseCerrada
{
public int x;
public int y;
}
class MainClass
{
public static void Main()
{
MiClaseCerrada mC = new MiClaseCerrada();
mC.x = 110;
mC.y = 150;
Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y);
}
}
35/35