Programaci´n o Orientada a Objetos C#

F´lix G´mez M´rmol e o a
3o Ingenier´ Inform´tica ıa a Julio de 2004

2

´ Indice general
´ Indice General 2. Clases y Objetos 2.1. Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1. Estructura . . . . . . . . . . . . . . . . . . . . . . . 2.1.2. Ocultaci´n de la informaci´n . . . . . . . . . . . . . o o 2.1.3. Relaciones entre clases: Cliente-Servidor y Herencia 2.1.4. Visibilidad . . . . . . . . . . . . . . . . . . . . . . . 2.2. Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Mensajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1. Sintaxis. Notaci´n punto . . . . . . . . . . . . . . . . o 2.3.2. Sem´ntica . . . . . . . . . . . . . . . . . . . . . . . . a 2.4. Sem´ntica referencia versus sem´ntica almacenamiento . . . a a 2.5. Creaci´n de objetos . . . . . . . . . . . . . . . . . . . . . . o 2.5.1. Destructores . . . . . . . . . . . . . . . . . . . . . . 2.6. Sem´ntica de la asignaci´n e igualdad entre objetos . . . . . a o 2.7. Genericidad . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8. Definici´n de una clase “Lista Doblemente Enlazada” . . . o 3. Dise˜ o por Contrato: Asertos y Excepciones n 3.1. Contrato software . . . . . . . . . . . . . . . . 3.2. Clases y Correcci´n del software: Asertos . . o 3.3. Excepciones en C# . . . . . . . . . . . . . . . 3.3.1. Lanzamiento de excepciones . . . . . . 3.3.2. Bloques try . . . . . . . . . . . . . . . 3.3.3. Manejadores . . . . . . . . . . . . . . 3.4. Conversi´n de asertos en excepciones . . . . . o 4. Herencia 4.1. Introducci´n . . . . . . . . . . . . . . . . . o 4.2. Doble aspecto de la herencia . . . . . . . . 4.3. Polimorfismo . . . . . . . . . . . . . . . . 4.3.1. Sobrecarga . . . . . . . . . . . . . 4.3.2. Regla de aplicaci´n de propiedades o 4.3.3. Estructuras de datos polim´rficas . o 4.3.4. Operadores is y as . . . . . . . . 4.4. Ligadura Din´mica . . . . . . . . . . . . . a 4.5. Clases Diferidas . . . . . . . . . . . . . . . 4.5.1. Interfaces . . . . . . . . . . . . . . 4.6. Herencia, reutilizaci´n y extensibilidad del o 4.7. Herencia m´ltiple . . . . . . . . . . . . . . u 3 4 5 5 5 7 8 9 10 10 10 10 11 11 12 12 14 14 17 17 17 18 20 21 22 22 25 25 26 26 27 29 29 29 30 31 32 34 37

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . software . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

4

´ INDICE GENERAL

4.7.1. Problemas: Colisi´n de nombres y herencia repetida . . . . . . . . . . o 4.7.2. Ejemplos de utilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8. C#, Java y C++: Estudio comparativo . . . . . . . . . . . . . . . . . . . . . ´ Indice de Figuras ´ Indice de Tablas ´ Indice de C´digos o Bibliograf´ ıa

37 38 39 41 43 45 47

son: Atributos. } } C´digo 2.") . int lunaKilo . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // Distancia hasta la Luna convertida a kil´ metros o using System . 2.609) . Sus caracter´ ısticas m´s destacables son que se trata de entidades sint´cticas y que descria a ben objetos que van a tener la misma estructura y el mismo comportamiento. WriteLine (" Kil´ metros = " o + lunaKilo + " km . Clases Definici´n 2.Tema 2 Clases y Objetos 2. que no son m´s que operaciones aplicables sobre los objetos.1 Una clase es una implementaci´n total o parcial de un tipo abstracto de o o dato (TAD). y M´todos. Console .1. convierte a kil´metros la o o distancia de la Tierra a la Luna en millas.1 La clase mostrada en el c´digo 2.1. que determinan una estructura de almacenamiento para cada objeto de la clase. public class Luna { public static void Main () { int luna = 238857. llamada Luna.1. Console . que a partir de ahora llamaremos miembros.1. e a Ejemplo 2. Estructura Los componentes principales de una clase.1: Clase Luna o 5 . lunaKilo = ( int ) ( luna * 1. WriteLine (" De la Tierra a la Luna = " + luna + " millas ") .

7 × 1038 ) de 15 a 16 d´ ıgitos significativos −28 .3: Otros tipos primitivos Tipos de datos primitivos Las tablas 2.6 Tema 2. 2147483647) (0. Alberto = 15}). Alex. 7. 65535) (-2147483648. Para declarar un tipo consistente en un conjunto etiquetado de constantes enteras se emplea la palabra clave enum (por ejemplo.1: Tipos enteros primitivos Tipo float double decimal Bytes 4 8 16 Rango de Valores (±3.1.4 muestra las palabras reservadas de C#. Clases y Objetos Tipo short ushort int uint long ulong Bytes 2 2 4 4 8 8 Rango de Valores (-32768.255) {true. 32767) (0.127) (0.2 y 2.2: Tipos flotantes primitivos Tipo byte ubyte bool char Bytes 1 1 1 2 Rango de Valores (-128.9 × 10+28 ) de 28 a 29 d´ (10 ıgitos significativos Tabla 2. abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach get goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed set short sizeof stackalloc static string struct switch this throw true try typeof unit ulong unchecked unsafe ushort using value virtual void volatile while Tabla 2. e Palabras reservadas La tabla 2. 2. 4294967295) (-9223372036854775808.3 muestran los tipos primitivos soportados por C#. enum Edades {F´lix = 21.4 × 1038 ) 7 d´ ıgitos significativos (±1.4: Palabras reservadas . 18446744073709551615) Tabla 2. 9223372036854775807) (0. false} Tabla ASCII Tabla 2.

2 En el c´digo 2. mediante o o o la clase Punto. public static readonly m. . . u Un miembro con acceso privado (opci´n por defecto) s´lo es accesible desde otros miemo o bros de esa misma clase. x = 5. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Punto { private double x . // Correcto w .2 se muestra un ejemplo de ocultaci´n de informaci´n.3 En el siguiente c´digo. Ocultaci´n de la informaci´n o o En ocasiones conviene ocultar ciertas caracter´ ısticas (atributos y/o m´todos) de una clase e al exterior. el servidor deber´ o ıa ocultar los aspectos de implementaci´n al cliente. } } . y = v. en una relaci´n entre clases de Cliente-Servidor.1 Clases 7 2. o Para llevar a cabo esto.6.1.9) . o Una forma de simular el efecto de const mediante readonly es usando adem´s la palabra a clave static. Para ello nos u valemos de los modificadores de acceso get y set. mientras que uno con acceso p´blico es accesible desde cualquier u clase. w . Otra pr´ctica interesante consiste en declarar un atributo como privado y. public void SetPunto ( double u .5. // Error sint´ ctico a . . // O simplemente double x . mediante otro a atributo p´blico tener acceso de lectura y/o escritura sobre el atributo privado. } } C´digo 2. .2: Ejemplo de Ocultaci´n de Informaci´n o o o A diferencia de C++. Ejemplo 2. Por ultimo. C# proporciona tres tipos de acceso: p´blico. n y m podr´ o ıamos decir que son “estructuralmente equivalentes”: public const n. mientras que con la segunda opci´n la inicializaci´n se da en o o o tiempo de compilaci´n. un miembro protegido s´lo es accesible por miembros de la misma clase o ´ o bien por miembros de alguna de las subclases.3 . Obs´rvese que el identificador value es siempre un objeto del mismo tipo que el atributo e que lo contiene.2.2. class Test { public void Prueba ( Punto w ) { . SetPunto (4. . y .4 En el c´digo 2. Ejemplo 2. en C# es posible declarar un miembro como de s´lo lectura mediante o la palabra clave readonly.3 se muestra un ejemplo de ocultaci´n de informaci´n mediante o o o el uso de get y set. Ejemplo 2. double v ) { x = u. . privado y protegido. y . La diferencia entre readonly y const es que con la primera opci´n la inicializaci´n tiene o o lugar en tiempo de ejecuci´n. Por ejemplo. .

2 Una clase A se dice que es cliente de una clase B. adaptable. . Definici´n 2. o A⇐B (a) B ↑ A (b) Figura 2. } // Acceso de lectura set { // Acceso de escritura if ( value . } .1.1. Length != 0 ) m_file_output = value .1. . } Por su parte. en cambio.8 Tema 2. o e El creador de la clase. si A contiene una declao raci´n en la que se establezca que cierta entidad (atributo. Clases y Objetos 1 2 3 4 5 6 7 8 9 10 11 12 13 public class CuentaPalabras { private string m_file_output . es decir. variable local) e es de o a tipo B. o La figura 2.3. o bien si A es una implementaci´n de B (herencia o o de implementaci´n). e o pero sin importarle su implementaci´n (siempre que ´sta sea eficiente y potente). si A es una versi´n especiao o lizada de B (herencia de especializaci´n). B conta. . } } } C´digo 2.3: Otro ejemplo de Ocultaci´n de Informaci´n o o o 2.1. . . conocer su especificaci´n. .a muestra la relaci´n de clientela entre A y B.1: Clientela y Herencia entre A y B Ejemplo 2. Definici´n 2. as´ como que pueda ser usada por el mayor n´mero de clientes ı u posible.b: class A: B { . par´metro. debe preocuparse de que dicha clase sea lo m´s reutilia zable.5 El siguiente c´digo muestra la relaci´n de clientela vista en la figura 2. mientras que en la 2. Relaciones entre clases: Cliente-Servidor y Herencia Un cliente de una clase debe ver a ´sta como un TAD. el siguiente c´digo muestra la relaci´n de herencia mostrada en la figura o o 2.1. .a: o o class A { . y eficiente.3 Una clase A se dice que hereda de otra clase B. // Atributo privado public string OutFile // Atributo p´ blico asociado u { get { return m_file_output .b se o observa la relaci´n de herencia entre dichas clases.

4 muestra un ejemplo de clases anidadas.c = c = e. x . return u . d.4 Una clase anidada no es m´s que una clase que se declara dentro de otra y o a que tiene visibilidad sobre todas las propiedades de los objetos de la clase que la incluye. pues en ´sta ultima se puede cambiar la implementaci´n de la clase que se emplea e ´ o en el cliente. } } C´digo 2. Visibilidad Adem´s de lo comentado en el apartado 2. } public class PruebaAnidada { public static void Main () { Dos x = new Dos () . o o Definici´n 2.6 El c´digo 2. Ejemplo 2. sin afectar a ´ste (en nuestro ejemplo. Console . Uno u = new Uno () . WriteLine (" IntAnidado (6) = " + IntAnidado (6) ) .1.1 Clases 9 Por ultimo cabe decir que la herencia es una decisi´n de dise˜o m´s comprometedora que ´ o n a la clientela. y = new Tres () .1.4: Ejemplo de Clases Anidadas o . 2. } public Tres y . } public class Dos { public int c . o El resultado mostrado por pantalla ser´ ıa: IntAnidado(6) = 17 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class Uno { public int c . u. se puede modificar la implementaci´n de e o B sin que esto afecte a A).c = 5 + e. public class Tres { public int IntAnidado ( int e ) { Dos d = new Dos () .2 acerca de la ocultaci´n de informaci´n. } private int c .4.2. c + c . en a o o esta secci´n trataremos la cuesti´n de las clases anidadas.

2.3). cada objeto se identifica un´ ıvocamente mediante su identificador de objeto (oid).5 Un objeto es una instancia de una clase.6. a Cuando un mensaje no especifica al objeto receptor la operaci´n se aplica sobre la instancia o actual. Por ejemplo.9) lo que se est´ queriendo decir es que se a aplique el m´todo SetPunto sobre el objeto receptor w. Descuento.7 En el mensaje w. a saber. a a o .10 Tema 2. Notaci´n punto o Como se ha podido observar en algunos de los ejemplos vistos hasta ahora. efectuando el correspondiente paso de e par´metros. Ejemplo 2. mientras que se dice que son compuestos si sus valores son subobjetos o referencias. Objetos Definici´n 2. Para especificar un paso de a par´metros “por referencia” se emplea la palabra clave ref delante del par´metro en cuesti´n. Dichos campos son simples si corresponden a atributos de tipos primitivos (v´ase tablas e 2. mientras que en los mensajes uno de esos argumentos. 2. recibe un “trato especial”. Mientras exista.2 y 2.1. creada en tiempo de ejecuci´n y o o formada por tantos campos como atributos tenga la clase. Sintaxis. patrones de dise˜o y GUI. n o n El estado de un objeto viene dado por la lista de pares atributo/valor de cada campo. Sem´ntica a La diferencia entre un mensaje y la invocaci´n a un procedimiento es que en ´ste ultimo o e ´ todos los argumentos reciben el mismo trato. .SetPunto(4. OO) o o existe un objeto destacado sobre el que se realiza alg´n tipo de operaci´n.3. Clases y Objetos 2.3. ´ 2.2. a • Procedentes del dise˜o/implementaci´n: TDA’s.1. siguiendo una sintaxis como la e que a continuaci´n se muestra: o receptor. el objeto receptor. o e Constan de tres partes: objeto receptor. Socio.. Comercial. o Producto. Objetos software: • Procedentes del an´lisis: objetos del dominio. el paso de par´metros es “por valor”.3. Para hacer referencia a la instancia actual en C# se emplea la palabra reservada this. la forma en que se invoca a un m´todo es mediante el operador punto.. Este objeto recibe u o el nombre de instancia actual. Si no se incluye nada. o En cada instante de la ejecuci´n de una aplicaci´n Orientada a Objetos (en adelante. 2. Su modificaci´n y consulta se realiza mediante mensajes.m´todo(argumentos) e 2. Una posible clasificaci´n de los objetos podr´ ser: o ıa Objetos externos: Son aquellos que existen en el dominio de la aplicaci´n. Mensajes Los mensajes son el mecanismo b´sico de la computaci´n OO y consisten en la invocaci´n a o o de la aplicaci´n de un m´todo sobre un objeto. identificador del m´todo y los argumentos de ´ste e e ultimo.3.

Los objetos son creados cuando son necesarios. o si se le asigna una referencia ya ligada).2: Variables en los lenguajes tradicionales Figura 2. e Toda referencia puede estar.4: Variables en los lenguajes OO Algunas ventajas de los tipos referencia son: Son m´s eficientes para manejar objetos. Dan soporte al polimorfismo.2.4. a Constituyen un soporte para definir estructuras de datos recursivas. como ya hemos visto. Estos constructores se encargan de inicializar los atributos con valores consistentes.22 ). Sin embargo tambi´n se pueden inicializar con unos valores por defecto. aunque tambi´n existen los tipos primitivos (figura 2. o 2. Creaci´n de objetos o En C# existe un mecanismo expl´ ıcito de creaci´n de objetos mediante la instrucci´n de o o creaci´n new y los llamados m´todos constructores (que deben tener el mismo nombre que la o e clase en la que se definen). 1 2 TE→Tiempo de Ejecuci´n o TC→Tiempo de Compilaci´n o .5. mediante los constructores e por defecto (aquellos que no tienen argumentos). o bien no ligada (con valor null). Se permite la compartici´n de un objeto. Sem´ntica referencia versus sem´ntica almacenamiento a a En C# se tiene sem´ntica referencia (figura 2.3: Variables tipo “puntero” en los lenguajes tradicionales Figura 2. Pero ojo. la asignaci´n o no implica copia de valores sino de referencias (⇒ Aliasing). o bien ligada a un objeto (mediante el operador new.41 ) para cualquier entidad asociada a una a clase.4 Sem´ntica referencia versus sem´ntica almacenamiento a a 11 2. Figura 2.

} { conta = value % 100.5 muestra un ejemplo de una clase con un constructor y un conso tructor por defecto.8 El c´digo 2.12 Tema 2. Cuando un objeto es recogido por el recolector de basura3 se llama impl´ ıcitamente a su destructor. 1 2 3 4 5 6 7 8 9 10 11 12 public class Contador { private int conta . } // Constructor por defecto Contador ( int i ) { conta = i % 100. Destructores Un destructor es un m´todo cuyo nombre es el nombre de la clase precedido de una tilde e ∼.6). Figura 2. } 2. pues ıa con el recolector de basura es suficiente para la finalizaci´n. No obstante.6: Ejemplo de copia profunda 3 garbage collector .5: Ejemplo de copia superficial Definici´n 2.5).7 Una copia se dice que es profunda si se crea un objeto con una estructura o id´ntica al objeto origen y sin compartici´n de referencias (figura 2. Clases y Objetos Ejemplo 2. Mientras que los constructores s´ pueden tener modificadores de acceso. } // Constructor int Conta { return conta . e o Figura 2.6. public public public { get set } public } C´digo 2.6 Una copia se dice que es superficial si se copian los valores de cada campo o del objeto origen en el objeto destino y ambos comparten referencias (figura 2. o 2.1. } void Click () { conta = ( conta + 1) % 100.5. Sem´ntica de la asignaci´n e igualdad entre objetos a o Definici´n 2. en la mayor´ de los casos las clases no necesitan destructores.5: Ejemplo de Constructores o Contador () { conta = 0. los destructores ı carecen de ellos.

m_mat [i .6 Sem´ntica de la asignaci´n e igualdad entre objetos a o 13 Como ya se dijo anteriormente. ++ j ) mat . m_col = ( col <= 0 ) ? 1 : col . a Si se tiene sem´ntica referencia y se realiza una copia superficial.9 Dos variables se dice que son iguales si ambas referencian a objetos con o valores iguales en sus campos (figuras 2. Definici´n 2. int col ) { m_row = ( row <= 0 ) ? 1 : row . lo cual puede llevarse a cabo.6 muestra un ejemplo de una clase que implementa el m´todo o e Clone() de la interfaz ICloneable para conseguir una copia profunda. return mat .6 es equivalente al o siguiente c´digo: o if (row <= 0) m_row = 1. j < m_col . } } C´digo 2. for ( int i = 0. } public object Clone () { matrix mat = new matrix ( m_row .Equals(ob) . e Ejemplo 2. ++ i ) for ( int j = 0.La l´ ınea 6 (equivalentemente la l´ ınea 7) del c´digo 2. por ejemplo. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class matrix : ICloneable { . public matrix ( int row . mientras que si se tiene sem´ntica almacenamiento entonces se a a copian los valores.7).8 Dos variables se dice que son id´nticas si ambas referencian al mismo objeto o e (figura 2. En C# esto se expresa de la siguiente forma: oa. la asignaci´n implica compartici´n de referencias si se o o tiene sem´ntica referencia.7: Ejemplo de variables id´nticas e Definici´n 2. m_col ]. j ]. m_mat = new double [ m_row .9 El c´digo 2.7). o Para evitar este efecto debemos realizar una copia profunda.. . En C# esto se expresa de la siguiente forma: oa == ob Figura 2. else m_row = row. los cambios hechos en a una variable tienen repercusi´n en su(s) correspondiente(s) copia(s). m_col ) .2. i < m_row . A este tipo de copia se le llama copia superficial y est´ soportada en C#. j ] = m_mat [i .6: Ejemplo de implementaci´n del m´todo Clone() o o e Nota. implementando el m´todo Clone() de la interfaz ICloneable.5 y 2. .

previous . } } public DListElement Data { get { return data . } . DListElement d ) { data = val .5). Imposibilidad de asegurar homogeneidad. 2. } public DListElement Next { get { return next . Previous = null . next = d . } set { previous = value . } public class DList { public DList () { head = null . mediante el empleo de la clase ra´ ız Object.8. u a C# consigue “genericidad” al estilo de Java. para implementar clases contenedoras gen´ricas. Dichas plantillas est´n propuestas para Java y C#. previous = this .7. private object data .7). } set { next = value . con los consabidos inconvenientes: Necesidad de conversiones expl´ ıcitas de tipo. pero no necesariamente a la inversa (figura 2. pero e a a´n est´n en una fase experimental. Clases y Objetos De esta ultima definici´n se deduce que siempre que haya identidad. 2. } } private DListElement next . Genericidad C++ hace uso de plantillas. } public DList ( object val ) { head = new DListElement ( val ) . Next = head . d . } set { data = value . head . que son altamente eficientes y muy potentes. } } public DListElement Previous { get { return previous . public class DListElement { public DListElement ( object val ) { data = val . tambi´n habr´ igual´ o e a dad superficial (figura 2. } public DListElement ( object val . a saber. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 Definici´n de una clase “Lista Doblemente Enlazada” o using System .14 Tema 2.

Next . Equals ( h . DListElement np = h . Next . } private DListElement Delete ( DListElement h ) { if ( h == null ) return null . } return h . return h . Previous .2.8 Definici´n de una clase “Lista Doblemente Enlazada” o 15 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 public bool IsEmpty () { return head == null . if ( np != null ) np . Previous = pp . } . Exception (" Empty DList ") . Next . head ) . Previous = null . else head = null . Previous = h . } public DListElement Find ( object val ) { DListElement h = head . if ( pp != null ) pp . Data . Data ) ) break . } else { DListElement h = new DListElement ( val . return head . head . Next = head . } public void Add ( object val ) { if ( IsEmpty () ) { head = new DListElement ( val ) . head . while ( h != null ) { if ( val . Next = np . head = h . pp = h . h = h . } } public object Front () { if ( IsEmpty () ) throw new System .

} private DListElement head . } public override string ToString () { return ToStr ingRec ursive ( head ) . respectivamente. respectivamente. Como ya se dijo anteriormente. distinta a la esperada. Es este un ejemplo de ocultaci´n de o informaci´n. El empleo del operador e == en esta l´ ınea provocar´ una ejecuci´n incorrecta.7: Lista gen´rica doblemente enlazada o e A continuaci´n destacaremos algunos aspectos de este c´digo: o o Obs´rvese el uso de get y set en las l´ e ıneas 13 a 20 (en m´todos declarados como p´blicos) e u y las declaraciones privadas de las l´ ıneas 22 y 23. Data + "\ n ") + ToStr ingRec ursive ( first . Como se observa en la l´ ınea 23 de este c´digo los datos almacenados en la lista son de o tipo object. as´ como la sobrecarga de constructores en las l´ ı ıneas 4 y 6. else return ( first . las cuales trataremos en el siguiente tema. y en la l´ ınea 90 vemos c´mo se sobrescribe el m´todo heredado ToString()4 . Next ) . o e 4 Todo lo relacionado con la herencia se ver´ en profundidad en el tema 4 a . } C´digo 2. Podemos ver la implementaci´n de un constructor por defecto y un constructor en las o l´ ıneas 28 y 29.16 Tema 2. } static string To String Recursive ( DListElement first ) { if ( first == null ) return "". as´ es como se consigue “genericidad” en ı C#. ıa o En la l´ ınea 55 se ve un ejemplo del uso de excepciones. o Otro ejemplo de ocultaci´n de informaci´n es la declaraci´n como privados de los m´too o o e dos Delete y ToStringRecursive de las l´ ıneas 72 y 93. En la l´ ınea 65 vemos un ejemplo de uso del m´todo Equals. Clases y Objetos 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public DListElement Delete ( object v ) { return Delete ( Find ( v ) ) .

1 En el c´digo 3. si el cliente cumple con las precondiciones. que se cumplen las postcondiciones. sin embargo permite al programador intentar recuperarse frente a estas situaciones y as´ continuar con la ejecuci´n del programa. con un mensaje de error. o ıan En C# la clase Debug contiene el m´todo Assert(). o Ejemplo 3. a Establecer una prueba formal completa de correcci´n del software es algo muy deseable. A estas condiciones se le conocen como o precondiciones. Contrato software Desde un punto de vista una excepci´n se puede decir que se basa en el incumplimiento o del contrato software entre el cliente y el servidor de una clase. la ejecuci´n proporciona una o o u o salida de diagn´stico. siempre que la entrada sea correcta. debe garantizar que. ı o 3. invocado de la siguiente manera: e Assert(expresi´n booleana. as´ como del empleo o ı de listeners para visualizar los mensajes de diagn´stico por pantalla.1.1 se muestra un ejemplo del uso de asertos. Las excepciones son habitualmente condiciones inesperadas de error que provocan la finalizaci´n del programa en el que o tienen lugar. De hecho. Los asertos se habilitan definiendo la variable o DEBUG. Para acceder a dicha salida de diagn´stico se emplean los listener. o 17 .mensaje). el usuario (cliente) debe garantizar que se cumplen las condiciones u necesarias para una correcta aplicaci´n del software. el software realizar´ la tarea deseada satisfactoriamente. Seg´n este modelo.Tema 3 Dise˜ o por Contrato: Asertos y n Excepciones En este tema se describe el manejo de excepciones en C#. o Si la expresi´n expresi´n booleana se eval´a como falsa. o pero por desgracia.2. por su parte. El proveedor (servidor). 3. Si esto es as´ se dice a ı. no se lleva a cabo en la mayor´ de las ocasiones. la discipliıa na consistente en plantear asertos apropiados frecuentemente consigue que el programador advierta y evite bastantes errores de programaci´n que antes podr´ pasar desapercibidos. Clases y Correcci´n del software: Asertos o La correcci´n de los programas se puede ver en parte como una prueba de que la ejecuci´n o o terminar´ proporcionando una salida correcta. C#. con el mensaje mensaje.

o El mecanismo de manejo de excepciones en C# es sensible al contexto. Y dicho contexto no es m´s que un bloque try. Listeners . Parse ( datos ) . Listeners . Debug . readLine () . string datos . o o 3. que es el objeto o la clase base de un a objeto lanzado por el sistema o por el usuario cuando ocurre un error en tiempo de ejecuci´n. .3. Ejemplo 3. public class AssertSqrRoot { public static void Main () { Debug . using System . Diagnostics . WriteLine ( x ) . Assert ( x > 0 . Dise˜ o por Contrato: Asertos y Excepciones n 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # define DEBUG using System . double x . WriteLine (" Introduzca un n´ mero real positivo :") . string datos . u datos = Console . Clear () . La excepci´n es entonces tratada por alguno de los manejadores que se encuentran al o final del bloque try. WriteLine (" La ra´ z cuadrada es " + Math . ı } } C´digo 3. Excepciones en C# C# contiene la clase est´ndar System. Console . en el cual se declaran los manejadores (handlers) al final del a mismo mediante la palabra clave catch. El inconveniente de los asertos es que no permiten una estrategia ıa a de reparaci´n o reintento para continuar con la ejecuci´n “normal” del programa. Add ( new T e x t W r i t e rT r ac eL i st e ne r ( Console . o 1 2 3 4 5 6 7 8 using System . Sqrt ( x ) ) . Console .18 Tema 3.1: Ejemplo del uso de asertos o El uso de asertos reemplaza el uso ad hoc de comprobaciones condicionales con una metodolog´ m´s uniforme. Un c´digo de C# puede alcanzar una excepci´n en un bloque try mediante la expresi´n o o o throw. con un bloque try. " Valor no positivo ") . Debug .Exception. public class LanzaExcepcion { public static void Main () { try { double x .2 muestra un ejemplo del uso de excepciones. o la expresi´n throw y los manejadores definidos mediante la palabra clave catch. x = double . Out ) ) .2 El c´digo 3. Console .

Console . WriteLine (" La ra´ z cuadrada es " ı + Math . mientras que en la tabla 3.2: Ejemplo del uso de excepciones o La tabla 3. datos = Console .2 a podemos observar las propiedades est´ndar que toda excepci´n debe tener. WriteLine ( x ) .1 muestra algunas excepciones est´ndar en C#. } o } } C´digo 3. WriteLine (" Lanzada excepci´ n " + e ) .2: Propiedades de las excepciones . WriteLine (" Introduzca un double :") . } catch ( Exception e ) { Console .1: Algunas Excepciones est´ndar a HelpLink InnerException Message StackTrace Source TargetSize Obtiene o establece un enlace a un fichero de ayuda Obtiene la instancia de Exception que caus´ la excepci´n o o Texto que describe el significado de la excepci´n o Traza de la pila cuando se llam´ a o la excepci´n o Aplicaci´n u objeto que gener´ la o o excepci´n o M´todo que lanz´ la excepci´n e o o Tabla 3. Exception () ) . if ( x > 0) throw ( new System . Sqrt ( x ) ) . Parse ( datos ) . a o SystemException ApplicationException ArgumentException ArgumentNullException ArgumentOutOfRangeException ArithmeticException DivideByZeroException IndexOutOfRangeException InvalidCastException IOException NullReferenceException OutOfMemoryException Clase base para las excepciones del sistema Clase base para que los usuarios proporcionen errores de aplicaci´n o Uno o m´s argumentos son inv´lidos a a Pasado null no permitido Fuera de los valores permitidos Valor infinito o no representable Auto-explicativa ´ Indice fuera de los l´ ımites del array Cast no permitido Clase base en el espacio de nombres System. else Console .IO para las excepciones de E/S Intento de referenciar a null Ejecuci´n fuera de la memoria heap o (mont´n) o Tabla 3. readLine () .3 Excepciones en C# 19 9 10 11 12 13 14 15 16 17 18 19 20 21 Console . x = double .3.

} catch ( Exception e ) { Console . WriteLine (" Excepci´ n recapturada " + e ) . } o } } C´digo 3. . o 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 using System . WriteLine (" Primera captura " + e ) . o Ejemplo 3. . el usuario probablemente querr´ informaci´n adicional por pantalla para a o seleccionar o ayudarle a decidir la acci´n a realizar por el manejador. En este caso ser´ o ıa apropiado “empaquetar” la informaci´n en un objeto derivado de una clase Exception ya o existente. Sin embargo. Por ejemplo. Console . .20 Tema 3. . las cuales deben ser objetos de la o clase Exception. } catch ( Exception e ) { . . public class ReLanzaExcepcion { public static void LanzaMsg () { try { . . Lanzamiento de excepciones Mediante la expresi´n throw se lanzan excepciones. pero con frecuencia ´stos no precisa de dicha informaci´n.3 muestra un ejemplo del relanzamiento de excepciones. .3: Ejemplo del relanzamiento de excepciones o Conceptualmente. throw new Exception (" Lanzada en LanzaMsg ") . LanzaMsg () . . throw . El bloque try m´s interno en el que se lanza una excepci´n es empleado a o para seleccionar la sentencia catch que procesar´ dicha excepci´n. Dise˜ o por Contrato: Asertos y Excepciones n 3. . . a o Si lo que queremos es relanzar la excepci´n actual podemos emplear un throw sin arguo mentos en el cuerpo de un catch. un manejador e o que simplemente imprime un mensaje y aborta la ejecuci´n no necesita m´s informaci´n de o a o su entorno. el lanzamiento de una excepci´n pasa cierta informaci´n a los manejao o dores. . . // Relanzamiento } } public static void Main () { try { .3 El c´digo 3. .3. Esta situaci´n puede ser util si deseamos que un segundo o ´ manejador llamado desde el primero realice un procesamiento m´s exhaustivo de la excepci´n a o en cuesti´n.1.

} catch ( StackError se ) { Console . o Una excepci´n puede ser tratada por una manejador en concreto si se cumplen alguna de o estas condiciones: 1. stk . Si la excepci´n lanzada ha sido derivada de la clase base del manejador.3. } get { return msg . TopEntry () ) . 2. ." Out of bounds ") . o Es un error listar los manejadores en un orden en el que se impida la ejecuci´n de alguno o de ellos. } public class StackErrorTest { public static void Main () { Stack stk = new Stack . } public class StackError : Exception { public StackError ( Stack s . }} private Stack st . como muestra el siguiente ejemplo. Msg + " with last char " + se . El orden en el que se definen los manejadores determina el orden en el que se intenta invocar cada manejador que puede tratar la excepci´n que haya saltado. private string msg . s [99].4 muestra un ejemplo del uso de objetos para empaquetar inforo maci´n que se pasa a los manejadores de excepciones. try { throw new StackError ( stk .4 El c´digo 3.3. } public char TopEntry () { return st . public class Stack { public char [] s = new char [100]. WriteLine ( se . s [99] = ’z ’. } public string Msg { set { msg = value .3 Excepciones en C# 21 Ejemplo 3. string message ) { st = s .4: Uso de excepciones con m´s informaci´n o a o 3. o El resultado mostrado por pantalla ser´ algo como: ıa Out of bounds with last char z 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 using System .2. Bloques try Un bloque try es el contexto para decidir qu´ manejador invocar para cada excepci´n e o que se dispara. msg = message . Si hay una coincidencia exacta. } } } C´digo 3.

public class ExAssert { public static void MyAssert ( bool cond . Exception e ) { if (! cond ) { Console . adem´s de imprimir m´s informaci´n. pues antes se encontrar´ una coincidencia ıa ıa con el primer catch. seg´n lo dicho en las condiciones anteriores.4. como ya hemos visto anteriormente. mientras que con las excepciones. ı Cuando se invoca a un manejador a trav´s de una expresi´n throw. o Los asertos simplemente imprimen un mensaje por pantalla. string datos . pero ahora mediante excepciones.6 El c´digo 3. . o Ejemplo 3.1 que se muestra en el ejemplo o o 3.5 es una reescritura del c´digo 3. u 3. Console . WriteLine (" Introduzca un double positivo :") . string message . En este ejemplo se ve c´mo el programa hace uso del mecanismo de excepciones para o llamarse a s´ mismo recursivamente hasta que el usuario introduzca un n´mero v´lido para ı u a la entrada.3. Error . el cual maneja las excepciones no u tratadas por los manejadores que s´ tienen argumento. La palabra clave finally despu´s de un bloque try introduce otro bloque que se ejecuta e despu´s del bloque try independientemente de si se ha lanzado una excepci´n o no. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 using System . throw e .5 Seg´n el siguiente c´digo: u o catch(ErrorClaseBase e) catch(ErrorClaseDerivada e) nunca se ejecutar´ el cuerpo del segundo catch. Dise˜ o por Contrato: Asertos y Excepciones n Ejemplo 3.3. se puede decidir (en algunos casos) entre a a o continuar la ejecuci´n del programa o abortarla de inmediato. Manejadores La sentencia catch parece la declaraci´n de un m´todo con un solo argumento y sin valor o e de retorno. Conversi´n de asertos en excepciones o La l´gica de las excepciones es m´s din´mica ya que los manejadores pueden recibir m´s o a a a informaci´n que los asertos. } } } class ExceptionSqrRoot { public static void ConsoleSqrt () { double x .22 Tema 3. e o 3. WriteLine ( message ) .1 del uso de asertos. nos salimos del bloque e o try y autom´ticamente se llama a los m´todos (incluidos los destructores) que liberan la a e memoria ocupada por todos los objetos locales al bloque try. Incluso existe un catch sin ning´n argumento.

WriteLine ( x ) . Parse ( datos ) . WriteLine (" La ra´ z cuadrada es " + Math . // Se vuelve a intentar } } public static void Main () { Console . WriteLine ( e ) . ToString () .5: Ejemplo del uso de excepciones en vez de asertos o . ConsoleSqrt () . } } C´digo 3. readLine () . MyAssert ( x > 0 . } catch ( Exception e ) { Console .3. Console . " Valor no positivo : x = " + x . x = double . ExceptionSqrRoot . Console . new Exception () ) . ı ConsoleSqrt () . WriteLine (" Probando Ra´ ces Cuadradas ") .4 Conversi´n de asertos en excepciones o 23 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 datos = Console . Sqrt ( x ı )). try { ExAssert .

Dise˜ o por Contrato: Asertos y Excepciones n .24 Tema 3.

as´ como los privilegios de acceso. Una clase derivada hereda la deso cripci´n de la clase base. n e B puede redefinir m´todos de A (bien para extender el m´todo original. bien para e e mejorar la implementaci´n). consistente o o en derivar una nueva clase a partir de una ya existente. la cual se puede alterar a˜adiendo nuevos miembros y/o modificando o n los m´todos existentes.1 En la figura 4. ıa o En muchas ocasiones distintas clases resultan ser variantes unas de otras y es bastante tedioso tener que escribir el mismo c´digo para cada una. e ı Ejemplo 4. A trav´s de la herencia es posible e crear una jerarqu´ de clases relacionadas que compartan c´digo y/o interfaces. o B puede implementar un m´todo diferido en A. pero puede incluir adaptaciones: e B puede a˜adir nuevos atributos. n B puede a˜adir nuevos m´todos. Introducci´n o La herencia es un potente mecanismo para conseguir reutilizaci´n en el c´digo.Tema 4 Herencia 4. e 25 .1 Si B hereda de A entonces B incorpora la estructura (atributos) y comporo tamiento (m´todos) de A. ıa Figura 4.1.1 se muestra un ejemplo de una jerarqu´ de clases.1: Jerarqu´ de clases ıa Definici´n 4.

Sin o embargo.2. object b) string ToString() Devuelve true si dos objetos son equivalentes.3.3. lo cual quiere decir que sus entidades (las cuales poseen un unico tipo est´tico y un conjunto de tipos din´micos) pueden estar conectadas a una instancia ´ a a de la clase asociada en su declaraci´n o de cualquiera de sus subclases. un mecanismo de especialio zaci´n y un mecanismo de implementaci´n.2.2: Herencia de especializaci´n y de implementaci´n o o 4.b sirve como mecanismo de especializaci´n. o a Ejemplo 4. a la vez. si no.2 La herencia entre clases que se observa en la figura 4. los ejemplos de las figuras 4. puede ocurrir que el motivo por el cual B hereda de A sea la necesidad de construir una implementaci´n “distinta” (si se quiere.26 Tema 4. o Figura 4. Doble aspecto de la herencia Como ya se dijo en la definici´n 2. as´ como en las figuras ı 4.d muestran la herencia como mecanismo de implementaci´n. o C# soporta el polimorfismo.2 Podr´ o ıamos definir el polimorfismo como la capacidad que tiene una entidad para referenciar en tiempo de ejecuci´n a instancias de diferentes clases. o Podr´ ıamos categorizar el polimorfismo en dos tipos: Param´trico e Real y Aparente → Sobrecarga Inclusi´n (basado en la herencia) o .1.2.2. una clase B puede heredar de otra clase A.c y 4. Herencia La tabla 4. por ser B una especializaci´n de A. la herencia es. ıa bool Equals(object o) void Finalize() int GetHashCode() Type GetType() object MemberwiseClone() bool ReferenceEquals (object a. devuelve false Equivalente a escribir un destructor Proporciona un entero unico para ´ cada objeto Permite averiguar din´micamente el a tipo de objeto Permite clonar un objeto Devuelve true si los objetos son la misma instancia Devuelve un string que representa al objeto actual Tabla 4. Polimorfismo Definici´n 4.1: Propiedades de las excepciones 4.2.a y 4. ra´ en toda e u ız jerarqu´ de clases de C#. o Por otra parte. m´s refinada) de A.1 muestra los m´todos p´blicos y protegidos de la clase object. o o Esto es.

si a y b son de tipo o o string.1. todo ello depenu diendo del tipo de datos de a y b. Uno de los ejemplos m´s claros es e a el del operador ‘+’.4. + − ! ∼ ++ −− true f alse Tabla 4. Rectangulo r. en el caso de los operadores relacionales <. C# soporta la sobrecarga de m´todos y de operadores. en punto flotante o de n´meros complejos. r = p. N´tese que el operador de asignaci´n no puede o o sobrecargarse y que los operadores sobrecargados mantienen la precedencia y asociatividad de los operandos. Cuadrado} te(c) = Cuadrado ctd(c) = {Cuadrado} donde “te” significa “tipo est´tico” y “ctd” significa “conjunto de tipos din´micos”. Rectangulo.3 La sobrecarga consiste en dar distintos significados a un mismo m´todo u o e operador.3 hace lo propio con los operadores binarios. Sin embargo. a a Y por lo tanto las siguientes asignaciones ser´ v´lidas: ıan a p = t. Pero no lo ser´ ıan. Cuadrado} te(t) = Triangulo ctd(t) = {Triangulo} te(r) = Rectangulo ctd(r) = {Rectangulo. p = c. por ejemplo: 4. Triangulo t. mientras que la tabla 4.3. e a . tambi´n es sobrecargado impl´ e ıcitamente. <= y >=). c = p.2 muestra los operadores unarios que en C# se pueden sobrecargar. Cuadrado c. si cabe. t = r. Tanto los operadores binarios como los unarios s´lo pueden ser sobrecargados mediante o m´todos est´ticos. Sobrecarga Definici´n 4.3 Polimorfismo 27 Ejemplo 4. c = t. su operador de asignaci´n asociado. p = r. lo realmente interesante es poder redefinir operadores cuyos operandos sean de tipos definidos por el usuario.3: Operadores binarios “sobrecargables” Cuando se sobrecarga un operador tal como ‘+’. siguiendo la jerarqu´ de clases de la figura 4. Pero conviene tener en cuenta que este tipo de actuaci´n s´lo es provechosa en aquellos o o casos en los que existe una notaci´n ampliamente usada que conforme con nuestra sobrecarga o (m´s a´n.1. o ‘+=’.2: Operadores unarios “sobrecargables” + − ∗ / % & | ∧ << >> == ! = < > >= <= Tabla 4. a u La tabla 4. y C# permite hacer esto.4 La expresi´n a + b puede significar desde concatenaci´n.3 Dada la siguiente declaraci´n. r = c. podemos decir que: te(p) = Poligono ctd(p) = {Poligono. hasta una suma entera. Triangulo. Ejemplo 4. o ıa Poligono p. >.

days . mins = 0 . days = i / 86400. } public void Reset ( unit i ) { totSecs = i . hours .1 muestra un ejemplo de sobrecarga de operadores. } public override string ToString () { Reset ( totSecs ) . mins = ( i / 60) % 60. Tick () . Herencia Ejemplo 4. totSecs ) . } public static MyClock operator +( MyClock c1 . pero con los par´metros en orden inverso. MyClock c2 ) { return new MyClock ( c1 . secs = 0 .5 El c´digo 4. uint m ) { return ( m * c ) . totSecs ) . hours = 0 . totSecs + c2 . El resultado mostrado por pantalla tras ejecutarse el m´todo Main() ser´ e ıa: Initial times day 00 time:00:00:59 day 01 time:23:59:59 One second later day 00 time:00:01:00 day 02 time 00:00:00 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 using System . secs = i % 60. } public static MyClock operator *( uint m . Esta pr´ctica com´n a a u evita que el operador sobrecargado tenga un orden prefijado en sus operandos. days = 0. } public static MyClock operator ++( MyClock c ) { c . class MyClock { public MyClock () { } public MyClock ( unit i ) { Reset ( i ) . } . secs ) . Obs´rvese como en la l´ e ınea 32 se vuelve a definir el operador ‘*’. } private uint totSecs = 0 . return c . mins . MyClock c ) { return new MyClock ( m * c . previamente sobrecargado por el m´todo de la l´ e ınea 29. } public static MyClock operator *( MyClock c . hours = ( i / 3600) % 24. } public void Tick () { Reset (++ totSecs ) .28 Tema 4. o como binarios. return String . tanto unarios. Format (" day {0: D2 } time :{1: D2 }:{2: D2 }:{3: D2 }" .

. WriteLine (" One second later \ n " + a + ’\n ’ + b ) .3. supuesta la declaraci´n X x. Definici´n 4. siguiendo el ejemplo de jerarqu´ de clases de la figura 4. 2.4. X incluye una propiedad con nombre final r... Y r est´ disponible para la clase que incluye el mensaje.3.3. o a 1 2 En adelante.T x. b = new MyClock (172799) . en un ıa instante dado podr´ ıamos tener una lista como la que se observa en la figura 4. si la conversi´n no est´ permitida. } } C´digo 4.).3: Ejemplo de estructura de datos polimorfa 4. Estructuras de datos polim´rficas o La lista doblemente enlazada implementada en el c´digo 2. devuelve true si se puede hacer un o “cast” de la expresi´n expresi´n al tipo tipo. WriteLine (" Initial times \ n " + a + ’\n ’ + b ) . Definici´n 4. Console ... Los argumentos son compatibles con los par´metros y coinciden en n´mero. ser´ legal o o a si el tipo de y es compatible con el tipo de x.3. RVM . RA En adelante. ser´ legal si: o a 1.) a una rutina r(. con id´ntica sintaxis devuelve la expresi´n expresi´n convertida al tipo e o o tipo...4 Un tipo T1 es compatible con otro tipo T2..y.6 Regla de Validez de un Mensaje 2 o Un mensaje ox.4.r(y). o bien. o o El operador as.7 es un claro ejemplo de eso tructura de datos polimorfa. si la clase de T1 es la misma o que la de T2 o una subclase de T2. Regla de aplicaci´n de propiedades o Definici´n 4. ++ a . a u 3.1: Ejemplo de Sobrecarga de Operadores o 4. ++ b . Console . Si en la l´ ınea 23 de dicho c´digo en vez de poner private object data escribi´ramos o e private Figura data.2.3 Polimorfismo 29 37 38 39 40 41 42 43 44 45 class MyClockTest { public static void Main () { MyClock a = new MyClock (59) . Operadores is y as El operador is. devuelve null. a 4. Figura 4.1.5 Regla de la Asignaci´n 1 o o Una asignaci´n x = y o una invocaci´n r(.3. cuya sintaxis es expresi´n is tipo.

f → α oa = od. D od = new D(). Ligadura Din´mica a Como ya dijimos en la definici´n 4. Herencia 4. por contra. e N´tese la diferencia entre un m´todo redefinido y un m´todo sobrecargado. la versi´n del m´todo que se ejecute depender´ del tipo din´mico del o e a a objeto de la clase A. Los m´todos o e e e sobrecargados son seleccionados en tiempo de compilaci´n bas´ndonos en sus prototipos o a (argumentos y valor de retorno) y pueden tener distintos valores de retorno.1. En esto consiste la ligadura din´mica. oa.2 muestra un ejemplo de redefinici´n de un m´todo heredado de la o o e clase base. como en C++. din´mico del objeto oa: a oa = ob. B puede o redefinir m´todos de A e implementar m´todos que en A sean diferidos.4: Herencia y redefinici´n de m´todos o e Dadas las siguientes declaraciones: A oa. Las letras griegas representan la versi´n de cada e o m´todo.30 Tema 4.f → β oa = oc.f → δ En C#. e Figura 4. as´ como de la palabra clave ı override en la l´ ınea 9.6 En la figura 4. C oc = new C().4 se muestra una jerarqu´ de clases en las que algunas de ellas ıa redefinen el m´todo f de sus ancestras. oa. A continuaci´n se muestra qu´ versi´n del m´todo f se ejecutar´ dependiendo del tipo o e o e ıa. Obs´rvese tambi´n como el valor devuelto por el m´todo redefinido e e e de la l´ ınea 9 es el mismo que el del m´todo original de la l´ e ınea 4. es seleccionado en tiempo de ejecuci´n bas´ndonos en e o a el tipo din´mico del objeto receptor y no puede tener distinto valor de retorno del que tenga a el m´todo al que redefine. siendo necesario incluir la a palabra clave virtual en aquellos m´todos que vayan a ser redefinidos y a los cuales s´ se e ı aplicar´ ligadura din´mica. a Ejemplo 4. B ob = new B(). oa. Un m´todo redefinido. void.7 El c´digo 4. Obs´rvese el uso de la palabra clave virtual en la l´ e ınea 4. a saber. El resultado mostrado por pantalla tras ejecutarse el m´todo Main() ser´ e ıa: Dentro de la clase base Dentro de la clase derivada Dentro de la clase derivada . a a Aquellas subclases que quieran redefinir un m´todo declarado como virtual en la clase e base deber´n emplear para ello la palabra clave override.4. como ya hemos visto en varios a ejemplos con el m´todo ToString(). si una clase B hereda de otra clase A. e Ejemplo 4. la ligadura es est´tica por defecto. e e Entonces cuando tengamos un objeto de la clase A y una invocaci´n a un m´todo redeo e finido en la clase B.

Si una clase hereda de otra clase abstracta y no implementa todos sus m´todos abstractos. Para ser m´s preciso. Ejemplo 4. Status () . o Sin embargo el m´todo abstracto Perimetro() es implementado en las tres subclases. y e para implementarlo en alguna subclase utilizamos la palabra clave override. o e esto es. abstract class Figura { abstract public double Area () . Es por ello que la subclase Triangulo sigue siendo abstracta. } .5 Clases Diferidas 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System . Para declarar en C# un m´todo como abstracto se emplea la palabra clave abstract. WriteLine (" Dentro de la clase base ") .7 Una clase diferida o abstracta es aquella que contiene m´todos abstractos. es a parcialmente abstracta (ver definici´n 4.8). Status () . m´todos que deben ser implementados en las subclases. b = d. pero no en la subclase Triangulo.8 El c´digo 4. } } class ClaseDerivada : ClaseBase { public override void Status () { Console . No se pueden crear instancias e de una clase abstracta. abstract public double Perimetro () .5.2: Redifinici´n de un m´todo heredado o o e 4. Status () . ClaseDerivada d = new ClaseDerivada () . WriteLine (" Dentro de la clase derivada ") . class ClaseBase { public virtual void Status () { Console . } } class L i g a d u r a D i n a m i c a T e s t { public static void Main () { ClaseBase b = new ClaseBase () . } } C´digo 4.4.3 muestra un ejemplo de una clase abstracta Figura. b . b . d . e entonces sigue siendo abstracta. Clases Diferidas Definici´n 4. cuyo m´todo o e abstracto Area() es implementado en las subclases Rectangulo y Circulo. e 1 2 3 4 5 6 using System .

} public override double Area () { return ( base * altura ) . deben e a ser p´blicos. } private double radio . Por lo tanto las palabras clave abstract y public se pueden omitir. lado3 .1.32 Tema 4. } private double altura . s´lo m´todos.5. o e 3 Lo veremos en profundidad m´s adelante a . mientras que en C# a o ´ est´ permitida la herencia m´ltiple de interfaces3 . no puede contener miembros de datos. } public override double Perimetro () { return ( lado1 + lado2 + lado3 ) . } public override double Perimetro () { return ( Math . o Una interface puede heredar de otra interface. sin embargo. Para referenciar al constructor de la clase base a˜adimos al final del constructor de la n clase derivada lo siguiente: : base(argumentos). base . base = b . PI * radio * 2) .8 Una clase parcialmente abstracta es aquella que contiene m´todos abstractos o e y efectivos.9 Una clase que unicamente contiene m´todos abstractos recibe el nombre de o ´ e interface. no es lo mismo que una clase abstracta. pues una clase abstracta puede estar parcialmente implementada. double b ) { altura = a . lado2 . } private double lado1 . } public override double Area () { return ( Math . adem´s de ser abstractos como ya hemos dicho. lado3 = l3 . } C´digo 4. double l2 . El constructor de la clase base es invocado antes de ejecutar el constructor de la clase derivada. } abstract class Triangulo : Figura { public Triangulo ( double l1 . y para implementar una interface se emplea la notaci´n vista hasta ahora para la herencia. } public override double Perimetro () { return (( base * 2) + ( altura * 2) ) . Adem´s una clase s´lo puede heredar de una unica clase abstracta. a u Todos los m´todos de una interface. lado2 = l2 .3: Clase abstracta Figura o Definici´n 4. Pero no confundamos. double l3 ) { lado1 = l1 . 4. Interfaces Definici´n 4. PI * radio * radio ) . } class Circulo : Figura { public Circulo ( double r ) { radio = r . u Para declarar una interface se emplea la palabra clave interface. Herencia 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Rectangulo : Figura { public Rectangulo ( double a .

set . } set { telefono = value . } int A~ oMatricula { get . } string Nss { get . } set { notaMedia = value . Las tres son implementadas por la clase Ayudante. set . } } public int Edad { get { return edad . } // M´ todos y propiedades requeridos por IEstudiante e public double NotaMedia { get { return notaMedia . a diferencia de las clases. } string Telefono { get . } set { name = value . set .5 muestra el esquema de herencia e implementaci´n de las interfaces y la clase o en cuesti´n. set . set . } bool esMayorDeEdad () . set . } set { a~ oMatricula = value . } } public string Telefono { get { return telefono .5 Clases Diferidas 33 Ejemplo 4. de la cual o heredan otras dos interfaces IEstudiante e IProfesor. } interface IEstudiante : IPersona { double NotaMedia { get . } // N o seguridad social } class Ayudante : IPersona .4 se muestra un ejemplo de una interface IPersona. Obs´rvese el convenio de nombrar a las interfaces con una ‘I’ may´scula delante del e u nombre. que no la llevan. IEstudiante . o Figura 4. set . } } public int A~ oMatricula n { get { return a~ oMatricula . } } public bool esMayorDeEdad () { return ( edad >= 18) . } set { edad = value .4.9 En el c´digo 4.5: Herencia e implementaci´n de interfaces o 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 interface IPersona { string Nombre { get . IProfesor { // M´ todos y propiedades requeridos por IPersona e public string Name { get { return name . } int Edad { get . n n } } . } n } interface IProfesor : IPersona { double Salario { get . La figura 4.

4. string numSec ) { nombre = nom . notaMedia . } set { salario = value . } // Otras implementaciones de constructores y m´ todos e . a~ oMatricula ) . } } public string Nss { get { return nss . .4: Herencia M´ltiple mediante interfaces o u string nombre . string nss .9} Edad : {2 . notaMedia = nm . o 2. Format (" Nombre : {0: -20} Tel´ fono : {1 . double nm .6. n } private private private private private private private } C´digo 4. salario . } set { nss = value . double sal . edad = ed . int am . nss . } } // Constructores para Ayudante public Ayudante ( string nom . n o nombre . nss = numSec . int a~ oMatricula . n double salario . public override ToString () { return String .. Conseguida gracias a la ligadura din´mio a ca y el polimorfismo. n salario = sal . Conseguida gracias a la ligadura din´mica y el o a polimorfismo. Conseguida gracias a la genericidad. Herencia 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 // M´ todos y propiedades requeridos por IProfesor e public double Salario { get { return salario . a~ oMatricula = am . reutilizaci´n y extensibilidad del software o A continuaci´n enumeramos cu´les son los requerimientos que debe cumplir un m´dulo o a o para facilitar la reutilizaci´n: o 1. 3.2}" + e "\ nSeguridad Social : {3} Salario : {4: C }" + "\ nNota media : {5} A~ o de matriculaci´ n : {6}" . Variaci´n en tipos. int edad . double notaMedia .. string telefono . edad . telefono = tlf . telefono . Herencia. string tlf . int ed . Variaci´n en estructuras de datos y algoritmos. Independencia de la representaci´n.34 Tema 4.

la segunda la 1. Captura de similitudes entre un un subgrupo de un conjunto de posibles implementaciones.).4... . la creaci´n o o o de componentes reutilizables.. } } private class A r r a y I m p a r E n umerator : IEnumerator { public A r r a y I m p a r E n u m e r ator ( ArrayImpar a ) . Conseguida mediante la construcci´n de clases. Conseguida gracias a la herencia. todos e ı e ellos de la interface IEnumerator. } public int this [ int i ] { get { return a [ i ]. Agrupaci´n de rutinas relacionadas.6 Herencia. 5. Noo u sotros trataremos ahora brevemente el contenido de System. Para construir un iterador necesitamos alguna manera de avanzar el iterador. as´ como el m´todo de acceso Current. La implementaci´n de la interface IEnumerate por parte de una clase contenedora dota o a ´sta de la posibilidad de emplear la instrucci´n foreach.10 El c´digo 4. o En C# existe una gran colecci´n (a´n en crecimiento) de elementos reutilizables. using System . Ejemplo 4. para realizar una implementaci´n concreta deben implementarse (valga la reo dundancia) los m´todos MoveNext() y Reset(). o o Existen dos aspectos importantes en la reutilizaci´n de c´digo: por una parte.. Obs´rvese que este valor no puede ser modificado.IEnumerable. o El resultado mostrado por pantalla ser´ ıa: 1 3 5 7 9 11 13 15 17 19 Iterando. la utilizaci´n de dichos componentes. Collections . de modo que se podr´ emplear la instrucci´n foreach con objetos de dicha a o clase (como puede observarse en la l´ ınea ). } set { a [ i ] = value . devolver el siguiente valor en la colecci´n y comprobar en cada instante si ya hemos iterado sobre todos o los elementos de la colecci´n. s´lo e o puede consultarse. e No obstante. o Para ello la interface IEnumerable declara el m´todo IEnumerator GetEnumerator(). class ArrayImpar : IEnumerable { public int [] a = new int [10].Collections y la interface Collections. public IEnumerator GetEnumerator () { return ( IEnumerator ) new ArrayImparEnumerator ( this ) . reutilizaci´n y extensibilidad del software o 35 4. cuya sintaxis es: e o foreach (Tipo nombreVariable in nombreArray) Mediante la instrucci´n foreach tenemos en cada iteraci´n en la variable nombreVariable o o el contenido de la clase contenedora.5 muestra un ejemplo de una clase que implementa la interface o IEnumerable. 3 7 11 15 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 using System . y por otra parte. Se trata de un array de 10 enteros cuyo iterador s´lo indexa los elementos que ocupan o posiciones impares (teniendo en cuenta que la primera posici´n es la 0.

Una a o a propiedad con este modificador de acceso s´lo puede ser accedida desde c´digo perteneciente o o al mismo ensamblado en el que se haya definido dicha propiedad. private ArrayImpar a . llamadas selladas. foreach ( int elemento in ai ) Console . Este tipo de ı clases. Write ( elemento + " ") . . } publoc object Current { get { return a [ indice ]. i < 10. } class ArrayImparTest { public static void Main () { ArrayImpar ai = new ArrayImpar () . todas sus subclases que hayan actuado de la manera anteriormente indicada se ver´n afectadas y a probablemente tambi´n deber´n modificar su implementaci´n. a [ i ] = 2 * i + 1. que est´ permitida en C++. pues puede ocurrir que una subclase apoye algunos de sus m´todos en la implementaci´n concreta e o conocida de la clase base.36 Tema 4. WriteLine ("\ nIterando . ´ Este es un factor negativo para la extensibilidad. pueden ser tratadas de una forma m´s eficiente por parte del compia lador. i ++) { ai . pues si modificamos la clase base. Sin embargo. a = a . Console . ya que sus m´todos no pueden ser redefinidos y por tanto se declaran autom´ticamente e a como no virtuales. } public bool MoveNext () { indice += 2. } Console . } } C´digo 4. Write ( ai . } public void Reset () { indice = -1.. Herencia 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 { this . } } private int indice .") . indice = -1. return ( indice <= 9) . La herencia privada. a s´ se puede inhabilitar la herencia de una clase mediante la palabra clave sealed.. e a o Adem´s de los tres tipos de acceso vistos en la secci´n 2.1. no es soportada en C#. a [ i ] + " ") . for ( int i = 0.2 existe otro m´s: internal.5: Implementaci´n de un iterador o o Tratando ahora la cuesti´n referente a la ocultaci´n de informaci´n en los casos en los o o o que existe herencia diremos que en tales situaciones se viola el principio de caja negra.

(a) muestra un ejemplo de herencia simple. u (a) (b) Figura 4.(b) hace lo propio con la herencia m´ltiple. ıa e A continuaci´n explicaremos dos de ellos: la colisi´n de nombres y la herencia repetida o o (aunque ´sta ultima.4 as´ como en la figura 4. tambi´n implica algunos inconvenientes.7: Herencia m´ltiple y colisi´n de nombres u o La herencia repetida se da cuando una misma propiedad es heredada por distintos caminos m´s de una vez.6: Herencia simple y m´ltiple u En C#.12 En el c´digo 4. u 4. a diferencia de C++.5 se muestra un claro ejemplo de o ı herencia m´ltiple de interfaces.7 Herencia m´ ltiple u 37 4. e o Ejemplo 4. no est´ permitida la herencia m´ltiple de clases.10 Se dice que existe herencia m´ltiple de clases (tambi´n puede ser de intero u e faces) cuando una clase hereda directamente de m´s de una clase. no se da en C#). Problemas: Colisi´n de nombres y herencia repetida o Aunque la herencia m´ltiple nos ofrece varias ventajas a la hora de programar seg´n la u u metodolog´ OO. al igual que en Java. este hecho se solventa mediante la herencia m´ltiple de interfaces u y simple de clases.13 En la figura 4. como veremos m´s adelante.7. Herencia m´ ltiple u Definici´n 4. mientras que la figura 4. a Ejemplo 4. Ejemplo 4. e ´ a La colisi´n de nombres tiene lugar cuando una clase hereda de dos o m´s clases un o a m´todo con el mismo nombre y diferente implementaci´n.11 La figura 4. a .4. u Figura 4.6.7.7 se muestra un ejemplo de colisi´n de nombres debida a la o herencia m´ltiple. Sin ema u bargo.1.6.

tambi´n podemos a e implementar un m´todo f() en C para el caso en el que se manipulen directamente objetos e de dicha clase. f ( object o ) { ..6 se muestra un ejemplo en el que una clase C hereda de dos o interfaces distintas A y B un m´todo con el mismo nombre f(object o).8 se muestra un ejemplo de herencia repetida debida a la herencia m´ltiple.6: Ambig¨edad de nombres debida a la herencia m´ltiple o u u Podemos resolver la potencial ambig¨edad de nombres dentro de la clase C incluyendo u declaraciones expl´ ıcitas para cada instancia de interface heredada.15 En el c´digo 4. si difieren en la signatura y/o en el valor de retorno.7. } class C : A . no hay herencia repetida.7. u En C#. f ( object o ) { . si tienen la misma signatura y valor de retorno. Ejemplos de utilidad Ejemplo 4. f () o B .. Estos cambios pueden observarse en el c´digo 4. como ya hemos dicho. En este caso existen dos posibilidades: 1. 2.7: Soluci´n a la ambig¨edad de nombres o o u .. } interface B { void f ( object o ) . o 1 2 3 4 5 class C : public public public } A.. resultando en una e ambig¨edad de nombres.38 Tema 4.. } C´digo 4. B { // A .2. Sobrecarga. B void void void { f ( string s ) { .14 En la figura 4. o 4. f () ?? public void g () { f () . u 1 2 3 4 5 6 7 8 9 10 11 12 interface A { void f ( object o ) . } B . Es m´s. } A ..8: Herencia m´ltiple y herencia repetida u Ejemplo 4. Herencia Figura 4. Compartici´n. pero s´ puede darse colisi´n de ı o nombres en el caso en el que una interface hereda de dos o m´s interfaces un m´todo con el a e mismo nombre. } } C´digo 4.

se puede solucionar f´cilmente. al igual que en el ejemplo anterior esto no es as´ u ı.15. Las letras enmarcadas representan ıa interfaces y las no enmarcadas.4.8. ´ e 4. clases. En esta circunstancia podr´ ıamos pensar que se dar´ un caso de herencia repetida. No obstante s´ deber´ implementar aquellos m´todos de la ı a e interface Y que no est´n en la interface W. Figura 4.17 Sea ahora la jerarqu´ mostrada en la figura 4.10: Herencia m´ltiple sin herencia repetida (II) u Si bien es cierto que la clase Z hereda los m´todos de la interface W por dos v´ no resulta e ıas. Normalmente el recolector de basura (garbage collector ) se encarga autom´ticamente de los objetos que ya no son necesarios (por ejemplo. Figura 4. Pero. Java y C++: Estudio comparativo Adem´s de las continuas referencias que durante todo el texto se han hecho hacia otros a lenguajes OO como Java y C++. pero ıa no es as´ ı. C#.9: Herencia m´ltiple sin herencia repetida (I) u La clase Z no necesita implementar los m´todos de la interface W. a Otra soluci´n distinta a la expuesta en el ejemplo 4.10.15 pero igualmente v´lida consiste en o a implementar una unica vez cada m´todo “repetido”. e Ejemplo 4. esto ser un problema.9. podr´ ıamos pensar que bajo estas premisas nos encontramos ante un caso de herencia m´ltiple. los no a . C# es muy parecido a Java. a continuaci´n se muestran s´lo algunas comparaciones o o entre dichos lenguajes y C#. pues ya hereda dichas e implementaciones de la clase X.16 Sea la jerarqu´ mostrada en la figura 4. pues como ya vimos en el ejemplo 4. Al igual que en el ejemplo ıa anterior. Java y C++: Estudio comparativo 39 Ejemplo 4.8 C#.

De hecho Java es conceptualmente un subconjunto de C#. En C# existe el concepto de propiedades. Ofrece demasiadas oportunidades al programador de manejar err´neamente los punteros en aras de la eficiencia. o C++ es dependiente del sistema. C# permite paso por referencia en los tipos primitivos. El mero hecho de que el n´cleo de C# est´ desprovisto del u e tipo puntero simplifica enormemente su compresi´n por parte de un estudiante de POO. o C# ha retenido. Herencia referenciados por ninguna variable). o . No est´ preparado para la Web. aunque de una forma m´s l´gica y simple. C# incorpora la instrucci´n foreach junto con la interface IEnumerator. la habilidad de C++ para a o sobrecargar operadores. Un programador de C# puede convertir r´pidamente su c´digo a Java. Toda clase tiene como clase base de su jerarqu´ a ıa la clase object. pero no a la a o inversa. No maneja la memoria a como lo hacen C# o Java. C++ es muy complejo e inseguro. lo cual proporciona los m´todos de acceso get y set para consultar y modificar los valores de los miembros e de datos de una clase. En C# todo es un objeto. lo cual pero mite la construcci´n de un iterador. C# tiene verdaderos arrays multidimensionales.40 Tema 4. Los tipos primitivos tales como int pueden ser tratados como objetos. No es este el caso de Java donde los tipos primitivos son estrictamente “tipos valor”.

. . . . . . . .2. . . . . . . . . . Variables en los lenguajes tradicionales . . . . . . . . . . . . . . Herencia simple y m´ltiple . .4. . . . . . . . . . . . . Herencia m´ltiple y colisi´n de nombres . . . . . . . . . . . . . . . . . Herencia y redefinici´n de m´todos . . . . Ejemplo de copia superficial . . . . . . . . . . . . . . . . . . o e 4. . . .6. e . . . . . . . u o 4. . . . . . . . . . . .10. . . 2. . . 2. .3. . . . . . . . . . . . . .6. . . . . . . . . . . . . . Herencia m´ltiple sin herencia repetida (II) . . . . . . . . Jerarqu´ de clases . . . . . . Ejemplo de copia profunda . . .5. . . . . . . . . . . . . . . . . . Ejemplo de variables id´nticas . . . . . . . . . . . . . . . . . u 4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . u 4. . . . . . . . . 2. . .7. . . . . . . . . . . . . . . . . .3. .7. . . 2. Herencia m´ltiple sin herencia repetida (I) . . . . . . . . . . . . ıa 4. . . .1. . . . . . . . . . . . . . . .1. . 2. . . . . . . . . . . . . . . . . . . . . . . . Herencia de especializaci´n y de implementaci´n o o 4. .8. . . . . . . . 2. Herencia e implementaci´n de interfaces .9. . . . .5. . . Ejemplo de estructura de datos polimorfa . . . . u 41 . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 4. . . 4. . . . . . 8 11 11 11 12 12 13 25 26 29 30 33 37 37 38 39 39 4. . . .´ Indice de Figuras 2. . . . . .4. Herencia m´ltiple y herencia repetida . . . . . . . . . Clientela y Herencia entre A y B . . . . . . . . . . . . . . . . Variables tipo “puntero” en los lenguajes tradicionales Variables en los lenguajes OO . . . . . . u 4.2. .

42 ´ INDICE DE FIGURAS .

4. .1. . Algunas Excepciones est´ndar . . . . . . . . .2. . . . . . . . . . . . . . . . . . . . Propiedades de las excepciones . . . . . . . . . . . . . . . . . . . . . . . . 2. . . . . . Operadores binarios “sobrecargables” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4. . . . . . . . . . 4. . . . . . . .3. . . . .4.2. . . . . . . . . . . . . . 43 . Tipos enteros primitivos . . . . . . . . . . . . . . . . . . .1. . a 3. . . . . . . . . . . . . . 6 6 6 6 19 19 26 27 27 3. .2. . . . . . .´ Indice de Tablas 2. 2. . . . . . . . . . . 2. Palabras reservadas . . . . . .3. . . Tipos flotantes primitivos Otros tipos primitivos . . . . Operadores unarios “sobrecargables” . . . . . . . . . . . . . . . . . . . . . . . . . .1. . . . . . . . . . . . . . . Propiedades de las excepciones . . . . . . . . . .

44 ´ INDICE DE TABLAS .

. . . . . . . 3. Uso de excepciones con m´s informaci´n . . . 4. . . o Ambig¨edad de nombres debida a la herencia m´ltiple u u Soluci´n a la ambig¨edad de nombres .3. . o o Ejemplo de Clases Anidadas . . .1. . . . . .4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6. . . . . . . .2. . Clase Luna . . . . . . . . . . . . 3. . . . . . . o e Clase abstracta Figura . .5. 3. . Ejemplo de implementaci´n del m´todo Clone() . . . . . 4. . .3. . . . . . . . . . . .1. . . u Implementaci´n de un iterador . . . . . . . . . . . . . 4. . . . . . . . . . . . . . . 2. .2.6. . . . . . . . . .4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ejemplo del uso de excepciones . . . . . . . o e Lista gen´rica doblemente enlazada . . . . . . . . . . . . . .7. . 5 7 8 9 12 13 14 18 18 20 21 22 28 31 31 33 35 38 38 45 . . . . . . . . . . .2. . . . . . Ejemplo de Ocultaci´n de Informaci´n . 4. . . . . . . . . . . 4. . . . . . . . . . . . . .4. . . . . . . . . . . . . . . . . . . . .´ Indice de C´digos o 2. . . . . . . . . . . . 2. . . . . . . . . . . 4. a o Ejemplo del uso de excepciones en vez de asertos . . . . .1. . Ejemplo de Constructores . . . . . . . . .3. 2. . . . . . . . . . . . . . . . . . . .5. . . Ejemplo de Sobrecarga de Operadores . . . . . 2. . . . . . . . . . . o u . . Herencia M´ltiple mediante interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . Redifinici´n de un m´todo heredado . . . . 2. . . . o o Otro ejemplo de Ocultaci´n de Informaci´n . . . . . . . . . Ejemplo del relanzamiento de excepciones . . . . . . . . . . . . . . 3. . . . . . . .5. . . . . . . . . . . . 3. . . 4. . . . . . . . . . . . . . . . . . . . . . e Ejemplo del uso de asertos . . . . . . . . 2. . .7. . . . .

46 ´ ´ INDICE DE CODIGOS .

Garc´ Molina. 47 . Lippman. [Mol04] J. 2003.Bibliograf´ ıa [Lip02] Stanley B. A Practical Approach. Addison Wesley. University of California. C# by Dissection. Apuntes de programaci´n orientada a objetos. Addison Wesley. 2002. ıa o [Poh03] Ira Pohl. C# Primer. 2004.

Sign up to vote on this title
UsefulNot useful