Clases y Objetos C#

download Clases y Objetos C#

of 47

Transcript of Clases y Objetos C#

Programacin o Orientada a Objetos C#

Flix Gmez Mrmol e o a3o Ingenier Informtica a a Julio de 2004

2

Indice general Indice General 2. Clases y Objetos 2.1. Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1. Estructura . . . . . . . . . . . . . . . . . . . . . . . 2.1.2. Ocultacin de la informacin . . . . . . . . . . . . . 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. Notacin punto . . . . . . . . . . . . . . . . o 2.3.2. Semntica . . . . . . . . . . . . . . . . . . . . . . . . a 2.4. Semntica referencia versus semntica almacenamiento . . . a a 2.5. Creacin de objetos . . . . . . . . . . . . . . . . . . . . . . o 2.5.1. Destructores . . . . . . . . . . . . . . . . . . . . . . 2.6. Semntica de la asignacin e igualdad entre objetos . . . . . a o 2.7. Genericidad . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8. Denicin de una clase Lista Doblemente Enlazada . . . o 3. Dise o por Contrato: Asertos y Excepciones n 3.1. Contrato software . . . . . . . . . . . . . . . . 3.2. Clases y Correccin 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. Conversin de asertos en excepciones . . . . . o 4. Herencia 4.1. Introduccin . . . . . . . . . . . . . . . . . o 4.2. Doble aspecto de la herencia . . . . . . . . 4.3. Polimorsmo . . . . . . . . . . . . . . . . 4.3.1. Sobrecarga . . . . . . . . . . . . . 4.3.2. Regla de aplicacin de propiedades o 4.3.3. Estructuras de datos polimrcas . o 4.3.4. Operadores is y as . . . . . . . . 4.4. Ligadura Dinmica . . . . . . . . . . . . . a 4.5. Clases Diferidas . . . . . . . . . . . . . . . 4.5.1. Interfaces . . . . . . . . . . . . . . 4.6. Herencia, reutilizacin y extensibilidad del o 4.7. Herencia mltiple . . . . . . . . . . . . . . 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: Colisin 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 Cdigos o Bibliograf a

37 38 39 41 43 45 47

Tema 2

Clases y Objetos2.1. Clases

Denicin 2.1 Una clase es una implementacin total o parcial de un tipo abstracto de o o dato (TAD). Sus caracter sticas ms destacables son que se trata de entidades sintcticas y que descria a ben objetos que van a tener la misma estructura y el mismo comportamiento.

2.1.1.

Estructura

Los componentes principales de una clase, que a partir de ahora llamaremos miembros, son: Atributos, que determinan una estructura de almacenamiento para cada objeto de la clase, y Mtodos, que no son ms que operaciones aplicables sobre los objetos. e a Ejemplo 2.1 La clase mostrada en el cdigo 2.1, llamada Luna, convierte a kilmetros la o o distancia de la Tierra a la Luna en millas.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 ; public class Luna { public static void Main () { int luna = 238857; int lunaKilo ; Console . WriteLine (" De la Tierra a la Luna = " + luna + " millas ") ; lunaKilo = ( int ) ( luna * 1.609) ; Console . WriteLine (" Kil metros = " o + lunaKilo + " km .") ; } } Cdigo 2.1: Clase Luna o

5

6

Tema 2. Clases y Objetos

Tipo short ushort int uint long ulong

Bytes 2 2 4 4 8 8

Rango de Valores (-32768, 32767) (0, 65535) (-2147483648, 2147483647) (0, 4294967295) (-9223372036854775808, 9223372036854775807) (0, 18446744073709551615)

Tabla 2.1: Tipos enteros primitivos Tipo float double decimal Bytes 4 8 16 Rango de Valores (3,4 1038 ) 7 d gitos signicativos (1,7 1038 ) de 15 a 16 d gitos signicativos 28 , 7,9 10+28 ) de 28 a 29 d (10 gitos signicativos Tabla 2.2: Tipos otantes primitivos Tipo byte ubyte bool char Bytes 1 1 1 2 Rango de Valores (-128,127) (0,255) {true, false} Tabla ASCII

Tabla 2.3: Otros tipos primitivos Tipos de datos primitivos Las tablas 2.1, 2.2 y 2.3 muestran los tipos primitivos soportados por C#. Para declarar un tipo consistente en un conjunto etiquetado de constantes enteras se emplea la palabra clave enum (por ejemplo, enum Edades {Flix = 21, Alex, Alberto = 15}). e Palabras reservadas La tabla 2.4 muestra las palabras reservadas de C#. abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false nally xed oat 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.4: Palabras reservadas

2.1 Clases

7

2.1.2.

Ocultacin de la informacin o o

En ocasiones conviene ocultar ciertas caracter sticas (atributos y/o mtodos) de una clase e al exterior. Por ejemplo, en una relacin entre clases de Cliente-Servidor, el servidor deber o a ocultar los aspectos de implementacin al cliente. o Para llevar a cabo esto, C# proporciona tres tipos de acceso: pblico, privado y protegido. u Un miembro con acceso privado (opcin por defecto) slo es accesible desde otros miemo o bros de esa misma clase, mientras que uno con acceso pblico es accesible desde cualquier u clase. Por ultimo, un miembro protegido slo es accesible por miembros de la misma clase o o bien por miembros de alguna de las subclases. Ejemplo 2.2 En el cdigo 2.2 se muestra un ejemplo de ocultacin de informacin, mediante o o o la clase Punto.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

public class Punto { private double x , y ; // O simplemente double x , y ; public void SetPunto ( double u , double v ) { x = u; y = v; } } . . . class Test { public void Prueba ( Punto w ) { . . . w . SetPunto (4.3 ,6.9) ; // Correcto w . x = 5.5; // Error sint ctico a . . . } } Cdigo 2.2: Ejemplo de Ocultacin de Informacin o o o A diferencia de C++, en C# es posible declarar un miembro como de slo lectura mediante o la palabra clave readonly. La diferencia entre readonly y const es que con la primera opcin la inicializacin tiene o o lugar en tiempo de ejecucin, mientras que con la segunda opcin la inicializacin se da en o o o tiempo de compilacin. o Una forma de simular el efecto de const mediante readonly es usando adems la palabra a clave static. Ejemplo 2.3 En el siguiente cdigo, n y m podr o amos decir que son estructuralmente equivalentes: public const n; public static readonly m; Otra prctica interesante consiste en declarar un atributo como privado y, mediante otro a atributo pblico tener acceso de lectura y/o escritura sobre el atributo privado. Para ello nos u valemos de los modicadores de acceso get y set. Ejemplo 2.4 En el cdigo 2.3 se muestra un ejemplo de ocultacin de informacin mediante o o o el uso de get y set. Obsrvese que el identicador value es siempre un objeto del mismo tipo que el atributo e que lo contiene.

8

Tema 2. Clases y Objetos

1 2 3 4 5 6 7 8 9 10 11 12 13

public class CuentaPalabras { private string m_file_output ; // Atributo privado public string OutFile // Atributo p blico asociado u { get { return m_file_output ; } // Acceso de lectura set { // Acceso de escritura if ( value . Length != 0 ) m_file_output = value ; } } } Cdigo 2.3: Otro ejemplo de Ocultacin de Informacin o o o

2.1.3.

Relaciones entre clases: Cliente-Servidor y Herencia

Un cliente de una clase debe ver a sta como un TAD, es decir, conocer su especicacin, e o pero sin importarle su implementacin (siempre que sta sea eciente y potente). o e El creador de la clase, en cambio, debe preocuparse de que dicha clase sea lo ms reutilia zable, adaptable, y eciente, as como que pueda ser usada por el mayor nmero de clientes u posible. Denicin 2.2 Una clase A se dice que es cliente de una clase B, si A contiene una declao racin en la que se establezca que cierta entidad (atributo, parmetro, variable local) e es de o a tipo B. Denicin 2.3 Una clase A se dice que hereda de otra clase B, si A es una versin especiao o lizada de B (herencia de especializacin), o bien si A es una implementacin de B (herencia o o de implementacin). o La gura 2.1.a muestra la relacin de clientela entre A y B, mientras que en la 2.1.b se o observa la relacin de herencia entre dichas clases. o

AB(a)

B A(b)

Figura 2.1: Clientela y Herencia entre A y B

Ejemplo 2.5 El siguiente cdigo muestra la relacin de clientela vista en la gura 2.1.a: o o class A { . . . B conta; . . . } Por su parte, el siguiente cdigo muestra la relacin de herencia mostrada en la gura o o 2.1.b: class A: B { . . . }

2.1 Clases

9

Por ultimo cabe decir que la herencia es una decisin de diseo ms comprometedora que o n a la clientela, pues en sta ultima se puede cambiar la implementacin de la clase que se emplea e o en el cliente, sin afectar a ste (en nuestro ejemplo, se puede modicar la implementacin de e o B sin que esto afecte a A).

2.1.4.

Visibilidad

Adems de lo comentado en el apartado 2.1.2 acerca de la ocultacin de informacin, en a o o esta seccin trataremos la cuestin de las clases anidadas. o o Denicin 2.4 Una clase anidada no es ms 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. Ejemplo 2.6 El cdigo 2.4 muestra un ejemplo de clases anidadas. o El resultado mostrado por pantalla ser a: IntAnidado(6) = 171 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 ; } public class Dos { public int c ; public class Tres { public int IntAnidado ( int e ) { Dos d = new Dos () ; Uno u = new Uno () ; u.c = 5 + e; d.c = c = e; return u . c + c ; } private int c ; } public Tres y ; } public class PruebaAnidada { public static void Main () { Dos x = new Dos () ; x . y = new Tres () ; Console . WriteLine (" IntAnidado (6) = " + IntAnidado (6) ) ; } } Cdigo 2.4: Ejemplo de Clases Anidadas o

10

Tema 2. Clases y Objetos

2.2.

Objetos

Denicin 2.5 Un objeto es una instancia de una clase, creada en tiempo de ejecucin y o o formada por tantos campos como atributos tenga la clase. Dichos campos son simples si corresponden a atributos de tipos primitivos (vase tablas e 2.1, 2.2 y 2.3), mientras que se dice que son compuestos si sus valores son subobjetos o referencias. Mientras exista, cada objeto se identica un vocamente mediante su identicador de objeto (oid). Una posible clasicacin de los objetos podr ser: o a Objetos externos: Son aquellos que existen en el dominio de la aplicacin. Por ejemplo, o Producto, Socio, Comercial, Descuento, ... Objetos software: Procedentes del anlisis: objetos del dominio. a Procedentes del diseo/implementacin: TDAs, patrones de diseo y GUI. n o n El estado de un objeto viene dado por la lista de pares atributo/valor de cada campo. Su modicacin y consulta se realiza mediante mensajes. o En cada instante de la ejecucin de una aplicacin Orientada a Objetos (en adelante, OO) o o existe un objeto destacado sobre el que se realiza algn tipo de operacin. Este objeto recibe u o el nombre de instancia actual. Para hacer referencia a la instancia actual en C# se emplea la palabra reservada this.

2.3.

Mensajes

Los mensajes son el mecanismo bsico de la computacin OO y consisten en la invocacin a o o de la aplicacin de un mtodo sobre un objeto. o e Constan de tres partes: objeto receptor, identicador del mtodo y los argumentos de ste e e ultimo.

2.3.1.

Sintaxis. Notacin punto o

Como se ha podido observar en algunos de los ejemplos vistos hasta ahora, la forma en que se invoca a un mtodo es mediante el operador punto, siguiendo una sintaxis como la e que a continuacin se muestra: o receptor.mtodo(argumentos) e

2.3.2.

Semntica a

La diferencia entre un mensaje y la invocacin a un procedimiento es que en ste ultimo o e todos los argumentos reciben el mismo trato, mientras que en los mensajes uno de esos argumentos, a saber, el objeto receptor, recibe un trato especial. Ejemplo 2.7 En el mensaje w.SetPunto(4.3,6.9) lo que se est queriendo decir es que se a aplique el mtodo SetPunto sobre el objeto receptor w, efectuando el correspondiente paso de e parmetros. a Cuando un mensaje no especica al objeto receptor la operacin se aplica sobre la instancia o actual. Si no se incluye nada, el paso de parmetros es por valor. Para especicar un paso de a parmetros por referencia se emplea la palabra clave ref delante del parmetro en cuestin. a a o

2.4 Semntica referencia versus semntica almacenamiento a a

11

2.4.

Semntica referencia versus semntica almacenamiento a a

En C# se tiene semntica referencia (gura 2.41 ) para cualquier entidad asociada a una a clase, aunque tambin existen los tipos primitivos (gura 2.22 ), como ya hemos visto. e Toda referencia puede estar, o bien no ligada (con valor null), o bien ligada a un objeto (mediante el operador new, o si se le asigna una referencia ya ligada). Pero ojo, la asignacin o no implica copia de valores sino de referencias ( Aliasing).

Figura 2.2: Variables en los lenguajes tradicionales

Figura 2.3: Variables tipo puntero en los lenguajes tradicionales

Figura 2.4: Variables en los lenguajes OO Algunas ventajas de los tipos referencia son: Son ms ecientes para manejar objetos. a Constituyen un soporte para denir estructuras de datos recursivas. Dan soporte al polimorsmo. Los objetos son creados cuando son necesarios. Se permite la comparticin de un objeto. o

2.5.

Creacin de objetos o

En C# existe un mecanismo expl cito de creacin de objetos mediante la instruccin de o o creacin new y los llamados mtodos constructores (que deben tener el mismo nombre que la o e clase en la que se denen). Estos constructores se encargan de inicializar los atributos con valores consistentes. Sin embargo tambin se pueden inicializar con unos valores por defecto, mediante los constructores e por defecto (aquellos que no tienen argumentos).1 2

TETiempo de Ejecucin o TCTiempo de Compilacin o

12

Tema 2. Clases y Objetos

Ejemplo 2.8 El cdigo 2.5 muestra un ejemplo de una clase con un constructor y un conso tructor por defecto.1 2 3 4 5 6 7 8 9 10 11 12

public class Contador { private int conta ; public public public { get set } public } Cdigo 2.5: Ejemplo de Constructores o Contador () { conta = 0; } // Constructor por defecto Contador ( int i ) { conta = i % 100; } // Constructor int Conta { return conta ; } { conta = value % 100; } void Click () { conta = ( conta + 1) % 100; }

2.5.1.

Destructores

Un destructor es un mtodo cuyo nombre es el nombre de la clase precedido de una tilde e . Mientras que los constructores s pueden tener modicadores de acceso, los destructores carecen de ellos. Cuando un objeto es recogido por el recolector de basura3 se llama impl citamente a su destructor. No obstante, en la mayor de los casos las clases no necesitan destructores, pues a con el recolector de basura es suciente para la nalizacin. o

2.6.

Semntica de la asignacin e igualdad entre objetos a o

Denicin 2.6 Una copia se dice que es supercial si se copian los valores de cada campo o del objeto origen en el objeto destino y ambos comparten referencias (gura 2.5).

Figura 2.5: Ejemplo de copia supercial Denicin 2.7 Una copia se dice que es profunda si se crea un objeto con una estructura o idntica al objeto origen y sin comparticin de referencias (gura 2.6). e o

Figura 2.6: Ejemplo de copia profunda3

garbage collector

2.6 Semntica de la asignacin e igualdad entre objetos a o

13

Como ya se dijo anteriormente, la asignacin implica comparticin de referencias si se o o tiene semntica referencia, mientras que si se tiene semntica almacenamiento entonces se a a copian los valores. A este tipo de copia se le llama copia supercial y est soportada en C#. a Si se tiene semntica referencia y se realiza una copia supercial, los cambios hechos en a una variable tienen repercusin en su(s) correspondiente(s) copia(s). o Para evitar este efecto debemos realizar una copia profunda, lo cual puede llevarse a cabo, por ejemplo, implementando el mtodo Clone() de la interfaz ICloneable. e Ejemplo 2.9 El cdigo 2.6 muestra un ejemplo de una clase que implementa el mtodo o e Clone() de la interfaz ICloneable para conseguir una copia profunda.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 , int col ) { m_row = ( row 0 , " Valor no positivo : x = " + x . ToString () , new Exception () ) ; Console . WriteLine (" La ra z cuadrada es " + Math . Sqrt ( x )); } catch ( Exception e ) { Console . WriteLine ( e ) ; ExceptionSqrRoot . ConsoleSqrt () ; // Se vuelve a intentar } } public static void Main () { Console . WriteLine (" Probando Ra ces Cuadradas ") ; ConsoleSqrt () ; } } Cdigo 3.5: Ejemplo del uso de excepciones en vez de asertos o

24

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

Tema 4

Herencia4.1. Introduccin o

La herencia es un potente mecanismo para conseguir reutilizacin en el cdigo, consistente o o en derivar una nueva clase a partir de una ya existente. A travs de la herencia es posible e crear una jerarqu de clases relacionadas que compartan cdigo y/o interfaces. a o En muchas ocasiones distintas clases resultan ser variantes unas de otras y es bastante tedioso tener que escribir el mismo cdigo para cada una. Una clase derivada hereda la deso cripcin de la clase base, la cual se puede alterar aadiendo nuevos miembros y/o modicando o n los mtodos existentes, as como los privilegios de acceso. e Ejemplo 4.1 En la gura 4.1 se muestra un ejemplo de una jerarqu de clases. a

Figura 4.1: Jerarqu de clases a Denicin 4.1 Si B hereda de A entonces B incorpora la estructura (atributos) y comporo tamiento (mtodos) de A, pero puede incluir adaptaciones: e B puede aadir nuevos atributos. n B puede aadir nuevos mtodos. n e B puede redenir mtodos de A (bien para extender el mtodo original, bien para e e mejorar la implementacin). o B puede implementar un mtodo diferido en A. e 25

26

Tema 4. Herencia

La tabla 4.1 muestra los mtodos pblicos y protegidos de la clase object, ra en toda e u z jerarqu de clases de C#. a bool Equals(object o) void Finalize() int GetHashCode() Type GetType() object MemberwiseClone() bool ReferenceEquals (object a, object b) string ToString() Devuelve true si dos objetos son equivalentes, si no, devuelve false Equivalente a escribir un destructor Proporciona un entero unico para cada objeto Permite averiguar dinmicamente 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.1: Propiedades de las excepciones

4.2.

Doble aspecto de la herencia

Como ya se dijo en la denicin 2.3, la herencia es, a la vez, un mecanismo de especialio zacin y un mecanismo de implementacin. o o Esto es, una clase B puede heredar de otra clase A, por ser B una especializacin de A. Sin o embargo, puede ocurrir que el motivo por el cual B hereda de A sea la necesidad de construir una implementacin distinta (si se quiere, ms renada) de A. o a Ejemplo 4.2 La herencia entre clases que se observa en la gura 4.1, as como en las guras 4.2.a y 4.2.b sirve como mecanismo de especializacin. o Por otra parte, los ejemplos de las guras 4.2.c y 4.2.d muestran la herencia como mecanismo de implementacin. o

Figura 4.2: Herencia de especializacin y de implementacin o o

4.3.

Polimorsmo

Denicin 4.2 Podr o amos denir el polimorsmo como la capacidad que tiene una entidad para referenciar en tiempo de ejecucin a instancias de diferentes clases. o C# soporta el polimorsmo, lo cual quiere decir que sus entidades (las cuales poseen un unico tipo esttico y un conjunto de tipos dinmicos) pueden estar conectadas a una instancia a a de la clase asociada en su declaracin o de cualquiera de sus subclases. o Podr amos categorizar el polimorsmo en dos tipos: Paramtrico e Real y Aparente Sobrecarga Inclusin (basado en la herencia) o

4.3 Polimorsmo

27

Ejemplo 4.3 Dada la siguiente declaracin, siguiendo la jerarqu de clases de la gura 4.1, o a Poligono p; Triangulo t; Rectangulo r; Cuadrado c;

podemos decir que: te(p) = Poligono ctd(p) = {Poligono, Triangulo, Rectangulo, Cuadrado} te(t) = Triangulo ctd(t) = {Triangulo} te(r) = Rectangulo ctd(r) = {Rectangulo, Cuadrado} te(c) = Cuadrado ctd(c) = {Cuadrado} donde te signica tipo esttico y ctd signica conjunto de tipos dinmicos. a a Y por lo tanto las siguientes asignaciones ser vlidas: an a p = t; p = r; r = c; t = r; r = p; p = c; c = p; c = t;

Pero no lo ser an, por ejemplo:

4.3.1.

Sobrecarga

Denicin 4.3 La sobrecarga consiste en dar distintos signicados a un mismo mtodo u o e operador. C# soporta la sobrecarga de mtodos y de operadores. Uno de los ejemplos ms claros es e a el del operador +. Ejemplo 4.4 La expresin a + b puede signicar desde concatenacin, si a y b son de tipo o o string, hasta una suma entera, en punto otante o de nmeros complejos, todo ello depenu diendo del tipo de datos de a y b. Sin embargo, lo realmente interesante es poder redenir operadores cuyos operandos sean de tipos denidos por el usuario, y C# permite hacer esto. Pero conviene tener en cuenta que este tipo de actuacin slo es provechosa en aquellos o o casos en los que existe una notacin ampliamente usada que conforme con nuestra sobrecarga o (ms an, si cabe, en el caso de los operadores relacionales , =). a u La tabla 4.2 muestra los operadores unarios que en C# se pueden sobrecargar, mientras que la tabla 4.3 hace lo propio con los operadores binarios. + ! ++ true f alse Tabla 4.2: Operadores unarios sobrecargables + / % & | > == ! = < > >= = 18) ; } // M todos y propiedades requeridos por IEstudiante e public double NotaMedia { get { return notaMedia ; } set { notaMedia = value ; } } public int A~ oMatricula n { get { return a~ oMatricula ; } set { a~ oMatricula = value ; n n } }

34

Tema 4. 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 ; } set { salario = value ; } } public string Nss { get { return nss ; } set { nss = value ; } } // Constructores para Ayudante public Ayudante ( string nom , string tlf , int ed , double nm , int am , double sal , string numSec ) { nombre = nom ; telefono = tlf ; edad = ed ; notaMedia = nm ; a~ oMatricula = am ; n salario = sal ; nss = numSec ; } // Otras implementaciones de constructores y m todos e ... public override ToString () { return String . Format (" Nombre : {0: -20} Tel fono : {1 ,9} Edad : {2 ,2}" + e "\ nSeguridad Social : {3} Salario : {4: C }" + "\ nNota media : {5} A~ o de matriculaci n : {6}" , n o nombre , telefono , edad , nss , salario , notaMedia , a~ oMatricula ) ; n } private private private private private private private } Cdigo 4.4: Herencia Mltiple mediante interfaces o u string nombre ; string telefono ; int edad ; double notaMedia ; int a~ oMatricula ; n double salario ; string nss ;

4.6.

Herencia, reutilizacin y extensibilidad del software o

A continuacin enumeramos cules son los requerimientos que debe cumplir un mdulo o a o para facilitar la reutilizacin: o 1. Variacin en tipos. Conseguida gracias a la genericidad. o 2. Variacin en estructuras de datos y algoritmos. Conseguida gracias a la ligadura dinmio a ca y el polimorsmo. 3. Independencia de la representacin. Conseguida gracias a la ligadura dinmica y el o a polimorsmo.

4.6 Herencia, reutilizacin y extensibilidad del software o

35

4. Captura de similitudes entre un un subgrupo de un conjunto de posibles implementaciones. Conseguida gracias a la herencia. 5. Agrupacin de rutinas relacionadas. Conseguida mediante la construccin de clases. o o Existen dos aspectos importantes en la reutilizacin de cdigo: por una parte, la creacin o o o de componentes reutilizables, y por otra parte, la utilizacin de dichos componentes. o En C# existe una gran coleccin (an en crecimiento) de elementos reutilizables. Noo u sotros trataremos ahora brevemente el contenido de System.Collections y la interface Collections.IEnumerable. La implementacin de la interface IEnumerate por parte de una clase contenedora dota o a sta de la posibilidad de emplear la instruccin foreach, cuya sintaxis es: e o foreach (Tipo nombreVariable in nombreArray) Mediante la instruccin foreach tenemos en cada iteracin en la variable nombreVariable o o el contenido de la clase contenedora. Obsrvese que este valor no puede ser modicado, slo e o puede consultarse. Para construir un iterador necesitamos alguna manera de avanzar el iterador, devolver el siguiente valor en la coleccin y comprobar en cada instante si ya hemos iterado sobre todos o los elementos de la coleccin. o Para ello la interface IEnumerable declara el mtodo IEnumerator GetEnumerator(). e No obstante, para realizar una implementacin concreta deben implementarse (valga la reo dundancia) los mtodos MoveNext() y Reset(), as como el mtodo de acceso Current, todos e e ellos de la interface IEnumerator. Ejemplo 4.10 El cdigo 4.5 muestra un ejemplo de una clase que implementa la interface o IEnumerable, de modo que se podr emplear la instruccin foreach con objetos de dicha a o clase (como puede observarse en la l nea ). Se trata de un array de 10 enteros cuyo iterador slo indexa los elementos que ocupan o posiciones impares (teniendo en cuenta que la primera posicin es la 0, la segunda la 1, ...). o El resultado mostrado por pantalla ser a: 1 3 5 7 9 11 13 15 17 19 Iterando... 3 7 11 15 191 2 3 4 5 6 7 8 9 10 11 12 13 14 15

using System ; using System . Collections ; class ArrayImpar : IEnumerable { public int [] a = new int [10]; public IEnumerator GetEnumerator () { return ( IEnumerator ) new ArrayImparEnumerator ( this ) ; } public int this [ int i ] { get { return a [ i ]; } set { a [ i ] = value ; } } 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 )

36

Tema 4. 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 . a = a ; indice = -1; } public void Reset () { indice = -1; } public bool MoveNext () { indice += 2; return ( indice