Você está na página 1de 46

LenguajeC#4.

0
ProgramacinOrientadaaObjetos

1.Fundamentos

CIPSA - Programacin C# .NET

DISTRIBUIDOPOR:

CENTRODEINFORMTICAPROFESIONALS.L.

C/URGELL,100
08011BARCELONA
TFNO:934265087

C/RAFAELAYBARRA,10
48014BILBAO
TFNO:944483133

www.cipsa.net

RESERVADOSTODOSLOSDERECHOS.QUEDAPROHIBIDOTODOTIPODE
REPRODUCCINTOTALOPARCIALDEESTEMANUAL,SINPREVIO
CONSENTIMIENTOPORELESCRITORDELEDITOR

CIPSA - Programacin C# .NET

1.ConceptosdeProgramacin
OrientadaaObjetos
1.1.DeclaracindeClases

Lasclasessedefinenenloslenguajesdeprogramacincomotiposdedatosdefinidos
porelusuarioquerepresentanuntipodeelementos.Porejemplo;enunaaplicacin
degestindeunconcesionariodeautomviles;laclaseVehculodefinetodoslosdatos
queseguardandecadavehculoascomolasoperacionesquellevanacaboconellos.

Ladeclaracindeunaclasesellevaacabomediantelapalabraclaveclassseguidadel
identificadordelaclaseyladefinicindesusmiembros.
class Puntos {
// definicin de la clase.
}

El identificador de una clase debe ser en minsculas con la primera letra en


maysculas.

1.1.1.Espaciosdenombres

Las clases se definen como parte de espacios de nombres que las contienen
manteniendounorden.Paradefinirunespaciodenombresseemplealapalabraclave
namespace:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
}
}

Aunque en un mismo fichero pueden definirse mltiples clases, lo recomendable es


definir cada clase en un fichero independiente con el propio nombre de la clase. De
esemodo,elficheroquecontienelaclaseprincipaldeunaaplicacindeconsola(la
claseProgram),sellamaprogram.cs.

CIPSA - Programacin C# .NET

1.1.2.Atributosdeunaclase

Los atributos de las clases estn representados por las variables y representan las
diferentesinformacionesquesedeseanalmacenardecadaelemento.

Por ejemplo; Supongamos una aplicacin de gestin de una academia para la que
hemosdefinidounaclaseAlumno.Losatributosnombre,apellidosyedadindicanqu
valoresdeseanalmacenarseporcadaalumnoquesemanejeenlaaplicacin.

public class Alumnos {


// Atributos
private String snombre;
private String sapellidos;
private int iedad;
// Metodos
public int GetEdad() {
return this.iedad;
}
public void SetEdad( int _edad )
{
if ( _edad > 0 && _edad < 100 )
{
this.iedad = _edad;
}
}
}

Los atributos de una clase se declaran privados para que no sean accesibles
directamente desde el exterior de la clase y evitar as que se les asignen valores
erroneosoincongruentes,comoporejemplounaedadnegativa.Parapoderaccedera
losatributosdeformacontroladaseempleanmtodosopropiedadespblicasques
sonaccesiblesdesdeelexterior.Ej:

// Metodos
public int GetEdad() {
return this.edad;
}
public void SetEdad( int _edad )
{
if ( edad > 0 && edad < 100 )
{
this.edad = _edad;
}
}

Losidentificadoresdelosatributosseexpresanenminsculasanteponiendounprefijo
queindicaeltipodelmismo.

CIPSA - Programacin C# .NET

1.1.3.Propiedades

Las propiedades son un mecanismo para poder manipular los atributos privados de
una clase desde el exterior de manera controlada. Los sidentificadores de las
propiedadesseexpresanenminsculasconlaprimeraletraenmaysculas.

LaspropiedadessustituyenamtodoscomoGetEdadySetEdadvistosantes.

Dentrodelapropiedadseencuentraunbloquegetquecontieneelcdigoqueretorna
elvalordelatributo,yunbloquesetprovistodelavariablevaluecomounparmetro
predefinidoquecontieneelvalorquesedeseaasignaralatributo.
Enelsiguientecdigosemuestraunejemplodepropiedad:

// Propiedad que permite obtener y asignar el valor del atributo edad


public int Edad
{
get { return iedad; }
set { if (value > 0 && value < 100) iedad = value; }
}

Siseomiteunodelosbloqueslapropiedadserdeslolectura,osloescritura.

Laspropiedadessemanejandesdeelexteriordelaclaseigualqueunavariablenormal
ycorrientemedianteeloperadordeasignacin.

Alumnos objAlumno = new Alumnos();


objAlumno.Edad = 10;
Console.WriteLine(objAlumno.Edad

1.1.4.Mtodos

Los mtodos de una clase tienen la forma de procedimientos y funciones que


representanoperacionesyaccionesquesellevancontraloselementosrepresentados
porunaclase.

Losidentificadoresdelosmtodossonverbosquedescribenunaoperacinconcretay
determinada y se expresan en minsculas con la primera letra en maysculas. Por
ejemplo:RegistrarAlumno,BuscarPersona,Iniciar,Detener.Etc.

Los mtodos de una clase se declaran como pblicos para permitir su acceso al
exterior. Slo cuando se trata de mtodos que realizan operaciones internas o
auxiliares de la clase se declaran como privados. De este modo, se asegura slo
puedenserinvocadospormtodosmiembrosdelapropiaclase.

CIPSA - Programacin C# .NET

1.1.5.Sobrecargademtodos.

Los mtodos de una clase pueden sobrecargarse. Esto consiste en definir varias
mtodosconelmismonombreperocondiferentenmeroy/otipodeparmetrosde
entrada.Esdecir,puedendefinirseversionesdiferentesdeunmtodomientrascada
unatengaunnmerodistintodeparmetrosdeentradaobiendiferentestipos.

class Operaciones
{
public int Sumar(int a, int b)
{
// sobrecarga 1
return a + b;
}
public float Sumar(float a, float b)
{
// sobrecarga 2
return a + b;
}
public int Sumar(int a, int b, int c)
{
// sobrecarga 3
return a + b + c;
}
}

El cdigo anterior muestra tres sobrecargas del mtodo Sumar. Todas ellas se
diferencianenelnmeroy/otipodeparmetrosdeentrada.Eltipoderetornonose
consideraunelementodiferenciador.

1.1.6.ModificadoresdeAcceso

Losmodificadoresdeaccesosonpalabrasclavequedeterminanlaaccesibilidaddeuna
clase y de sus miembros ( mtodos y atributos ). Estos se indican precediendo la
declaracindelaclaseomiembrodelaclasealqueafectan.

Public:Accesopblico:Aplicadoaunaclasehacequeseavisibleparatodaaplicacin.Aplicado
aunmiembrodeunaclasehacequeseaaccesibledesdeelexteriordelaclase.Habitualmente
seaplicaalosmtodosdeunaclase.

Private:Accesoprivado:Aplicadoaunmiembrodeunaclasehacequesloseaaccesiblepara
elrestodemiembrosdelaclase.habitualmenteseaplicaalosatributosdelaclaseparaevitar
sumanipulacindirectaeincontrolada.

Protected:Accesoprotegido:Aplicadoaunmiembrodeunaclasehacequesloseaaccesible
para el resto de miembros presentes en la propia clase y sus clases hijas. Habitualmente se
aplica a los atributos de una clase de la que se espera se definen otras clases aplicando
herencia.

Internal:Accesointerno:Aplicadoaunaclasehacequeseavisiblenicamenteparaelrestode
clasespertenecientesalmismoespaciodenombres.Aplicadoaunmiembrohacequeslosea
accesibleparaotrasclasesdefinidasdentrodelmismoespaciodenombres.

CIPSA - Programacin C# .NET

El siguiente diagrama muestra muy esquemticamente los mbitos de accesibilidad


asociados a las clases y sus miembros en funcin del modificador de visibilidad
empleado.

CIPSA - Programacin C# .NET

1.2.Creacindeobjetosdeunaclase(Instanciacin).

Los objetos son instancias de una clase que representan elementos concretos,
mientrasquelasclasesmuestranunadefinicinabstractadelosmismos.Lacreacin
deunobjetoeslaaccinporlacualsereservaespacioenlamemoriaparacontener
susatributos,yseleasignasureferenciaaunavariabledeinstancia.

Declaracin: Consiste en declarar una variable para referenciar a un objeto de


una determinada clase. Estas variables se denominan variables de instancia.
Cuandounavariabledeinstanciaesdeclaradaapuntaanull.

// Declaracin
Coche objCoche;

Instanciacin: Es la creacin del objeto propiamente. En el momento de la


instanciacinseinvocaalmtodoconstructorquedeberdarvaloresinicialesa
losatributosdelobjeto.Paraellodebeemplearseeloperadornew.

// Inicializacin sin parmetros.


objetoCoche = new Coche()

Esimportantetenerclaraladiferenciaentreelobjetoyvariabledeinstanciaalobjeto;
NOSONLOMISMO.Unavariabledeinstanciaesunasimplereferenciaaunobjeto,no
un objeto. Mltiples variables de instancia pueden referenciar al mismo objeto de
maneraquesisecambiaelvalordeunatributoatravsdeuna;elcambioservisible
mediantelasdems.

Elsiguienteejemplomuestraladeclaracindedosvariablesdeinstanciaapuntandoal
mismoobjeto.

Coche objCocheA;
Coche objCocheB;
objCocheA = new Coche();
objCocheB = objCocheA;

//
//
//
//

Referencia declarada
Apunta a null.
Referencia declarada
Apunta a null.
Instanciacin de objeto y vinculado a referencia
objCocheA y objCocheB apuntan al mismo objeto.

El siguiente ejemplo muestra la declaracin e inicializacin de dos variables de


instanciaqueapuntanaobjetosdistintos.

Coche objCocheA;
// Referencia declarada
Coche objCocheB;
// Referencia declarada
objCocheA = new Coche();
objCocheB = new Coche();

Apunta a null.
Apunta a null.

CIPSA - Programacin C# .NET

1.2.1.Accesoamiembrosdeunaclase

Elaccesoalosmiembrosdeunaclase(propiedadesymtodos)sellevaacaboatravs
delasvariablesdeinstanciaempleandoeloperadordereferencia:.

Acceso a las propiedas de un objeto: se emplea la variable de instancia que


referencia al objeto seguido del operador de referencia . acompaado y el
nombredelmtodooatributo:

<objeto>.<atributo>=<valor>

Variable=<objeto>.<atributo>

// Asignacin de valor a atributos nombre y edad del objeto objAlumno


objAlumno.nombre = Pedro
objAlumno.edad = 25

Llamada a los mtodos de un objeto: Se emplea la variable de instancia que


referencia al objeto seguido del operador de referencia . y el nombre del
mtodoseguidodelosparmetrosdeentradaquetengadeclarados.Sisetrata
de una funcin con un valor de retorno; la invocacin se situar a la parte
derechadeunaasignacinpararecogerelvalorretornado.Lavariablesituada
a la parte izquierda de la asignacin deber ser de un tipo apropiado al de
retornodelafuncininvocada.

<objeto>.<mtodo>(<parmetros>,..)
Variable=<objeto>.<mtodo>(<parmetros>,.)
// Llamada a mtodo que matricula alumno objAlumno en curso 1 de programacin.
objAlumno.matricularCurso(Programacin, 1 )
// Llamada a mtodo que retorna la calificacin del primer examen de objAlumno.
float notaExamen;
notaExamen = objAlumno.devolverNotaExamen( 1 )

1.2.2.MtodosConstructores.

Los constructores son mtodos especiales que se invocan automticamente al


instanciarunobjetodeunaclase.Losmtodosconstructoresseempleanparaasignar
valores a los atributos de la clase en el momento de la creacin del objeto. De este
modo,elobjetoescreadoconsusatributosinicializadosdesdeelprimermomento.

Estos mtodos se caracterizan por declararse con el mismo nombre de la clase y sin
ningntipoderetorno(nisiquieravoid).

CIPSA - Programacin C# .NET

Algunos constructores no reciben parmetros e inicializan los atributos de la clase a


unosvalorespredeterminados.Estossonlosconstructoresnoparametrizados.

class punto
{
int x;
int y;
// Constructor predeterminado
public punto() {
x = 0;
y = 0;
}
}

Tambin pueden definirse constructores que reciban parmetros para asignar sus
valoresalosatributosdelobjeto.Estopermiteinicializarlosatributosdeunobjetoen
la misma sentencia de instanciacin evitando tener que darles valores por separado
despus.

class Punto
{
int x;
int y;
// Constructor predeterminado, declarado para que sigua existiendo.
public punto()
{
x = 0;
y = 0;
}
// Constructor de la clase
public punto(int _x, int _y)
{
x = _x;
y = _y;
}
}

Enelejemploanteriorsehaaadidodosconstructores(sobrecargados).Elprimeroes
noparametrizadoeinicializaa0losatributos.Elsegundorecibecomoparmetroslos
valoresparasusatributos.Suusopermitecrearobjetosdandovaloresasusatributos
enelmomentomismodesucreacin:

Punto p1, p2;


p1 = new Punto();
// Crea objeto punto ( X = 0, Y = 0 ).
P2 = new punto( 10, 20 ); // Crea objeto punto ( X = 10, Y = 20 ).

1.2.3.Constructorpredeterminado

Aunque no se defina ningn constructor en una clase, todas tienen un constructor


implcitopredeterminadoquenorecibeningnparmetronitieneningncdigo.Este
constructordesapareceenelmomentoenquesedefinenconstructoresenlaclase.

10

CIPSA - Programacin C# .NET

1.2.4.Lareferenciathis

Lareferenciathis;esunareferenciapredefinidaporellenguajequeapuntasiempreal
propioobjeto.Atravsdeellasepuedeaccederalosmiembrosdelpropioobjeto.

En el siguiente ejemplo, el uso de la referencia this permite diferenciar los atributos


delobjetodelosparmetrosdelconstructor:

// Constructor de la clase
public punto(int _x, int _y)
{
this.x = x;
this.y = y;
}

1.2.5.Mtododestructor

Elmtododestructoresunmtodoespecialqueseejecutanicamenteantesqueel
objetodeunaclaseseaeliminadodelamemoria.Estemtodoseimplementacuando
sedesearealizaralgunaoperacincoincidiendoconlaeliminacindeunobjeto,como
por ejemplo cerrar un archivo o la conexin a una base de datosetc. El mtodo
destructor no tiene tipo de salida, ni parmetros de entrada, ni modificador de
visibilidad,ysunombrecoincideconeldelaclaseprecedidodelsigno(~).

class Alumno {
~Alumno() {
}
}

El mtodo destructor no puede ser invocado directamente por el programador. Este


mtodo es nicamente invocable por el gestor de memoria de .NET ( Garbage
Collector)cuandosedisponeaeliminardelamemoriaunobjeto.ElGarbageCollector
( GC ) es un componente encargado de reservar y administrar la memoria requerida
por las aplicaciones .NET para su funcionamiento. El GC funciona de modo no
determinista. Esto quiere decir que la memoria se libera en un momento
indeterminadodurantelaejecucindelprograma,obienalterminarlaejecucin:

Sea:

class punto
{
public punto()
{
System.Diagnostics.Debug.WriteLine("INICIO");
}
~punto()
{
System.Diagnostics.Debug.WriteLine("FIN");
}
}

11

CIPSA - Programacin C# .NET

Alejecutarelsiguientecdigo:

static void Main(string[] args)


{
punto p = new punto();
p = null;
}

Elresultadomostradoes:

INICIO
El subproceso 'vshost.RunParkingWindow' (0x338) termin con cdigo 0 (0x0).
El subproceso '<Sin nombre>' (0xdec) termin con cdigo 0 (0x0).
FIN
El programa '[2944] ConsoleApplication1.vshost.exe: Seguimiento de programa' termin con
cdigo 0 (0x0).
El programa '[2944] ConsoleApplication1.vshost.exe: Administrado (v4.0.30319)' termin
con cdigo 0 (0x0).

EltextoFINaparecejustounavezterminadalaejecucindelaaplicacinjustoenel
momentoenqueeseliminadoelobjetodelamemoria.

Aunqueeldestructordeunaclasenopuedeserinvocadodirectamente,sesposible
llamarelrecolectordebasura(GC)paraquesugerirlequeliberelamemoriaenun
determinadomomento.ParaelloseinvocaalmtodoCollect:
GC.Collect();

Estallamadaprovocaquesedestruyantodosaquellosobjetosquepermanecenenla
memoriasinningunavariabledeinstanciareferencindolos.

12

CIPSA - Programacin C# .NET

1.3.Clasesymiembrosestticos.

Losatributosymtodosconvencionalespertenecenalosobjetosyrequierendeuna
instancia contra la que son invocados. Existe sin embargo otro tipo de mtodos y
atributos que son comunes a todos los objetos de una clase y pueden invocarse a
partirdelnombredelapropiaclase.Estosrecibenelnombredemtodosyatributos
estticos.

Unatributoestticoesunatributocuyovalorescompartidoportodaslasinstancias
delaclase.Sielvalordeunatributoestticoesmodificadoporunobjeto,todoslos
demsobjetospercibirnelcambio.

Losmtodosestticossonmtodosqueseinvocandirectamenteempleandolaclasey
que slo pueden alterar el valor de atributos estticos o invocar a otros mtodos
estticos.

Tantomtodoscomoatributosestticossedeclaranempleandolapalabraclavestatic
previaasudefinicin,ypuedeninvocarseempleandoelnombredelapropiaclaseen
vezdeunobjeto.

class Academia {
public static int numAlumnos = 0;
public static void incrementarAlumnos() {
numAlumnos++;
}
}
Academia.numAlumnos = 10;
Academia.incrementarAlumnos();

// atributo esttico.
// mtodo esttico.

// llamada atributo esttico.


// llamada mtodo esttico.

Unaclasetambinpuededeclarseestticaaadiendolapalabraclavestaticdelantede
class.

static class Gestor {


.
}

Las clases estticas slo pueden poser miembros estticos, y no pueden crearse
instancias de ellas. Estas clases se inicializan automticamente cuando se inicia el
programamedianteelempleodeunconstructoresttico.

class SimpleClass
{
static SimpleClass()
{
//...
}
}

// Constructor esttico

13

CIPSA - Programacin C# .NET

Unconstructorestticoincluyeelcdigoquedebeejecutarsealinicializarseunaclase
esttica. Este mtodo nicamente invocable por el entorno .NET al iniciarse el
programa,ynopuedeposeerningnparmetrodeentrada.

Las clases estticas se emplean para definir clases puramente funcionales que
encapsulanmtodosnoasociadosaningunainstanciaparticular.Unbuenejemplode
claseestticaeslaclaseMathdefinidaenelespaciodenombresSystem.Cadaunode
losmtodosdelaclaseMathrepresentaunaoperacinmatemticanoligadaaningn
objetoconcreto.

Los atributos estticos se emplean para atributos cuyo valor se desea nico y
compartidoentretodoslosobjetosdelaclase.

Losmtodosestticosseempleanparadefiniroperacionesquenosonaplicablesaun
objetodeterminado,sinoavariosobjetossinmanipularninguno.

Ejemplo:

class Vector
{
private int x;
private int y;
public Vector(int _x, int _y)
{
this.x = _x;
this.y = _y;
}
// Mtodo convencional. Suma a un objeto Vector las coordenadas de otro
// pasado como parmetro.
public void Sumar(Vector b)
{
this.x += b.x;
this.y += b.y;
}
// Mtodo esttico. Crea un tercer objeto Vector a partir del sumatorio
// de las coordenadas de otros dos.
public static Vector Sumar(Vector a, Vector b)
{
return new Vector(a.x + b.x, a.y + b.y);
}
}

Elmtodoconvencionalsumar,modificalosatributosxeydelobjetocontraelquese
invocaaadiendoelvalordelosatributosdelobjetopasadocomoparmetro.

Vector v1 = new Vector(2, 2);


Vector v2 = new Vector(3, 3);
v1.Sumar(v2);

// Llamada a mtodo convencional

Vector v3 = Vector.Sumar(v1, v2);

// Llamada a mtodo esttico.

Elmtodoestticosumar,nomodificaningnobjetopuestoqueseinvocacontrala
propiaclase,ydevuelvecomoresultadounnuevoobjetoVectorconelsumatoriode
lascoordenadasdelosindicadoscomoparmetros.

14

CIPSA - Programacin C# .NET

Tambinesposibledefinirmtodosestticosquerepresentanoperadoresausarentre
los objetos de una clase. Por ejemplo; puede definirse el operador + para poder
sumardosobjetosdeunaclase.

SupongamosquetenemosunaclaseVector:

class Vector
{
private int x;
private int y;
public Vector(int _x, int _y)
{
this.x = _x;
this.y = _y;
}
public readonly int CoordX { get { return this.x; } }
public readonly int CoordY { get { return this.Y; } }
public static Vector operator +(Vector v1, Vector v2)
{
return new Vector(v1.x + v2.x, v1.y + v2.y);
}
}

En el ejemplo, se ha definido el operador + sumar dos objetos de la clase Vector. El


resultadoesunobjetoVectorcuyosatributosvalenlasumadelosobjetosoperandos.

Unavezdefindoeloperadorseempleacomoconcualquierotrotipodevariablesde
tiposprimitivos:

Vector v1 = new Vector(0, 1);


Vector v2 = new Vector(1, 0);
Vector v3 = v1 + v2;
Console.WriteLine("Vector resultado: {0}, {1}", v3.CoordX, v3.CoordY);

15

CIPSA - Programacin C# .NET

2.Herencia

Elmecanismodeherenciaesunodelospilaresfundamentalesenlosquesebasala
programacinorientadaaobjetos.Laherenciapermitedefinirnuevasclasesapartir
deotrasyadefinidas.Laherenciaseplanteasiguiendolasrelacionesdeespecializacin
ygeneralizacinquepuedenestablecerseentrelasentidadesrepresentadasporcada
clase.Deestemodo;aunqueesposible;nodebeutilizarselaherenciaentreclasessin
relacinalguna.

UnarelacindeespecializacinseestableceentredosentidadesAyBcuandoBesun
subtipodeA.Porejemplo,losperrosylosgatossontiposdemamiferos,porloque,
son especializaciones de la entidad mamifero. Esto implica que la entidad gato y
mamifero comparte ciertas caractersticas propias de los mamferos, y al mismo
tiempo;poseenotrascaractersticasquelosdiferencianentreellos.

Una relacin de generalizacin se establece entre dos entidades A y B cuando A


representaunaentidadqueenglobaaByaotrasmuchasconlasquecomparteciertas
caractersticas. Por ejemplo; un trangulo, un cuadrado y un pentgono son figuras
geomtricasconundeterminadonmerodeladosylongitud:

Cuandounaclasederivadeotrayaexistenterecibeelnombredeclasehija,mientras
quealainicialseledenominaclasepadre.Laclaseshijasheredanensudefinicinlos
mtodosyatributosdefinidosenlaclasepadrecomosifuesenpropios.

16

CIPSA - Programacin C# .NET

La herencia a nivel de programacin implica que todas las clases hijas heredan los
atributosymtodosdefinidosenlaclasepadredemodoquenonecesitandefinirlos
porsimismas:

No obstante, esto puede controlarse mediante los modificadores de visibilidad.


nicamente los mtodos y atributos declarados como pblicos o protegidos se
heredanenlasclaseshijas.

2.1.Declaracindeunaclasehija

Para indicar en la declaracin de una clase como hija de otra debe indicarse el
operador:seguidodelnombredelaclasepadre:
class <nombreHija>:<nombrePadre> {
...
}

Laherenciatambininfluyeenladefinicindelosconstructores.Elconstructordeuna
clasehijadeberecibirlosparmetrosnecesariosparadarvalortantoasusatributos
comoalosheredadosdelaclasepadre:

class Persona
{
// Atributos de la clase padre.
public string nombre;
public ine edad;
public string nif;
}
class Trabajador : Persona
{
// Atributo propio de la clase hija
public int Sueldo;
// Constructor de la clase hija
public Trabajador(string nombre, int edad, string nif, int sueldo)
{
this.Sueldo = sueldo;
this.nombre = nombre;
this.edad = edad;
this.nif = nif;
}
}

17

CIPSA - Programacin C# .NET

2.1.1Lareferenciapredefinidabase.

De igual manera que la referencia predefinida this representa al propio objeto, la


referenciabaserepresentaalobjetopadre.

Cuandolaclasepadreposeeunconstructorparametrizado,lareferenciabaseseutiliza
parainvocarlopasndolelosparmetroscorrespondientes.Lasintaxisaemplearesla
siguiente:

<constructor>( <parmetros>. )
: base( <argumentos_constructor_padre> )
// Llamada al padre
{
cdigo del cuerpo del constructor de la clase hija.
}

Estoesobligatoriosilaclasepadreposeenicamenteconstructoresparametrizados.

// Clase padre Mamifero


public class Mamifero
{
private int patas;
private String nombre;
// Constructor parametrizado de la clase Mamifero
public Mamifero(String nombre, int patas) {
this.nombre = nombre;
this.patas = patas;
}
public void imprimirPatas() {
System.Console.WriteLine(this.nombre + " tiene " + this.patas + " patas");
}
}
// Clase Perro que hereda de la clase Mamifero
public class Perro : Mamifero
{
private String raza;
// Constructor parametrizado de la clase Perro.
public Perro(String raza, String nombre)
: base(nombre, 4)
// Inicializador base
{
this.raza = raza;
}
}

Silaclasepadredefinealgnconstructorsinparmetrosonotieneningnconstructor
con parmetros definido), entonces puede omitirse la llamada a su constructor
mediantebase.

18

CIPSA - Programacin C# .NET

2.2.MtodosVirtualesysobrescritura.

Enlaherencialasclaseshijasrecibencomosifueransuyoslosmtodosyatributosde
lasclasesPadres.Sinembargo,avecesesnecesariomodificarunmtodoheredadode
la clase Padre para su funcionamiento en la clase Hija. En estos casos el mtodo
heredado vuelve a declararse en la clase Hija. Esta operacin recibe el nombre de
sobrescritura.

2.2.1.MtodosVirtuales(virtual)

Un mtodo virtual es aquel que puede sobrescribirse en las clases hijas. Para
sobrescribir un mtodo heredado, ste debe ser declarado como virtual en la clase
padre.Paraelloseemplealapalabraclavevirtual.Aestosselesdenominamtodos
virtuales:
virtual <tipoDevuelto> <nombreMtodo>(<parmetros>) {
<cdigo>
}

En la clase hija, la sobrescritura del mtodo debe ir precedida de la palabra clave


override:
override <tipoDevuelto> <nombreMtodo>(<parmetros>) {
<nuevoCdigo>
}

Ejemplo:ElsiguientecdigomuestralaclasepadreMamifero,ylaclasehijaPerroque
sobrescribeelmtodovirtualDevolverDescripciondefinidoenlaclasepadre.

// Clase padre Mamifero


public class Mamifero
{
private int patas;
private String nombre;
// Constructor parametrizado de la clase Mamifero
public Mamifero(String nombre, int patas) {
this.nombre = nombre;
this.patas = patas;
}

// Mtodo virtual
public virtual String DevolverDescripcion() {
return this.nombre + " tiene " + this.patas + " patas";
}

EnelcdigodelaclaseMamifero,elmtodoDevolverDescripcinestdeclaradocomo
virtualparapermitirqueseasobrescritoenclaseshijas.

19

CIPSA - Programacin C# .NET


// Clase Perro que hereda de la clase Mamifero
public class Perro : Mamifero
{
private String raza;
// Constructor parametrizado de la clase Perro.
public Perro(String raza, String nombre)
: base(nombre, 4)
// Inicializador base
{
this.raza = raza;
}
// Sobrescritura de mtodo virtual
public override String DevolverDescripcion()
{
String descripcion = base.DevolverDescripcion();
return "Es un animal de raza : " + raza + descripcion;
}
}

Alsobrescribirunmtododeunaclasepadreesposibleinvocardesdeelinteriorala
versinoriginaldelmtodoparaaprovecharlafuncionalidadoriginaldelmismo.Para
ellodebeemplearselareferenciapredefinidabase.

En el ejemplo anterior, la sobrescritura del mtodo DevolverDescripcin en la clase


Perro invoca internamente a la versin original del mtodo para recoger el valor
retornadoyaadirlelainformacindelatributodelaclasehija.Paraelloseinvocael
mtodo original sobre la referencia base. Esto recibe el nombre de sobrescritura
parcial.

2.2.2.MtodosSellados(sealed)

Un mtodo declarado como virtual puede ser sobrescrito en la clase hija, y vuelto a
sobrescribir en la clase hija de la clase hija, y as sucesivamente. Se llama mtodo
selladoalasobrescrituradeunmtodovirtualquenoadmitevolverasersobrescrita
enlasclaseshijas.

Supngaselassiguientesclases:

class Cuenta
{
public virtual float ObtenerIntereses()
{
return 0.0f;
}
}
class CuentaBonificada : Cuenta
{
public sealed override float ObtenerIntereses()
{
return 0.0f;
}
}

// METODO SELLADO

Paradeclararunmtodoselladoseindicalapalabraclavesealeddelantedeoverrides.

20

CIPSA - Programacin C# .NET

El mtodo ObtenerIntereses est declarado como virtual en Cuenta, por lo que es


perfectamente sobrescribible en CuentaBonificada. Sin embago; al declararse la
sobrescrituradelmtodosellada(sealed),stenopuedevolverasersobrescrito:

class CuentaBonificadaEspecial : CuentaBonificada


{
public override ObtenerIntereses() {
// ERROR: MTODO NO SOBRESCRIBIBLE
}
}

La clase CuentaBonificadaEspecial no admite la sobrescritura del mtodo


ObtenerInteresesporsersellado.Estoesinteresantesisedeseaquelafuncionalidad
delmtodopermanezcainalterableenlasclaseshijas.

Nodebeconfundirseunmtodoselladoconunmtodonosobrescribible.Sisedesea
queunmtodonopuedasersobrescritoenningunaclasehija,bastaconnodeclararlo
virtual.

2.3.ClasesAbstractas

Las clases abstractas son un tipo de clases especiales que se emplean como raz o
cabezadejerarquasdeherenciaenlasqueunasclasesseheredandeotrasavarios
niveles. Estas clases se caracterizan por definir mtodos sin incluir ningn tipo de
cdigo para que sean las clases hijas las que les asignen cdigo sobrescribindolos.
Estosmtodossincdigorecibenelnombredemtodosabstractos.

Noesobligatorioquelasclasesabstractascontenganmtodosdeestetipo,peroslo
es marcarla como abstracta si contiene almenos uno. Los mtodos abstractos se
definenprecediendosudefinicinlapalabraclaveabstract.

// Clase abstracta
public abstract class A
{
// Mtodo abstracto
public abstract void F();
}

Un mtodo definido como abstracto no tiene cdigo y no es posible invocarlo. Las


clasesabstractasnoadmitenlainstanciacinynopuedencrearseobjetosdeellas.Por
suparte;lasclaseshijasdeunaclaseabstractadebensobrescribirtodoslosmtodos
abstractosdelaclasepadre,odelocontrarioseconviertentambinenabstractas.

Los mtodos abstractos se consideran implicitamente virtuales para permitir as su


necesariasobrescritura.

21

CIPSA - Programacin C# .NET

2.3.1.Sobrescriturademtodosasbtractos

Unmtododefinidocomoabstractoesimplcitamentevirtual,yaquedelocontrario
no podra ser redefinido en las clases hijas. Por ello la sobrescritura de un mtodo
abstracto se lleva acabo de igual manera que con un mtodo definido como virtual;
empleandolapalabraclaveoverride.

// Clase abstracta
public abstract class A
{
// Mtodo abstracto
public abstract void F();
}
// Clase C heredando de B
class C: A
{
// Sobrescritura de mtodo abstracto F.
public override void F()
{
}
}

En el caso de sobrescritura de mtodos abstractos no tiene sentido el uso de la


referencia predefinida base, puesto que el mtodo original no tiene cdigo ni
funcionalidadalgunaquereaprovechar.

2.4.ConversionesdetiposdeObjetos(BoxingyUnboxing)

2.4.1.Boxing

Una cualidad de la programacin orientada asociada a la herencia permite hacer


referenciaaunobjetodeunaclasehijaempleandounavariabledeinstanciadeltipo
delaclasepadre:

<tipopadre>obj=new<tipo_hija>();

En.NETtodaslasclasesheredandeformaimplicitadelaclaseSystem.Object,lacual
hacedeclasepadredetodaslasclasesincluidaslasdefinidasporelprogramador.Por
tanto; puede instanciarse un objeto de cualquier clase empleando una reerencia del
tipodeunaclasepadre:

// Declaracion de variable de instancia de tipo Object


Object cuenta;
// Instanciacin de la clase Cuenta.
cuenta = new Cuenta();

EnelcdigosecreaunainstanciadelaclaseCuentayseasociaaunavariabledetipo
Object.EstaoperacinrecibeelnombredeencajonadooBoxing.

22

CIPSA - Programacin C# .NET

El encajonado impone una restriccin: Slo pueden llamarse los mtodos miembros
definidosenlaclasepadre:

Seanlassiguientesdosclases:PuntoyPuntoColoreado.

class Punto
{
private int x;
private int y;
public Punto(int _x, int _y)
{
this.x = _x;
this.y = _y;
}
public int ObtenerX()
{
return this.x;
}
public int ObtenerY()
{
return this.y;
}
}
class PuntoColoreado : Punto
{
private String Color;
public PuntoColoreado(int _x, int _y, String _color)
: base(_x, _y)
{
this.Color = _color;
}
public String ObtenerColor()
{
return this.Color;
}
}

Es posible crear un objeto de la clase PuntoColoreado empleando una variable de


instanciadeltipoPunto:

Punto p = new PuntoColoreado(0, 0, "Verde");


Console.WriteLine("La posicion X es : {0}", p.ObtenerX());
Console.WriteLine("La posicion Y es : {0}", p.ObtenerY());
Console.WriteLine("El color es: {0}", p.ObtenerColor());

// ERROR!

Sinembargo,lavariabledeinstanciadetipoPuntoslopermitellamaralosmiembros
pblicos heredados de la clase padre: ObtenerX y ObtenerY. El mtodo miembro
ObtenerColornoresultaaccesible.

Para poder invocar a los miembros pblicos propios de PuntoColoreado es preciso


reasignarelobjetoaunavariabledeinstanciadeltipoPuntoColoreado.Estaoperacin
recibeelnombrededesencajonadooUnboxing.

23

CIPSA - Programacin C# .NET

2.4.2.Unboxing

Elunboxingodesencajonadoconsisteenconvertirunareferenciadetipopadreaotra
del tipo hijo correspondiente al objeto referenciado. Supngase las siguientes clases
relacionadasporunajerarquadeherencia:

PodraemplearseunavariabledeinstanciadetipoFiguraparareferenciarobjetosde
cualquieradelastresclaseshijas:

Figura f;
f = new Circulo();
f = new Pentagono();
f = new Triangulo();

Portanto,paradesencajonarunobjetoreferenciadoatravsdeunavariabledetipo
Figuraloprimeroesdeterminaraculdelastresclaseshijasperteneceelobjeto.Para
elloseempleaeloperadoris.

objis<tipo>

Eloperadordevuelvevalorlgicociertosielobjetoreferenciadoporlavariableobj
esunainstanciadelaclase<tipo>,yfalsoencasocontrario.

Figura f = new . . . ()
if (f is Circulo)
{
// Se ejecuta si y solo s, el objeto asociado a 'f'
// es una instancia de la clase Circulo
}

Una comprobado el tipo del objeto referenciado puede asignarse a una variable de
instanciadesupropiotipoempleandoeloperadoras:

Figura f = new Circulo();


if (f is Circulo)
{
Circulo objCirculo = f as Circulo; // UNBOXING
}

24

CIPSA - Programacin C# .NET

2.5.LaclaseSystem.Object

Todaslasclasesdefinidasen.NETheredandelaclasepadreSystem.Objectdemanera
implicita.EstohacequelosmtodosdefinidosenlaclaseObjectaparezcanheredados
entodaslasclasesdefinidasen.NET.

LosdosmtodosmsbsicosdefinidosenlaclaseObjectson:

publicvirtualboolEquals(objecto):Comparaunaobjetoconotroydevuelveciertosiambos
objetosseconsideraniguales,ofalsoencasocontrario.

public virtual string ToString() : Devuelve una cadena de texto con informacin descriptiva
sobreelobjetocontraelqueseinvoca.

Estos mtodos pueden sobrescribirse para adaptar su implementacin a las


caractersticas de cada clase. El mtodo toString puede sobrescribirse para obtener
una cadena de caracteres con los datos de un objeto, y el mtodo equals para
comparardosinstanciasdelaclase.

class Cuenta
{
private String numCuenta;
private String titular;
private decimal saldo;
public Cuenta(String _numCuenta, String _titular, decimal _saldo)
{
this.numCuenta = _numCuenta;
this.titular = _titular;
this.saldo = _saldo;
}
public override bool Equals(object obj)
{
if (obj is Cuenta)
{
Cuenta cuentaComparar = obj as Cuenta;
return (this.numCuenta == cuentaComparar.numCuenta);
}
else return false;
}
public override string ToString()
{
return "Num Cuenta: " + numCuenta.ToArray() + " Nombre: " + this.titular;
}
}

El ejemplo muestra el cdigo de la clase Cuenta donde se ha sobrescrito el mtodo


ToString() para que al ser invocado devuelva una cadena de caracteres con el texto
Num Cuenta: XXXXXX Nombre: XXXXXXX. De igual modo, el mtodo Equals est
sobrescritoparapermitirlacomparacindeobjetosCuentaporelvalordesuatributo
Cuenta.

25

CIPSA - Programacin C# .NET

2.5.1.Comparacindeobjetos.

Alahoradecomparardosobjetosdebediferenciarseentreelusodeloperador==yel
usodeunaversinsobrescritadelmtodoEquals.

Cuando se emplea con variables de instancia; el operador == nicamente indica si


hacen referencia al mismo objeto, es decir; compara nicamente la direccin de
memoria referenciada. El operador Equals por el contrario permite comparar dos
objetosenfuncindelosvaloresdesusatributos.

Sea:

class Cuenta
{
private String numCuenta;
private String titular;
private decimal saldo;
public Cuenta(String _numCuenta, String _titular, decimal _saldo)
{
this.numCuenta = _numCuenta;
this.titular = _titular;
this.saldo = _saldo;
}
public override bool Equals(object obj)
{
if (obj is Cuenta)
{
Cuenta cuentaComparar = obj as Cuenta;
return (this.titular == cuentaComparar.titular);
}
else return false;
}
public override string ToString()
{
return "Num Cuenta: " + numCuenta.ToArray() + " Nombre: " + this.titular;
}
}

Elsiguientecdigo:

Cuenta c1 = new Cuenta("0343", "Roger", 123455);


Cuenta c2 = new Cuenta("0293", "Roger", 123455);
// Comparacin de los objetos
Console.WriteLine(c1 == c2);

// DEVUELVE FALSO.

// Comparacin de dos cuentas


Console.WriteLine(c1.Equals(c2));

// DEVUELVE CIERTO

Eloperador==devuelvecomoresultadoFALSO,puestoquec1yc2sonvariablesde
instanciaapuntandoadosobjetosdistintosendiferentesdireccionesdememoria.

El operador Equals ha sido sobrescrito para comparar dos objetos Cuenta


considerndoquesonigualescuandosutitulareselmismo.Aspuesenelcdigode
ejempl,lallamadaalmtodoEqualsdevuelvecomoresultadoCIERTO,puestoquec1y
c2tienenelmismovalorparasuatributotitular.

26

CIPSA - Programacin C# .NET

2.6.ClasesFinales

Unaclasefinalesaquellaquenoadmiteherenciaynopermitenportantoladefinicin
deotrasclasesqueheredendeella.Paradeclararunaclasecomofinaldebeindicarse
lapalabraclavesealeddelantedeclass:

sealed class CuentaBonificada : Cuenta


{
}

Unaclasesedeclaracomofinalcuandonosedeseaquesecreenclasesqueextiendan
deestaclase.

2.7.Polimorfismo

Alencajonarunaobjetomedianteunareferenciadeunaclasepadreslolosmtodos
heredados de la clase padre resultan accesibles. No obstante, al llamar a mtodos
virtualessobrescritosseejecutaelcdigocorrespondientealaclasehijaenvezdela
delpadre.

Ejemplo: Supngase las siguientes cuatro clases. La clase padre Figura define un
mtodovirtualObtenerDescripcionqueessobrescritoporelrestodesusclaseshijas
Cuadrado,TringuloyCrculo:

class Figura
{
public virtual String ObtenerDescripcion() {
return "Soy una figura ";
}
}
class Cuadrado:Figura
{
public override string ObtenerDescripcion() {
return base.ObtenerDescripcion() + " de tipo Cuadrado.";
}
}
class Circulo : Figura
{
public override string ObtenerDescripcion() {
return base.ObtenerDescripcion() + " de tipo Crculo.";
}
}
class Triangulo : Figura
{
public override string ObtenerDescripcion() {
return base.ObtenerDescripcion() + " de tipo Tringulo.";
}
}

En el siguiente cdigo se crean dos instancias de las clases Crculo y Tringulo


asociadasavariablesdeinstanciadeltipodesuclasepadreFigura.

Figura f1 = new Circulo();


Figura f2 = new Triangulo();
Console.WriteLine(f1.ObtenerDescripcion());
Console.WriteLine(f2.ObtenerDescripcion());
Console.ReadKey();

27

CIPSA - Programacin C# .NET

DadoqueelmtodoObtenerDescripcin()estdeclaradoenlaclasepadrepuedeser
llamadoatravsdelareferenciadeltipoFigura.Sinembargoencadacasoseejecuta
el cdigo correspondiente a la sobrescritura de la clase a la que pertenece el objeto
referenciado.

Elresultadomostradoes:
Soy una figura de tipo Crculo
Soy una figura de tipo Tringulo.

Estacapacidadpermiteinvocaramtodossobrescritosenlasclaseshijasempleando
referencias del tipo de la clase padre. En cada caso, el cdigo ejecutado es el
correspondientealasobrescrituradelaclasehijaalaqueperteneceelobjetoseacual
sea.

28

CIPSA - Programacin C# .NET

3.Interfaces

Una interfaz es una declaracin de mtodos sin cdigo que representan una
funcionalidad. Una clase implementa un interfaz al declarar e implementar todos los
mtodos del interfaz. Esto confiere a sus objetos la funcionalidad descrita por el
interfaz.

3.1.Declaracineimplementacindeinterfaces.

Ladeclaracindeunainterfazessimilaraladeunaclaseperoempleandolapalabra
claveinterfaceenvezdeclass:

<modificadores>interface<nombre>:<interfacesBase>{

<miembros>
}

Ejemplo:
interface IVisualizable
{
public String ObtenerDatos();
}

Los nombres de las interfaces no representan conjuntos de elementos sino


funcionalidad. Sus nombres suelen corresponderse con adverbios precedidos por la
letaImayscula:IVisualizable,IComparable,IEnumerable...etc.

Adiferenciadelasclases,unainterfaznopuededefinirniatributos,niconstructoreso
destructores. Sus miembros nicamente pueden ser mtodos, propiedades,
indizadoresyeventos.

Mtodos:<tipoRetorno><nombreMtodo>(<parmetros>);
Propiedades:<tipo><nombrePropiedad>{set;get;}
Indizadores:<tipo>this[<ndices>]{set;get;}
Eventos:event<delegado><nombreEvento>;

Losmodificadoresdevisibilidadadmitidosenlasinterfacessonlosmismosquelosde
lasclase:public,private,protected.

Lasclasesimplementanlasinterfaces,noheredandeellas.Losmtodosdeclaradosen
un interfaz no son ni abstractos ni virtuales y no pueden emplearse palabras clave
comoabstractovirtualconellos.

29

CIPSA - Programacin C# .NET

Para indicar que una clase implementa uno o varios interfaces se emplea la misma
sintaxisqueconlaherencia:

class<identificador>:<interfaz1>,<interfaz2>,...

Ejemplo: Sean las dos interfaces IVisualizable y IComparable; la clase Figura puede
implementarambasinterfacesalmismotiempo:

interface IVisualizable
{
public String ObtenerDatos();
}
interface IComparable
{
public bool EsMayor(Object obj);
}

class Figura:IVisualizable, IComparable


{
public string ObtenerDatos()
{
...
}
public bool EsMayor(object obj)
{
...
}
}

EnelcdigomostradolaclaseFiguraincluyeeimplementalosmtodosdeclaradosen
las interfaces IVisualizable e IComparable. Se dice entonces que la clase implementa
ambasinterfaces.

3.2.HerenciaeImplementacin.

No deben confundirse clases abstractas e interfaces, ni la herencia con la


implementacin.Susprincipalesdiferenciassonlassiguientes:

Una clase abstracta puede definir mltiples o ningn mtodo abstracto. Una interfaz declara
todossusmtodossincdigo.

Unaclasepuedeimplementarmltiplesinterfaces,perosloheredardeunanicaclasepadre.
Ambascosassonposiblesalmismotiempo.

Una clase que implementa un interfaz est obligada a implementar todos los mtodos del
interfaz.Unaclasequeheredadeunaclaseabstractapuedenosobrescribirtodossusmtodos.

Debe existir una relacin semntica entre las clases relacinadas por herencia; las clases hijas
representanversionesmsconcretasdeltipodelaclasepadre.Sinembargo,noesnecesario
ningunarelacinentrelasclasesqueimplementanuninterfaz.

30

CIPSA - Programacin C# .NET

3.2.1.Ejemplodeherenciaeimplementacin.

Unaclasepuedeheredardeunaclasepadreeimplementarunoovariosinterfacesal
mismotiempo.

El siguiente cdigo muestra la declaracin del interfaz IImprimible que representa la


capacidaddepodermostrarporpantallalosdatosdeunobjeto.Elinterfazdeclaraun
nicomtodoImprimir.

// INTERFAZ IIMPRIMIBLE

interface IImprimible
{
void Imprimir();
}

// CLASE ABSTRACTA CON METODO ABSTRACTO CalcularSaldo

abstract class Cuenta


{
protected String numCuenta;
protected String titular;
protected decimal saldo;
protected int intereses;

public abstract float CalcularSaldo();


}

LasiguienteclaseCuentaBonificadaimplementaelinterfazIImprimibleyheredadela
claseabstractaCuenta:
class CuentaBonificada : Cuenta, IImprimible
{
private float bonificacion;

// IMPLEMENTACION METODO IMPRIMIR DEL INTERFAZ IIMPRIMIBLE

public void Imprimir()


{
Console.WriteLine(numCuenta + " : " + titular + " -> " + saldo.ToString());
}

// SOBRESCRITURA DEL METODO ABSTRACTO HEREDADO DE CUENTA


public override float CalcularSaldo()
{
...
}

3.3.Polimorfismoeninterfaces

Al igual que en el caso de la herencia, los objetos de una clase que implementa un
interfazpuedenserasociadosavariablesdeltipodelinterfaz.

IVisualizable objVisualizable = new Figura();


Console.WriteLine(objVisualizable.ObtenerDatos());

Enelcdigodeejemplo;lavariabledeinstanciaobjVisualizablepodraemplearsepara
referenciaraunobjetodecualquierclasequeimplementeelinterfazIVisualizable.Sin
embargo;slopodrnllamarselosmtodosdeclaradosenelinterfaz.

31

CIPSA - Programacin C# .NET

No obstante; NUNCA puede crearse un objeto a partir del tipo de una interfaz. El
siguientecdigogeneraraunerror:

IVisualizable objVisualizable = new IVisualizable(); // ERROR

En este sentido, un intefaz se comporta como una clase abstracta la creacin de


objetosapartirdesutipo.

3.4.Extensinentreinterfaces.

Unainterfacepuededeclararseextendiendootrayaexistenteincluyendoastodossus
mtodos:

interface IActualizable
{
void Actualiza();
}
interface IDibujable : IActualizable
{
void Dibuja();
}

Enelejemplo,elinterfazIDibujableextiendeelinterfazIActualizableincluyendoasel
mtodo Actualiza(). Una clase que implemente el interfaz IDibujable deber
implementarambosmtodos:Actualiza()yDibuja().
class Componente : IDibujable
{
public void Dibuja ()
{
...
}
public void Actualiza ()
{
...
}
}

32

CIPSA - Programacin C# .NET

4.Excepciones

Unaexcepcineslarepresentacindeunerrordeejecucin.Cuandolamquinade
ejecucin de .NET ( CLR ) detecta una situacin anmala que impide continuar la
ejecucin,lanzaunaexcepcin.

4.1.Lasexcepcionesen.NET

LasexcepcionesdentrodelFramework.NETestnrepresentadasporunconjuntode
clases derivadas todas ellas de la clase padre System.Exception. Cada excepcin
representeundeterminadotipodeerror.

Algunasdelasmshabitualessonlassiguientes:

DivideByZeroException:Divisinporcero
IndexOutOfRangeException: Indice de acceso a elemento de tabla fuera del rango vlido
(menorqueceroomayorqueeltamaodelatabla)
InvalidCastException:Conversinexplcitaentretiposnovlida
NullReferenceException:Accesoamiembrodeobjetoquevalenull
OverflowException:Desbordamientonumrico.
OutOfMemoryException:Faltadememoriaparacrearunobjetoconnew
StackOverflowException: Desbordamiento de la pila, generalmente debido a un excesivo
nmerodellamadasrecurrentes.

Todas las clases excepciones comparten una serie de mtodos y propiedades


heredados de su clase padre System.Exception. Estos permiten obtener informacin
sobreelorigenycausasdelerrorquerepresentalaexcepcin:

string Message: Propiedad de slo lectura que proporciona un mensaje descriptivo de las
causasdelaexcepcin.Pordefectoestemensajeesunacadenavaca()

stringStackTrace:Retornaunalistaconelcontenidodelapiladellamadasamtodosquese
tenaenelmomentoenqueseprodujolaexcepcin.Estapilaesunacadenaconinformacin
sobreelmtodoenqueseprodujolaexcepcin,yelmtodoqueloinvoc.Ej:
string Source: Almacena informacin sobre cul fue la aplicacin u objeto que caus la
excepcin.

ExceptionInnerException:Retornalaexcepcinanidada.Unaexcepcinpuedeirasociadaa
otra producida anteriormente. En tal caso, la excepcin original es accesible mediante esta
propiedad.

33

CIPSA - Programacin C# .NET

4.2.CapturadeExcepciones(TryCatchFinally)

Cuandoseproduceunaexcepcindebesercapturadaparapodertratarelproblemay
darle una solucin. En caso contrario; la excepcin provocar la interrupcin de la
aplicacinmostrandounmensajedeerror.

Vistadelmensajedeerrordeejecucinmostradoporunaaplicacin.NETalproducirseunaexcepcinnocapturada.

Paracapturarunaexcepcindebeencapsularseelcdigoquepuedeoriginarladentro
deunaestructuratrycatchfinally:

try
{
// CODIGO GENERADOR DE EXCEPCION -> BLOQUE TRY
}
catch (<tipo excepcion1> ex)
{
// CODIGO DE MANEJO DE EXCEPCION 1 -> BLOQUE CATCH 1
}
catch (<tipo excepcion2> ex)
{
// CODIGO DE MANEJO DE EXCEPCION 2 -> BLOQUE CATCH 2
}
catch (<tipo excepcion3> ex)
{
// CODIGO DE MANEJO DE EXCEPCION 3 -> BLOQUE CATCH 3
}
finally
{
// CODIGO DE FINALIZACION -> BLOQUE FINALLY
}

La secuencia de cdigo que puede producir el error se sita en el bloque try. Cada
clusula catch hace referencia a un tipo de excepcin y encapsula el cdigo que se
ejecuta si se produce. El bloque finally es opcional y contiene cdigo que se ha de
ejecutarsiempreseproduzcaonounerror.

34

CIPSA - Programacin C# .NET

Enelsiguientecdigopuedenproducirsealmenosdostiposdeexcepciones:

a = Convert.ToInt32(Console.ReadLine());
b = Convert.ToInt32(Console.ReadLine());
r = a / b;
Console.WriteLine("La division de {0} entre {1} es {2}", a, b, r);

Las dos primeras sentencias pueden producir una excepcin FormatExceptin si el


usuario introduce no numrico. La tercera lnea de cdigo puede producir una
excepcinDivideByZeroExceptionsielusuariointroduceelvalor0enlavariableb.

Para capturar ambas excepciones debera encapsularse el cdigo en una estructura


trycatchconlasiguienteforma:

int a;
int b;
float r;
try
{
a = Convert.ToInt32(Console.ReadLine());
b = Convert.ToInt32(Console.ReadLine());
r = a / b;
Console.WriteLine("La division de {0} entre {1} es {2}", a, b, r);
}
catch (FormatException ex)
//
CAPTURA DE VALOR NO NUMERICO
{
Console.WriteLine("El valor introducido no es vlido");
}
catch (DivideByZeroException ex)
//
CAPTURA DE DIVISION POR CERO
{
Console.WriteLine("Division por cero detectada.");
}
catch (Exception ex)
//
CAPTURA EXCEPCION DESCONOCIDA
{
Console.WriteLine("Error desconocido: " + ex.Message);
}
finally
{
Console.WriteLine("Adios");
Console.ReadKey();
}

Cadaclasulacatchseocupadecapturaruntipodeexcepcin.Siseproducecualquier
excepcin, sta se compara con el tipo de excepcin de cada clusula catch hasta
encontrar una que coincida. Una vez que se encuentra se ejecuta el cdigo
correspondiente.Siporelcontrarioningunaclusulacoincideconeltipodeexcepcin
ocurrida,laexcepcinquedasincapturarypodrallegarainterrumpirlaaplicacin.

ParaevitarlolaltimaclusulacatchcapturalaexcepcinException.Estaclusulase
ponesiemprelaltimayescapazdecapturarcualquierexcpecinindependientemente
del tipo que sea. Esto es debido a que Exception es la clase padre de todas las
excepcionesylasrepresentaatodas.

PorqunoemplearunanicaclusulacatchconeltipoException?.Elmotivoesque
sibienesopermitiracapturarcualquierexcepcinquesediera,resultaraigualmente
difcil diferenciar qu tipo de error es. El empleo de mltiples clusulas catch con
diferentesexcepcionesobedecealanecesidaddetratarcadaerrordemaneradistinta.

35

CIPSA - Programacin C# .NET

Laclusulafinallycontieneunaseccindecdigoqueseejecutapaseloquepase.Esta
sueleemplearseparaincluiroperacionesquedebenejecutarseinclusosisedieraun
error,comoporejemplo;cierresdeficherooconexionesabasesdedatos.

Seaelsiguientecdigo:

try
{
Console.WriteLine("INICIO TRY");
String cadena = "HOLA";
int numero = Convert.ToInt32(cadena);

// Provoca FormatException

Console.WriteLine("FIN TRY");
}
catch (FormatException ex)
{
Console.WriteLine("CATCH");
}
finally
{
Console.WriteLine("FINALLY");
Console.ReadKey();
}

Alejecutarse,elresultadomostadoporpantallaes:

INICIO TRY
CATCH
FINALLY

AlproducirselaexcepcinFormatException,laejecucinsaltadelbloquetryalcdigo
comprendidoenlaclusulacatchdelaexcepcin,ydeahalbloquefinally.

Encasodenoproducirseningunaexcepcin,elresultadomostradosera:

INICIO TRY
FIN TRY
FINALLY

Portanto,encasodeausenciadeerroreselcdigodelbloquefinallyseejecutauna
vezterminadalaejecucindelbloquetry.

36

CIPSA - Programacin C# .NET

4.3.Propagacindeexcepciones

Cuando se produce una excepcin el sistema busca una estructura trycatchfinally


capazdecapturarlaexcepcin.

Siseproduceunaexcepcinenelcdigodeunmtodoynoescapturada,lamquina
de ejecucin ( CLR ) buscar una estructura trycatchfinally capaz de hacerlo en el
cdigodelmtodollamante.

De igual modo, si el mtodo llamante no contiene ninguna estructura trycatch, se


buscarenelmtodoquelollamo.Elprocesoserepetirsucesivamentehastaque:

Se encuentre una estructura trycatch que capture el tipo de excepcin


adecuado o Exception en su defecto La aplicacin puede recuperarse y
continuarlaejecucin.

Se llegua al mtodo de inicio main sin encontrar una estructura trycatch que
capturelaexcepcinLaaplicacinseinterrumpedefinitivamentemostrando
unmensajedeexcepcinnocapturada.

El siguiente esquema muestra el mecanismo de propagacin descrito en una


excepcin:

37

CIPSA - Programacin C# .NET

Ejemplo:

LaclasecontieneunafuncinFunc1queinvocaasuvezaunafuncinFunc2dentrode
unaestructuratrycatch:

class Program
{
public static void Func1()
{
Console.WriteLine("Inicio Func1...");
try
{
Console.WriteLine("inicio bloque try...");
Func2();
Console.WriteLine("fin bloque try...");
// NO EJECUTA
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Excepcion capturada");
}
Finally
{
Console.WriteLine("Fin Func1...");
}
}

ElmtodoFunc2estprogramadoparaprovocardeliberadamenteunaexcepcinde
divisinporcero(DivideByZeroException).
public static void Func2()
{
Console.WriteLine("Inicio Func2...");
int b = 0;
int a = 1;
float r = a / b;
Console.WriteLine("Fin Func2...");
}

Finalmente,elmtododeinicioMain,invocaalmtodoFunc1.
public static void Main()
{
Console.WriteLine("INICIO MAIN...");
Func1();
Console.WriteLine("FIN MAIN...");
Console.ReadKey();
}
}

Alejecutarseelcdigo,elresultadomostradoeselsiguiente:

INICIO MAIN
INICIO FUNC1
INICIO BLOQUE TRY
INICIO FUNC2
EXCEPCION CAPTURADA
FIN FUNC1
FIN MAIN

El mtodo Func2 provoca la excepcin. Ya que no tiene ninguna estructura trycatch


quelacapture,stasepropagaalmtodollamanteFunc1.ElmtodoFunc1detectala
excepcinylaejecucinsaltaalbloquecatchcorrespondiente.Finalmenteseejecuta
el cdigo del bloque finally y la ejecucin retorna al mtodo de inicio main que lo
invoc.

38

CIPSA - Programacin C# .NET

4.4.LanzamientodeExcepciones.

Lasexcepcionessongeneradasporlamquinadeejecucin(CLR)comorespuestaa
errores que imposibilitan la ejecucin normal del cdigo. No obstante; tambin es
posible generar una excepcin manualmente mediante cdigo para indicar una
situacindeerror.

Para lanzar una excepcin debe emplearse la palabra clave throw seguida de la
instanciacindelaclaseExceptionempleandoalgunodesusconstructores:

Lanzaunaexcepcingeneralsinningntipodeinformacinasociada.
throw new Exception();

Lanzaunaexcepcingeneralconelmensajeinformativoindicado.El mensaje
puederecuperarseenelcatchaccediendoalapropiedadMessage.

throw new Exception("Error de conexion");

Lanzaunaexcepcingeneralasociadaaunaexcepcinsucedidapreviamente.
LaexcepcinpuederecuperarseatravsdelapropiedadinnerException.
throw new Exception("Error de conexion", excepcion);

Ejemplo: La clase Persona implementa las propiedades pblicas Nombre y Edad que
permitenobteneryestablecerelvalordelosatributoscorrespondientes.

public class Persona


{
private String nombre;
private String apellido;
private int edad;

LapropiedadNombregeneraunaexcepcinencasoqueseasigneunacadenade
textovacacomonombre.
public String Nombre
{
get { return this.nombre; }
set
{
if (String.IsNullOrEmpty(value))
{

throw new Exception("El nombre no puede ser una cadena vaca.");

}
else
{
this.nombre = value;
}
}
}

39

CIPSA - Programacin C# .NET

Deigualmodo,lapropiedadEdadgeneraunaexcepcinsielvalorindicadonoest
comprendidoentre0y100.
public int Edad
{
get { return this.edad; }
set
{
if (value >= 0 && value <= 100)
{
this.edad = value;
}
else
{
}

throw new Exception("Valor fuera de rango permitido,");

}
}
}

Es importante tener presente que una excepcin debe ser capturada de igual modo
independientemente de si es provocada por el sistema o manualmente mediante
cdigo. En ambos casos, la excepcin puede llegar a interrumpir fatalmente la
ejecucindelaaplicacin.

4.6.Creacindeexcepcionespersonalizadas

Todaslasexcepcionesdefindasen.NETsecorrespondenconclasesqueheredandela
clase System.Exception. Es posible crear tipos propios de excepciones definiendo
clases propias que hereden tambin de Exception. Esto da lugar a excepciones
personalizadas.

Las excepciones personalizadas identifican y distinguen distintas situaciones


consideradas como errores en el cdigo de una aplicacin o librera de clases. Por
convenio, todas las clases que representan excepciones deben terminar su nombre
conalsufijoException:
public class ClaveIncorrectaException : Exception
{
public ClaveIncorrectaException() : base("La clave no es correcta") { }
}

En el cdigo de ejemplo se muestra la declaracin de la excepcin personalizada


ClaveIncorrectaException con un mensaje de error predeterminado mediante la
propiedadMessageheredadadeException.

El lanzamiento de excepciones personalizadas sigue las mismas normas que las


excepcionesdelsistema:

throw new ClaveIncorrectaException();

40

CIPSA - Programacin C# .NET

Cualquierexcepcinlanzadamedianteporcdigo,bienpertenezcaa.NET,odefinida
por el usuario; debe ser igualmente capturada y tratada mediante el empleo de
estructurastry..catch.

4.7.LagestindeExcepciones

Lasexcepcionesexistenparasealarsituacionesdeerrorinesperadasquepuedanser
capturadasytratadas.Sinembargo;comonormageneraldebeintentarseprevenirlas
excepcionesenvezdedejarqueocurranycapturarlas.

Ejemplo: La siguiente funcin solicita al usuario un valor numrico. Si el usuario


introduce un valor no numrico se le vuelve a solicitar hasta que lo introduzca
correctamente:

public int SolicitarValor(String mensaje)


{
bool valorCorrecto = false;
int valor = 0;
String cadena;
do
{
try
{
Console.WriteLine(mensaje);
cadena = Console.ReadLine();
valor = Convert.ToInt32(cadena);
valorCorrecto = true;
}
catch (FormatException ex) {
Console.WriteLine("El valor introducido no es vlido.");
}
} while (!valorCorrecto);
return valor;
}

La funcin captura de la excepcin FormatException para detectar un error de


validacin. Sin embargo, ste problema puede detectarse y resolverse sin que se
produzcalaexcepcinempleandoelmtodoTryParse:

public int SolicitarValor(String mensaje)


{
bool valorCorrecto = false;
int valor = 0;
String cadena;
do
{
Console.WriteLine( mensaje );
cadena = Console.ReadLine();
valorCorrecto = int.TryParse(cadena, out valor);
if (!valorCorrecto)
{
Console.WriteLine("El valor no es vlido.");
}
}
while ( !valorCorrecto);
return valor;
}

En general es preferible la segunda manera a la primera pues evita el lanzamiento y


captura de una excepcin. Las excepciones slo deben emplearse para sealar
situacionesdeerroresquenopuedenprevenirse.

41

CIPSA - Programacin C# .NET

EjerciciosPOO

1.Aritmetica

Crearunaclasequepermitarealizarclculosmatemticos.

Laclasedebeposeerunconstructorquerecibadosparmetrosenteros,ypropiedades
pblicas para modificar el valor de sus atributos. Deben crearse cuatro funciones
miembropblicas:sumar(),restar(),producto()ydivisin();quedevolverncadaunael
resultadodelaoperacincorrespondientesobrelosatributos.

Realizar una pequea aplicacin que solicite al usuario dos valores por consola y le
permiteseleccionaraoperacinarealizarmedianteunmen.Enelcasodeladivisin,
sielvalorindicadocomodivisorescerodebecapturarselaexcepcincorrespondiente
ymostrarunmenajeDIVISIONPORCERO.

2.ControldeUsuario

a.Creaunaclasequeidentifiquelacuentadeunusuarioenunsistema.Susobjetos
deben almacenar el nombre real del usuario, su nombre de usuario en el sistema, y
una contrasea. Tambin es necesario almacenar un valor lgico que indique si el
usuarioestconectadoono.

Laclasedebeposeerunconstructorquerecibalosvaloresnecesarios,ylossiguientes
mtodos:

public bool EstaConectado


public void Desconectar();
public void Conectar(String usuario, String contrasea);
public bool CambiarClave(String clave_antigua, String clave_moderna);

El mtodo CambiarClave() devuelveun valor lgico cierto si la contrasea antiguaes


correctaysemodificaconlamodernaindicada,ofalsoencasocontrario.

b. Modifica el mtodo Conectar() de modo que produzca una excepcin de tipo


Exceptionencasodequeelusuariointroduzcavaloresincorrectos.Laexcepcindebe
contenerlossiguientesmensajesdescriptivos:

Sielnombredeusuarioesincorrecto:Nombredeusuariodesconocido.
Silacontraseaesincorrecta:Contraseaincorrecta.

42

CIPSA - Programacin C# .NET

c.Definedosexcepcionespersonalizadas:

ArgumentoNoValidoException. Debe admitir la indicacin de una cadena de


textocomomensajedescriptivoalserlanzada.
ClaveIncorrectaException: Debe contener el mensaje descriptivo: La
contraseaantiguaindicadanoesvlida.

Estas excpeciones deben ser lanzadas por el mtodo CambiarClave en los siguientes
casos:
Si el usuario introduce una cadena vaca como argumento para clave_antigua
se genera una excepcin ArgumentoNoValidoException con el mensaje
clave_antiguanopuedeserunacadenavaca..

Sielusuariointrodocueunacadenavacacomoargumentoparaelparmetro
clave_modernaselanzalamismaexcepcinconelmensajeclave_modernano
puedeserunacadenavaca.

3.Mapas

Crealassiguientesclasesconlosrequisitosindicadosencadacaso:

a.Creaunaclasequerepresenteunelementosituadoenunmapa.Decadaelemento
seobtienensuscoordenadasmediantedosatributosprotegidosdetipoenteroxey.
LaclaseElementoGPSdebetenerunconstructorparametrizadoyunmtodoabstracto
llamadoVisualizar()quedevuelvaunacadenadetexto.

b.CreaunaclaseEdificioquepermiterepresentarlainformacindeunedificioenun
mapa incluyendo su direccin. La clase debe heredar de la clase ElementoGPS. La
sobrescritura del mtodo Visualizar() debe devolver una cadena de texto con el
siguienteformato:Edificio<direccion>en<x>,<y>.

c.CreaunaclaseVehculoquepermiterepresentarlainformacindeunvehculoen
unmapaincluyendosumatrcula.LaclasedebeheredardelaclaseElementoGPS.La
sobrescritura del mtodo Visualizar() debe devolver una cadena de texto con el
siguienteformato:Vehculo<matricula>en<x>,<y>.

43

CIPSA - Programacin C# .NET

d.DefineunainterfazIMapeablequeincluyalossiguientesmiembros:

interface IMapeable
{
int CoordX();
int CoordY();
double CalcularDistancia(IMapeable objB);
}

e. Implementa la interfaz IMapeable en las clases Edificio y Vehculo. Los mtodos


coordX y coordY deben devolver los valores de los atributos x e y. El mtodo
CalcularDistanciadevuelveladistanciaentreelobjetocontraelqueseinvocayaquel
quesepasacomoargumento.

Elclculodeladistanciadadacomoresultadoserealizaaplicandolasiguientefrmula:

D(objA,objB)=(objA.coordXobjB.coordX)2+(objA.coordYobjB.coordY)2

Para probar la implementacin de las clases crea un objeto Edificio y una matriz de
objetosVehculo.AcontinuacinordenalosobjetosVehculoporsucercanaalobjeto
Edificioindicadoalprincipio.

4.Tiempo

a. Crea una clase Tiempo que represente unahora del da. La clase debealmacenar
comovaloreslahora,losminutosylossegundos.Laclasedebetenerunconstructor
parametrizadoypropiedadesquepermitenaccederasusatributos.

Deben controlarse las siguientes restricciones con respecto a los valores de los
atributostantodesdeelconstructorcomodesdelaspropiedades:

Elatributohoraadmitevaloresenteroscomprendidosentre0y23incluidos.Encaso
deerrorselanzaExcepcionconmensajeHorafueraderango.

Losatributosminutosysegundosadmitenvaloresenteroscomprendidosentre0y59
incluidos.EncasodeerrorselanzaExcepcinconmensajeMinutos/Segundosfuera
derango.

b. Implementar la interfaz System.IComparable de .NET en la clase Tiempo para


permitir la comparacin de dos instancias. Debe implementarse para ello el mtodo
CompareTodefinidoporlainterfaz:

public int CompareTo(object obj)

44

CIPSA - Programacin C# .NET

Elmtododebedevolverlossiguientesvalores:

1Siobjesunahoraposterioralaquerepresentaelpropioobjeto.
0Siobjsecorrespondeconlamismahorarepresentadaporelpropioobjeto
1Siobjesunahoraanterioralaquerepresentaelpropioobjeto.

c. Sobrescribir los mtodos ToString y Equals heredados de la clase Object. La


sobrescritura del mtodo Equals() debe devolver el valor lgico cierto si y solo s, el
objetopasadocomoparmetroesdetipoTiempoysusatributosvalenlomismoque
los del objeto contra el que se instancia el mtodo. La sobrescritura del mtodo
ToString()debedevolverunacadenaconelformato:<hora>:<minutos>:<segundos>.

5.Gestindeconexiones

Crea una clase Conexin que representa una conexin a una base de datos. La clase
debeimplementarlossiguientesmtodos:
public bool EstaConectado;
public bool Conectar();
public void Desconectar();

Labasededatossoportaunlmitedecincoconexionessimultneas,porloquedebe
asegurarse que no haya nunca ms de cinco objetos Conexin conectados al mismo
tiempo.

ElmtodoConectar()estableceelobjetocomoconectadosinoestabayaconectadoy
noserebasaelmximodecincoconexionessinmultaneas.Entalcasoseretornaun
valor lgico cierto. Si el mximo de conexiones se ha alcanzado o el objeto ya est
conectado se devuelve un valor lgico falso. El mtodo Desconectar() establece el
objetocomodesconectado.

Para controlar el nmero total de objetos conectados al mismo tiempo emplea un


atributo esttico entero que se incremente cuando un objeto se conecta, y
decrementecuandounobjetosedesconecta.

45

CIPSA - Programacin C# .NET

6.Bancario

a. Crea una clase Cliente que incluya como atributos su DNI, nombre y telfono. La
clase debe contener un constructor parametrizado y las propiedades
correspondientes. La clase debe incluir una sobrescritura del mtodo ToString() que
devuelvaunacadenadetextoconelvalordetodoslosatributos.

b.CreaunaclaseCuentaBancariaquerepresentaunacuentabancariadeuncliente
en un banco. La cuenta debe incluir atributos como capital, intereses y un atributo
titular de tipo Cliente, que representa al cliente titular de la cuenta. La clase debe
contarconlossiguientesmtodos.

Constructor:
public CuentaBancaria(Cliente cliente, Decimal capitalInicial, Decimal interes);

Propiedad sobrescribible de slo lectura que devuelve el capital actual


incluyendolosinteresessobreelcapitalactual:
public virtual Decimal Capital;

Elclculodebeser:capital+=capital*inters;

La clase debe incluir adems una sobrescritura del mtodo ToString() que devuelve
unacadenaconelconjuntodevaloresdelacuentayeltitular.

c. Crea una clase CuentaBancariaBonificada que hereda de la clase CuentaBancaria


aadiendounatributobonificacindetipodecimaldoble.Laclasedebesobrescribirla
propiedad Capital para que retorne el valor del capital incluyendo los intereses
calculadossobreelvalordelatributointersmselvalordelabonificacin.

Elclculodebeser:capital+=capital*(inters+bonificacin)
DebesobrescribirseparcialmenteelmtodoToString()paraquedevuelvaunacadena
conelvalordetodoslosatributosdelacuentabancariaincluyendolabonificacin.

46

Você também pode gostar