Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Ingeniería en Desarrollo de Software 8º cuatrimestre
Programa de la asignatura: Programación .NET II Unidad 2. 2. Herencia y polimorfismo en el lenguaje de programación C Sharp Clave: 150930934
Universidad Abierta y a Distancia de México UnADM
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
1
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Índice Presentación Presentación de la unidad ................................................................................................. 3 Propósitos.......................................................................................................................... 3 Competencia Competencia específica específica..................................................................................................... 4 2.1. Herencia en C Sharp ................................................................................................. Sharp ................................................................................................. 4 2.1.1. Herencia simple .................................................................................................... 7 2.1.2. Clases abstractas abstractas ............................................................................................... 14 2.1.3. Clases selladas .................................................................................................. 22 Actividad 1. Herencia ....................................................................................................... 26 2.1.4. Interfaces ........................................................................................................... 27 Actividad 2. Herencia mediante C Sharp.......................................................................... 36 2.2. Polimorfismo en C Sharp ....................................................................................... Sharp ....................................................................................... 37 2.2.1. Métodos polimórficos polimórficos.......................................................................................... 39 2.2.2. Métodos genéricos ............................................................................................. 48 Actividad 3. Métodos polimórficos.................................................................................... 50 2.3. Sobreescritura en C Sharp ..................................................................................... Sharp ..................................................................................... 51 2.3.1. Modificador virtual ............................................................................................. virtual ............................................................................................. 52 2.3.2. Modificador override .......................................................................................... override .......................................................................................... 53 Autoevaluación Autoevaluación ................................................................................................................ 56 Evidencia Evidencia de aprendizaje. aprendizaje. Herencia simple, polimorfismo y sobreescritura sobreescritura...................... 57 Cierre de la unidad .......................................................................................................... 58 Para saber más ............................................................................................................... 58 Fuentes de consulta ........................................................................................................ 59
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
2
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Unidad 2. Herencia y polimorfismo en el lenguaje de programación C Sharp Presentación de la unidad Bienvenido a la nueva unidad de programación en .Net.II. Herencia y polimorfismo en el lenguaje de programación C Sharp es una unidad muy importante. Aquí trabajarás con esos dos conceptos fundamentales de la programación orientada a objetos basada en C Sharp. La filosofía de programación orientada a objetos maneja como pilar fundamental el concepto de reutilización de código; trata de evitar que los mismos procedimientos se reinventen una y otra vez. Hay dos formas de reutilización de código: la herencia y el polimorfismo. En la primera, el código se reutiliza de una clase ya existente; en la segunda, un método puede realizar diferentes funciones. Estos dos conceptos te serán de gran utilidad en el desarrollo de tu carrera, los cuales se explican en los temas 2.1. Herencia en C Sharp y 2.2. Polimorfismo en C Sharp, que forman parte de esta segunda unidad. En el 2.3. Sobre escritura en C Sharp, observarás que es posible que las clases que heredan cambien la funcionalidad de las ya existentes.
Propósitos Al término de de esta unidad unidad lograrás: lograrás:
Entender el concepto de herencia y la forma de construirla dentro de C Sharp. Manejar los métodos polimórficos polimórfi cos en el contexto de problemas planteados. Identificar la utilidad de los métodos polimórficos polimórfic os al construir programas con el lenguaje C Sharp. Identificar la utilidad del uso de interfaces en el contexto de un problema. Comprender el concepto de sobreescritura y su importancia en los procesos de herencia para la programación orientada a objetos en C Sharp.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
3
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Competencia específica
Implementar los conceptos de herencia , interfaces , polimorfismo, sobreescritura y seguir los estándares propuestos por la tecnología .NET; esto con el fin de entender los conceptos de programación orientada a objetos en dicha plataforma.
2.1. Herencia en C Sharp Un programa simple en C# puede usar una o dos clases; sin embargo, es seguro que en problemas reales sea necesario utilizar una gran cantidad. Muchas de estas clases pueden necesitar campos o métodos similares, y sería lógico compartir el código común entre ellas; dicho en otras palabras: reutilizar el código. C# incluye el concepto orientado a objetos de herencia como una “forma de reutilización de software con la que los programadores crean clases que absorben los datos y comportamientos de una clase existente y los mejoran con nuevas capacidades ” (Deitel y Deitel, 2007, p. 665). Una clase, que puede ser llamada padre, sede atributos a otra nombrada hija o derivada; de esta forma, en lugar de reescribir el código se reutiliza. El concepto de herencia en la programación orientada a objetos fue pensado, principalmente, para evitar la reescritura de datos y métodos en clases que puedan reutilizarse; reducir los errores al volver a escribir códigos similares; ahorrar tiempo en la programación; reforzar la reutilización de software de alta calidad, y comprobar, depurar y garantizar al máximo la implementación de un sistema en forma efectiva (Deitel y Deitel, 2007). La herencia también ayuda en los procedimientos de especialización. Una clase, a medida que se hereda, se especializa en las clases derivadas. Otra de las grandes ventajas en el uso de la herencia consiste en que al corregirse el error, sólo una vez, del dato que se heredará de la clase “base” , todas las clases subsecuentes se corregirán en consecuencia Este concepto de herencia es tan importante en el desarrollo de aplicaciones que Andrew Troelsen, en su obra Pro C# 2010 and the .NET 4 Platform , la llama “Pilar de la programación orientada a objetos” , porque permite crear jerarquías de clases relacionadas por funcionalidades similares (al compartir datos y métodos comunes). Aquí aparece el término que permite entender la herencia y que es la parte medular de esta tecnología: es-un (Deitel es-un (Deitel y Deitel, 2007, p. 666). Este término señala una relación entre dos clases, y se basa en “ la idea […] de la herencia clásica [donde] las nuevas clases se División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
4
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
pueden crear utilizando las clases existentes como punto de partida” (Troelsen, 2010, p.
219). A continuación continuación se expone expone un ejemplo sencillo de la vida real real para entender entender el término y el concepto. Se sabe con certeza que un gato es un animal mamífero. Si se requiere representar esta relación, en una clase C Sharp mediante herencia, una forma muy clara se muestra a continuación.
Mamíferos
Gato
Aquí se puede observar observar lo siguiente: 1) Se cuenta con una clase padre (también llamada base), que es Mamíferos. Mamíferos. Ésta tendrá las características generales de todos los mamíferos (se alimenta de leche materna durante cierto periodo de tiempo, tiene pelo, etc.). 2) Se cuenta con una clase hija, Gato (también Gato (también llamada derivada), que tiene las características específicas del animal gato (es doméstico, es terrestre, come carne, etcétera). Si se requiere programar las características generales que serán heredadas por la clase hija, sólo se programarán en la clase padre y de forma automática, al aplicar el concepto Gato, en este caso). de herencia, aparecerán en la clase derivada ( Gato, A continuación continuación se exponen exponen algunos ejemplos ejemplos de herencia.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
5
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Tabla 1. Ejemplos de herencia Clase base* Clase derivada*1 Estudiante EstudianteGraduado EstudianteNoGraduado Forma Circulo Triangulo Rectangulo Prestamo PrestamoAutomovil PrestamoMejoraCasa PrestamoHipotecario Empleado Docente Administrativo Administrativo Cuenta CuentaDeCheques CuentaDeAhorros Deitel y Deitel, 2007, p. 667. En esta representación es posible observar lo siguiente: Estudiante. Esta tendrá las 1) Se cuenta con una clase base o padre que es Estudiante. características generales de todos los estudiantes (acuden a una institución educativa, tienen una matrícula, etcétera). EstudianteGraduado, que 2) Se cuenta con dos clases hijas o derivadas que son EstudianteGraduado, tiene las características específicas de un estudiante; es decir, ya concluyó los estudios y adquirió el grado académico correspondiente y Estudiantenograduado que puede ser de cualquier nivel del sistema educativo correspondiente. Si se tiene que programar en esta clase las características generales que serán heredadas por la clase hija, sólo se asignarán en la clase padre, y, de forma automática, EstudianteGraduado o al aplicar el concepto de herencia aparecerán en la derivada ( EstudianteGraduado o Estudiantenograduado según sea el caso). Se observa que esto es natural de cierta forma porque EstudianteGraduado o Estudiantenograduado es un Estudiante. Estudiante. Como puede observarse este término significa que, por el concepto de herencia, la clase derivada es un ejemplar de la clase base.
1
Se omiten los acentos por cuestiones propias de la programación en las siguientes palabras que
integran la tabla ejemplo de herencia: Círculo, Triángulo, Rectángulo, Préstamo y Automóvil.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
6
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Puede concluirse que “la herencia en la programación orientada a objetos es el procedimiento mediante el cual es posible construir nuevas clases extendiendo la funcionalidad de clases existentes” (Troelsen, 2010, p. 220).
2.1.1. Herencia simple Como se revisó en el apartado anterior, herencia es un concepto de programación orientada a objetos, el cual hace posible que una clase derivada reciba atributos (datos y métodos) de una clase base. En el marco de la herencia en programación orientada a objetos, pueden observarse dos casos de herencia C Sharp (Sharp, 2010, p. 262): 1) Una clase padre otorga atributos a una o más clases hija. 2) Varias clases padre otorgan atributos a una o varias clases hija. El primer caso se conoce como herencia simple, el segundo, como herencia múltiple (el nombre es dado por el número de clases padre, no por el de clases hija). Esto puede representarse de la siguiente manera: Padre
Hija1
Herencia simple
Nota: El símbolo:
Padre1
Hija2
Padre2
Hija
Herencia múltiple
Significa que una clase base o padre hereda
atributos a una clase hija. La punta de flecha padre.
♦ indica quién es la clase .
Lo anterior es posible en la programación orientada a objetos. Para la programación en C Sharp no está permitido el manejo de la herencia múltiple, sino sólo la herencia simple;
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
7
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
según lo señalado en la página web de Microsoft (MSDN, 2013 c), “como Java, C# no admite herencia múltiple, lo que significa que las clases no pueden heredar más de una clase” . Lo que sí es posible es tener herencia lineal múltiple. Esto se muestra en la siguiente figura.
Clase1
Clase2
Niveles de herencia
Clase3 Para fines prácticos, Clase1 es Clase1 es padre de Clase2, Clase2, y ésta a su vez es padre de Clase3. Clase3. Es posible generar cualquier jerarquía de clases (cualquier nivel) en este proceso de herencia, pero siempre respetando el concepto herencia simple: Sólo puede heredarse de un padre a una vez. Como se muestra en la imagen anterior, Clase1 es padre de Clase2, y éste a su vez es padre de Clase3. El ejemplo anterior es un proceso acumulativo. Clase2 tendrá atributos que recibirá de Clase1. Clase3 tendrá atributos que recibirá de la Clase2 y Clase1. Esto se repetirá en todas las clases situadas en los niveles de herencia. Desde el punto de vista de programación de C Sharp, el concepto de herencia se logra con el símbolo “ :”. A continuación se ofrece un ejemplo. Persona y Docente. Docente. La primera debe heredar de la segunda. Se tienen dos clases, Persona y El enunciado en C Sharp puede representarse así:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
8
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
¿Qué atributos se heredan? En heredan? En este punto es necesario retomar el concepto de encapsulamiento de la unidad anterior. Recuerda que un dato o método miembro puede tener cuatro niveles de alcance: protegido, protegido, público, público, privado y privado y de alcance al proyecto actual. actual. El nivel de alcance es la visibilidad que estos miembros tendrán fuera del objeto. En lo que corresponde al caso expuesto sobre el tema de herencia, herencia, es necesario recordar los tres primeros niveles porque sólo éstos son los que se utilizan para el control de la herencia (Ferguson, Patterson y Beres, 2005, p. 259). Si una clase padre tiene miembros (datos y métodos) privados, ninguno de ellos será heredado a una clase hija; los miembros protegidos sí se heredarán, pero seguirán siendo protegidos para la clase derivada; los miembros públicos se heredarán y continuarán siendo públicos. Las funciones y los datos que se desean heredar deben seguir las reglas de encapsulamiento. En el ejemplo se incluirán estas especificaciones: Persona tendrá Persona tendrá los siguientes datos que deberán ser heredados: tipo string el string el nombre, char el sexo e int la int la edad. Se integrará un constructor que recibirá estos tres datos y los guardará como privados. Se agregará un método llamado información de tipo público, que mostrará en la pantalla el contenido de los tres datos. Para implementar la clase es importante recordar que los datos en un objeto siempre deben ser privados; pero como se desea heredarlos, en este caso serán protegidos.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
9
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La clase escrita en C Sharp tendrá la siguiente forma:
El proceso de herencia quedará como sigue:
El constructor que tiene la clase Docente llama Docente llama al constructor padre con el comando base y envía los parámetros que recibe, los cuales deben ser los mismos en posición y tipo. Esto indica que se cumple la siguiente regla en la programación de herencia en lenguaje C Sharp: “Un constructor a pesar de ser un método público es el único que no se hereda y necesita ser llamado explícitamente desde la clase hija por la palabra base, con los argumentos entre paréntesis que se le envían” (Troelsen, 2010, p. 229).
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
10
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
En el programa, es posible utilizar ambos objetos (Persona y Docente) de la siguiente manera:
Pueden observarse en el programa principal los siguientes puntos:
Ambos objetos objetos pueden instanciarse instanciars e de manera similar, a pesar de que la clase Docente no tiene código interno para la declaración de los datos miembros; pero Persona sí los puede utilizar. al ser una clase heredada de Persona sí Ambos tienen el método de información(), información(), que muestra el contenido de los datos Docente. miembro, a pesar de que no se implementó en la clase Docente.
Si se ejecuta el programa, la salida será la siguiente: Nombre: Manuel Sexo: M Edad: 34 Nombre: Luisa Sexo: F Edad: 30 En la salida del programa se observa que ambos objetos tienen información interna, y Informacion(), a pesar de que sólo se ha programado ésta se muestra con el método Informacion(), dicho método para la clase base, pero la clase hija puede utilizarla por herencia.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
11
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Es posible agregar información al objeto; por ejemplo: si se toma en cuenta que un docente, además de contar con nombre, sexo y edad, tiene también un número de tarjeta, puede agregarse un nuevo dato privado llamado tarjeta de tipo entero. Se modificará el constructor para que llame al de la clase padre y guarde el nuevo dato. Éste también tendrá un método público con el nombre de informacionTotal(), informacionTotal(), que mostrará el nombre, sexo, edad y la nueva información de la tarjeta. Tal como se aprecia en el siguiente código:
Como se puede ver, el constructor ahora recibe cuatro parámetros, de los cuales tres envía al constructor padre, el último lo asigna él mismo. Cuando un constructor hijo llama al padre deben respetarse las siguientes reglas: 1) El número de parámetros enviados y su tipo deberán ser los mismos que los que recibe el padre (el nombre no importa, sólo el tipo y el número). 2) Después de invocar a su padre actualizará sus propios datos (también (tambié n puede realizar otro tipo de procesos, pero siempre después de llamar al constructor padre).
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
12
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
El programa principal puede modificarse de la siguiente manera:
Al ejecutar ejecutar este programa, programa, la salida salida será la siguiente: siguiente: Nombre: Manuel Sexo: M Edad: 34 Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Se puede observar cómo la información se ha ido agregando. Para finalizar el análisis de esta parte, se recapitula lo revisado respecto al concepto base es-un; en este caso la herencia es factible de ser de la herencia cuando utiliza el término es-un; utilizada porque el objeto Docente es una “ Persona”, finalmente. A continuación continuación se revisarán revisarán las clases abstractas, abstractas, subtema subtema muy importante importante para para la herencia porque permite escribir clases que no se deben instanciar.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
13
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
2.1.2. Clases abstractas En el mundo real existen clases base que no deben ser instanciadas porque son sólo un concepto. En una institución educativa no existen las personas como tales; existen alumnos, directores, profesores, administrativos, etcétera, pero una persona sin una función no es un concepto aceptable. Por ejemplo:
Mamíferos
Gato
La clase Mamífero es una clase abstracta porque en el mundo real no existe un ente específico llamado mamífero. Es el nombre genérico con el que se clasifica a cierto tipo de animales; sin embargo, cuando se observa un perro, un gato o un delfín, puede decirse que son mamíferos; pero por sí mismo el concepto mamífero no indica un animal en específico; es decir, se refiere a una entidad inexistente en la realidad. A esas entidades entidades que que no deben deben ser instanciada instanciadass porque no representan representan una una realidad son declaradas como clases abstractas para que el usuario no las instancie y como consecuencia no las utilice (Ferguson, Patterson y Beres, 2005, p. 267). Una definición clara de lo que es una clase abstracta se cita en Microsoft (MSDN, 2013b), en la Guía de programación de C#, el apartado de “Clases y miembros de clase abstractos y sellados ”, donde se señala que “el propósito de una clase abstracta es proporcionar una definición común de una clase base que múltiples clases derivadas pueden compartir. Por ejemplo, una biblioteca de clase puede definir una clase abstracta que se utiliza como parámetro para muchas de sus funciones y solicitar a los programadores que utilizan esa biblioteca que proporcionen su propia implementación de la clase mediante la creación de una clase derivada” . abstract permite crear clases únicamente con propósitos de herencia, La palabra clave abstract permite pero estas no se pueden instanciar.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
14
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
En el ejemplo, la clase Persona no debe instanciarse porque es abstracta. Para ello, simplemente se agrega la palabra abstract antes abstract antes de class, class, como como puede observarse en el siguiente código.
En esta ocasión el programa principal mostrará el siguiente error:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
15
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Persona. Si se suprime la línea que tiene el error se No es correcto instanciar el objeto Persona. obtendrá lo siguiente:
Al ejecutar ejecutar el programa es posible observar el el siguiente resultado: Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Persona y su llamada p.Informacion(). Informacion(). Se debe quitar la instancia de Persona y Una clase abstracta puede tener (aunque no es necesario) métodos miembro abstractos. Un miembro abstracto puede ser heredado (si es público o protegido), y su finalidad es indicar que debe existir una implementación, aunque no se dice el cómo hacerla.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
16
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Si se requiere un método abstracto para la clase Persona llamado Identificacion(), Identificacion(), este método no se implementará (programará), sólo indicará que toda clase que herede de él debe integrar el código para que realice su función. Un método abstracto tiene la siguiente sintaxis, según el MSDN (2013 b): p u b l i c | p r o t e c t ed ed a b s t r a c t t i p o n o m b r e (p (p a r a m e t r o s ) ;
public | protected: protected: significa que los métodos abstractos deben ser públicos o protegidos. Esto es una consecuencia lógica porque deben de ser heredados, y la clase derivada se va a encargar de su implementación. abstract: indica abstract: indica que este método no tendrá código. tipo: tipo: indica el valor de retorno del método correspondiente. nombre(parametros): nombre(parametros): indica el nombre de la función. Si no tiene parámetros sólo debe llevar los paréntesis, en caso contrario se agrega la lista de parámetros. En C Sharp se codificaría como sigue:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
17
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
18
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La clase derivada Docente mostraría Docente mostraría el siguiente error:
Docente indica que la clase no ha dado funcionalidad al método El subrayado en Docente indica Identificacion(). Se le otorga funcionalidad de la siguiente manera: abstracto Identificacion().
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
19
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
20
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Como se puede ver en el ejemplo, cuando una clase hereda un método abstracto y debe implementarlo, debe incluirse la palabra reservada override. override. De esta manera se indica que el método tendrá código para realizar lo solicitado en esta clase. El programa principal en este ejemplo tendrá la siguiente implementación:
La ejecución es la siguiente: Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Identificación con tarjeta número: 57 Una clase abstracta puede heredarse por otra abstracta. Significa que ninguna de ellas puede instanciarse. Si se traslada al mundo real, este principio puede comprenderse en la siguiente jerarquía de clases: Vertebrados <
>
Mamíferos <>
Perro
Tigre
Aves <>
Tucán
Canario
Peces <>
Trucha
Sardina
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
21
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Al observar observar esta jerarquía, jerarquía, pueden pueden obtenerse obtenerse varias varias conclusiones conclusiones sobre las distintas distintas clases: 1) 2) 3) 4) 5) 6)
Vertebrados, Mamíferos o Aves no pueden instanciarse. Perro, Tigre, Tucán pueden instanciarse. instanciar se. Un Perro es-un Mamífero y un Perro es-un Vertebrado. Perro y Tigre comparten información. informaci ón. Son mamíferos y son vertebrados. vertebrados. Canario y Trucha comparten información como que son vertebrados. Cada constructor debe llamar, con el comando base, al constructor padre. El padre llamará al constructor de su padre y así sucesivamente.
Las clases han generado una jerarquía que permiten relacionar objetos que comparten características similares, y separar objetos que no lo hacen. Surge aquí una pregunta: ¿si la clase Vertebrados tiene Vertebrados tiene un método abstracto, qué debe hacer Mamíferos cuando Mamíferos cuando herede este método? Tiene dos opciones: 1) Volverla a declarar como método abstracto; esto se logra volviendo a escribirla tal y como fue definida en la clase base, sin codificación. El codificarla será trabajo de la siguiente clase en la jerarquía de la herencia. 2) Sobreescribirla Sobreescribi rla para darle funcionalidad, como se indicó en el ejemplo de Persona-Docente. Persona-Docente.
Puede concluirse que en un sistema jerárquico de herencia lineal no existe ninguna restricción sobre el número de niveles que pueden agregarse.
2.1.3. Clases selladas Cierto, en la herencia lineal no existe restricción sobre el número de niveles que pueden agregarse, pero puede ser conveniente detener esta derivación por la naturaleza del problema. El modificador sealed se utiliza para impedir la derivación de una clase. Si se especifica que sealed es la clase base de otra clase, clase, se produce un error en tiempo de compilación; sealed no sealed no puede ser tampoco abstracta. El modificador sealed se sealed se utiliza,
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
22
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
principalmente, para impedir la derivación no intencionada, pero también permite algunas optimizaciones en tiempo de ejecución, según se explica en Microsoft (MSDN, 2013a). Dicho de otra manera, una clase sellada indica que ésta no puede usarse como base en una jerarquía de herencia, y que debe ser la última en la jerarquía lineal. Es también claro que una abstracta no puede ser sellada, porque las clases abstractas deben ser derivadas para implementarse; lo cual contradice los conceptos de clase sellada y clases abstractas. En el ejemplo de herencia, Persona-Docente, Persona-Docente, es posible heredar de Docente una nueva clase llamada Jefe. En algunas instituciones los jefes de departamento deben ser docentes propuestos de la misma academia; es decir, que pertenezcan a la misma academia. Un Jefe de departamento es un docente un docente con estas características:
Tiene asignado un departamento. Es responsable de las funciones de varias personas a su cargo.
Antes de implementar implementar la clase sellada, sellada, es conveniente conveniente hacer hacer la siguiente siguiente observación: observación: una jerarquía de clases no tiene por por qué seguir seguir una jerarquía jerarquía organizacion organizacional; al; son dos conceptos muy diferentes, la primera indica cómo se desarrollan y comportan objetos computacionales, la segunda se refiere al comportamiento lógico de una empresa en cuanto a sus relaciones laborales. Con base en estas consideraciones, la representación de los objetos se conforma de la siguiente manera: Persona <>
Docente
Jefe <
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
23
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La clase Jefe tendrá un dato miembro privado con el nombre de departamento, de tipo string; string; éste será recibido en el constructor. El código de esta clase se muestra a continuación:
Como puede observarse, existen dos indicaciones importantes:
La palabra sealed antes sealed antes de class class indica indica que esta clase no puede ser derivada; es herencia.. Algunos autores, en otros decir, está sellada a la jerarquía la jerarquía de herencia lenguajes, llaman a este concepto clase “ Final” porque la instrucción obliga a que se termine una jerarquía lineal de varios niveles. La palabra new indica new indica que el método Informacion() oculta Informacion() oculta el método Informacion() de Informacion() de la clase base Docente. Docente. El uso de esta instrucción es muy bien definido en el siguiente texto: “ Hay ocasiones en las que puede resultar interesante usar la herencia únicamente como mecanismo de reutilización de código pero no necesariamente para reutilizar miembros. Es decir, puede que interese heredar de una clase sin que ello implique que su clase hija herede sus miembros tal cuales sino con ligeras modificaciones” (González, 2004, p. 83).
La ocultación significa que, cuando se invoque a este método, se ejecutará el de la clase derivada y no el de la clase padre.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
24
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
El programa principal tendrá el siguiente código:
La ejecución de este programa arrojará el siguiente resultado: Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Identificación con tarjeta número: 57 Nombre: Ángel Sexo: M Edad: 38 Departamento: Sistemas Para concluir este punto, se recuerda que una clase sellada no puede derivarse o heredar; por lo tanto, después de Jefe no Jefe no puede haber más herencia.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
25
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Actividad 1. Herencia El propósito de esta actividad es que distingas las características de los siguientes tipos de términos: clases estándares, clases abstractas, clases selladas. Según lo desarrollado en el Tema 2.1. Herencia en C Sharp, ésta simplifica la reutilización de código cuando una clase hija recibe los métodos y datos miembro de una clase padre. En esta actividad identificarás los diferentes usos de clases y los alcances de cada una de ellas. Elabora un cuadro comparativo de las características de las siguientes clases: 1. Elabora un normales, interfaces, abstractas y selladas. Explica en tu cuadro la definición, uso, alcance y características de cada uno de 2. Explica en los tipos clase, que permiten tener una jerarquía de acuerdo a la realidad de los objetos en el mundo. Agrega ejemplos de cada uno, así como tus propias conclusiones sobre semejanzas y diferencias entre ellos. Identifica el uso en la vida real de herencia simple, múltiple y simple-múltiple. 3. Identifica el Sube tu trabajo a la base de datos. 4. Sube tu Comenta el cuadro comparativo y los ejemplos de tus compañeros(as), al menos 5. Comenta el uno de ellos, sobre la definición de los tipos de clases, así como la pertinencia de los ejemplos. Recuerda que tus comentarios no deben ser agresivos, sino constructivos. Guarda la actividad con el nombre DPRN2_U2_A1_XXYZ. Sustituye las XX por 6. Guarda la las dos primeras letras de tu primer nombre, la Y por tu primer apellido y la Z por tu segundo apellido. Envía el archivo a tu Facilitador(a) para recibir retroalimentación. 7. Envía el *Consulta la Rúbrica para elaborar el cuadro comparativo que encontrarás en el archivo Criterios de evaluación de las actividades de la Unidad 2 , para conocer los parámetros de esta actividad.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
26
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
2.1.4. Interfaces En los subtemas anteriores se comentó que la herencia múltiple no existe en C Sharp, pero que ésta puede ser simulada al utilizar Interfaces. ¿Por qué se utiliza el término “simular”? , porque una interfaz no hereda datos o métodos miembro a la clase que la implementa, sólo comportamientos; es decir, indica qué, pero no cómo se debe hacer Accelerated C# 2010 2010 describe Trey Nash en su libro Accelerated describe una interfaz como un contrato que nos permite acordar una serie de funcionalidades en una clase, esto porque una interfaz en C Sharp “Contiene s ólo las firmas de los métodos […], la implementación de ellos se hace en la clase que implementa la interfaz” , según se menciona en Microsoft (MSDN, 2013 d), en el apartado “Interface (Referencia de C#) ”.
En otras palabras, una interfaz es una clase especial que sólo indica qué métodos debe tener, pero no dice el cómo debe programarse. Por eso una interfaz sólo tiene la firma de los métodos (es importante recordar que, según se revisó en la Unidad 1, la firma de un método es su alcance, el tipo de datos que devuelve, su nombre y los parámetros que recibe). A continuación continuación se expone expone lo ya mencionado mencionado con el siguiente ejemplo: Recordarás que en el subtema anterior 2.1.3. Clases selladas, se desarrolló una jerarquía de clases Persona-Docente-Jefe. En este caso, se requiere crear la herencia de Alumno Persona. El primero tendrá nombre, sexo y edad, pero se necesitan dos que deriva de Persona. string. Un número de control y una carrera de tipo protegido, métodos adicionales de tipo string. Persona-Alumno genera en la clase Alumno el Alumno el siguiente código: esta nueva relación Persona-Alumno genera
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
27
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Aquí se observa observa la siguiente información: información: 1) El constructor de la clase derivada Alumno llama Alumno llama a su padre con la instrucción base. base. 2) Se está ocultando el método Informacion() Informacion() de la clase padre por un nuevo método, para ello se utiliza la palabra reservada new. new. 3) Se está obligado a darle funcionalidad al método Informacion(), Informacion(), porque en la clase padre está definida como abstracta (con abstracta (con la palabra reservada abstract), abstract), cuya funcionalidad debe ser escrita en la clase hija.
Para crear la herencia de Alumno que deriva de la clase Persona, se supone la existencia de otra también derivada de Persona, llamada Movilidad. Una instancia de Movilidad representará a un alumno con número de control y carrera, pero debe tener también un campo que represente la institución de procedencia (en los institutos tecnológicos la movilidad significa que un alumno puede salir de una institución, tomar una o varias materias en otros tecnológicos y regresar a su institución de origen tantas veces y en instituciones diferentes como él lo desee); por el contrario, un alumno representa a un División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
28
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
individuo que se encuentra en dicha institución. La codificación de esta clase se muestra a continuación:
El programa principal tendrá la siguiente codificación:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
29
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Al ejecutarse ejecutarse se mostrarán mostrarán los siguientes siguientes resultados: resultados: Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Identificación con tarjeta número: 57 Nombre: Ángel Sexo: M Edad: 38 Departamento: Sistemas Nombre: Pedro Sexo: M Edad: 20 N. Control: 01010202 Carrera: Sistemas Nombre: Juan Sexo: M Edad: 23 N. Control: 00040104 Carrera: Electrónica Procedencia de: Veracruz División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
30
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Cuando un alumno ingresa a esa institución existe un convenio importante con él. Puede cambiar en cualquier momento de carrera −esto también es válido con alumnos de movilidad −, pero el proceso es diferente al que se seguiría en el caso de los primeros, quienes al cambiar de carrera sólo deben indicar el interés. En el caso de los segundos, es necesario generar un número de oficio, que debe llevar a la institución de procedencia, con el siguiente formato: ORI-aaaammdd-numerodecontrol; donde el primer segmento debe sustituirse por el año, mes y día, respectivamente. Esta es una situación típica que puede ser representada por una interfaz. Este C onvenio (como se nombrará a esta interfaz) codificado se muestra a continuación:
A continuación continuación se presenta presenta el el problema que se puede puede representar representar en el siguiente siguiente diagrama: Persona <>
Docente
Convenio <>
Alumno
Movilidad
Jefe <
Se puede observar que Alumno y Movilidad necesitan de un tipo de herencia múltiple y que son una Persona, una Persona, de alguna forma, pero ellos dos no son un convenio. un convenio. Convenio sólo indica la forma en que pueden cambiar su carrera, pero no más datos.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
31
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La primera parte de la explicación, acerca de la herencia múltiple, no es posible de resolver “C Sharp no soporta la herencia múltiple” como lo indica Trey Nash en su libro Accelerated Accelerated C# (2010, p. 92): “En C #, una clase sólo puede tener una clase base, para los procesos de herencia ”. Pero C Sharp sí permite que una clase reciba información de una o varias interfaces simultáneamente. Antes de mostrar cómo se codificaría esto, es necesario recordar que no es una herencia de una interfaz porque este tipo de clases sólo indican lo que se debe hacer (convenios o protocolos), pero no dicen cómo se debe hacer.
La primera es una clase (Persona) y se considera herencia; la segunda es una interfaz (Convenio) y no es herencia, sino funcionalidades que deben realizar ambas clases, Alumno y Movilidad. Movilidad. Una clase puede recibir indicaciones de funcionalidad de una o varias interfaces, para esto no existe un límite como en el caso de la herencia simple obligatoria. En el ejemplo planteado se deben agregar dos métodos que describan la funcionalidad de cambio de carrera. En el caso de la clase Alumno el Alumno el método tiene la siguiente codificación:
El método de cambiarCarrera(), de la clase Movilidad, además de tener otra codificación string. necesita agregar un dato privado llamado oficio, de tipo string.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
32
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
informacion() debe agregar el siguiente código: En el caso de Movilidad, el método informacion()
El programa principal quedará así:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
33
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La salida de este código es la siguiente: Nombre: Luisa Sexo: F Edad: 30 Tarjeta: 57 Identificación con tarjeta número: 57 Nombre: Ángel Sexo: M Edad: 38 Departamento: Sistemas Nombre: Pedro Sexo: M Edad: 20 N. Control: 01010202 Carrera: Informática
Nombre: Juan Sexo: M División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
34
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Edad: 23 N. Control: 00040104 Carrera: Mecatrónica Procedencia de: Veracruz Cambio de carrera con el oficio: ORI-2013511-00040104 Para concluir este tema, se recapitulan los siguientes puntos: Las interfaces permiten definir características características de comportamiento o capacidades, que se aplican a las clases sin tener en cuenta su jerarquía. Desde un punto de vista conceptual, “las interfaces son contratos entre dos trozos de código distintos ” (Archer, 2010, p. 151). Así, aunque dos clases implementen la misma interfaz, esto no significa que tenga alguna jerarquía.
Cuando se tiene definida una interfaz y una clase la toma para dar funcionalidad al término correcto en el que la clase implementa la interfaz, aunque algunos autores utilizan como sinónimo la clase heredada de la interfaz, esto conceptualmente no es cierto (Archer, 2010, p. 152). Dado que las interfaces definen un contrato, cualquier clase que implemente una interfaz tiene que definir todos y cada uno de los métodos, de lo contrario el código no se compilará (Archer, 2010, p. 153). En otras palabras, si una interfaz propone cinco métodos, la clase que implemente debe implementar esos cinco métodos o el programa no se ejecutará. Mediante la utilización de interfaces se pueden implementar características característi cas de comportamiento múltiples en una única clase. En C#, una clase puede derivar de una clase única, pero puede implementar tantas interfaces como necesite (Archer, 2010, pp. 155-156).
Ahora que que has concluido concluido el primer primer tema, realiza realiza las actividades actividades de aprendizaje. aprendizaje.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
35
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Actividad 2. Herencia mediante C Sharp El propósito de la actividad es que soluciones un problema en donde sea necesario desarrollar una jerarquía de herencia, y que utilices las instrucciones de C Sharp. Para el desarrollo de la actividad, tu Facilitador(a) te hará llegar un problema respecto a un diseño de herencia, en el cual realizarás los siguientes pasos: Construye una clase abstracta. 1. Construye una Integra un constructor y métodos abstractos. 2. Integra un Construye clases con ciertas características de herencia. 3. Construye clases Otorga funcionalidad. 4. Otorga funcionalidad. Construye la interfaz requerida. 5. Construye la Integra un archivo de texto en el cual muestres las capturas de pantalla de cada 6. Integra un uno de los pasos de este proceso. empaca todo tu proyecto en un archivo .zip; 7. Una vez realizado tu programa, empaca todo incluye el archivo de texto con las capturas de pantalla del procedimiento realizado. 8. Guarda la Guarda la actividad con el nombre DPRN2_U2_A2_XXYZ. Sustituye las XX por las dos primeras letras de tu primer nombre, la Y por tu primer apellido y la Z por tu segundo apellido. 9. Envía el Envía el archivo a tu Facilitador(a) mediante la herramienta Tareas para recibir retroalimentación. *No olvides consultar el documento Criterios de evaluación de las actividades de la Unidad 2 , para conocer los parámetros.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
36
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
2.2. Polimorfismo en C Sharp Como ya se dijo, uno de los pilares fundamentales de la programación orientada a objetos herencia; muchos autores afirman que el segundo es el polimorfismo (Troelsen, polimorfismo (Troelsen, es la herencia; 2010) que, como veremos en este apartado, es en gran parte una consecuencia de la primera. Como introducción al concepto de polimorfismo, se propone analizar el caso de herencia propuesto en el siguiente diagrama, donde se simula la serie de cuentas que existen en un banco. Clase Cuenta <> Métodos <>Deposito() <>Retiro()
Clase DeAhorros
Clase Inversiones
DeAhorros e Inversiones), Inversiones), Esta estructura de herencia es muy fácil de entender. Ambas ( DeAhorros e al heredar de la clase abstracta Cuenta, tienen la obligación de implementar métodos abstractos: Deposito() y Retiro(). No es lo mismos retirar de clase DeAhorros que DeAhorros que de Inversiones. Inversiones. De la primera puede retirarse en cualquier momento, pero de la segunda sólo se puede hacer en ciertos momentos específicos; aunque en ninguna se puede retirar una cantidad mayor al saldo que contengan. Maestra, similar a la Supón que el banco promociona una nueva clase de cuenta llamada Maestra, de ahorros, pero que por proporcionar un mayor interés cobra una pequeña comisión adicional por realizar retiros; los depósitos están condicionados, deben tener un monto mínimo para aceptarlos. De primera instancia es posible proponer la siguiente jerarquía
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
37
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
de herencia, donde se toma como clase base DeAhorros y DeAhorros y de ella deriva Maestra. Maestra. Esto se observa a continuación:
Clase Cuenta <> Métodos <>Deposito() <>Retiro()
Clase DeAhorros
Clase Inversiones
Clase Maestra
De este problema surgen las siguientes consideraciones y una pregunta fundamental: 1) La clase DeAhorro, DeAhorro, al heredar de Cuenta, Cuenta, debe implementar los métodos Deposito() Deposito() y Retiro(), Retiro(), porque no es abstracta, sino una definida. 2) La clase Maestra, Maestra, al heredar de DeAhorro, DeAhorro , recibirá r ecibirá los métodos implementados de Deposito() Deposito() y Retiro(); Retiro(); pero no le sirven por tener condiciones diferentes, por ello deberá cambiarlos. ¿Cómo puede hacerlo? El cambio puede realizarse en función de tres soluciones diferentes:
Ocultar los métodos del padre (esto se revisó en el subtema 2.1.3. 2.1.3. Clases selladas). Al utilizar la palabra reservada new antes new antes de la nueva definición del método, se ocultará el de su padre y quedará en función el método de clase derivada. Al cambiar el tipo de parámetros que reciba el método, la clase derivada tendrá dos métodos: el que hereda de su padre y el suyo propio, un caso de
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
38
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
sobrecarga. En cualquier momento, la clase derivada podrá hacer uso de ambos métodos sólo con cambiar los parámetros con los que se invoque. Al cambiar el tipo de parámetros que reciba el método, la clase derivada tendrá dos métodos: el que hereda de su padre y el suyo propio, lo que también deriva en un caso de polimorfismo.
Según Deitel y Deitel (2007), un método polimórfico o polimorfo se define como una función que tiene la capacidad de responder al mismo nombre con diferente operatividad en función de los parámetros utilizados en su invocación. En la siguiente sección se estudiará el uso del polimorfismo en C Sharp.
2.2.1. Métodos polimórficos La palabra polimórfico proviene del griego poly (πολύς ): ): mucho, numeroso, frecuente; y de morpho ( μορφος ): ): que tiene una forma determinada (Universidad de Salamanca, 2011). Es decir, polimórfico significa que “posee varias formas diferentes ” (Troelsen, 2010, p. 235). Desde el punto de vista de programación, un método polimórfico significa una función que tiene el mismo nombre, pero diferente tipo de parámetros y funcionalidad Este es un concepto fundamental en la programación orientada a objetos, y en general existen tres tipos en C Sharp: De sobrecarga o sobrecarga (Unidad I. Desarrollo de objetos en la plataforma. NET). Paramétrico. De inclusión.
Polimorfismo paramétrico Para entender el polimorfismo paramétrico se explica cómo hacer métodos polimórficos en una clase sin herencia.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
39
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Se requiere desarrollar una clase llamada perímetro, ésta tendrá varios métodos que permitirán calcular el derredor de las siguientes figuras irregulares.
Se conoce:
Se conoce:
Se conoce:
Se conoce:
L1, L2 y L3
L1, L2, L3 y L4
L1, L2, L3, L4 y L5
L1, L2, L3, L4, L5 y L6
Esta clase tendrá cuatro métodos que recibirán:
La primera, tres parámetros de tipo double y double y devolverá el perímetro. La segunda, cuatro parámetros de tipo double y double y devolverá el perímetro; así sucesivamente. double. Todos los resultados regresarán de tipo double. Todos los métodos se llamarán CalculaPerimetro(). CalculaPerimetro ().
La codificación es la siguiente.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
40
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Puede decirse que el método CalculaPerimetro() CalculaPerimetro() es polimórfico paramétrico, porque cambia el número de parámetros, pero conserva la misma firma (nombre calculaPerimetro, calculaPerimetro, nivel de ocultamiento public y public y valor de retorno double) double) (Sharp, 2010). El uso es muy sencillo. Si se desea calcular el perímetro de un triángulo, se llama al método con tres parámetros; si lo que se desea calcular es el perímetro de un pentágono, se envía al mismo método cinco parámetros. Esto puede observarse en el programa principal.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
41
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La ejecución del programa muestra el siguiente resultado: Perímetro de un triángulo: 11.3 Perímetro de un cuadrángulo: 10.6 Perímetro de un pentágono: 18.8 Perímetro de un hexágono: 18.6 El método CalculaPerimetro() CalculaPerimetro() es un método polimórfico porque existen cuatro métodos parecidos y sólo son diferentes en el número de parámetros. El anterior fue un ejemplo de polimorfismo paramétrico A continuación continuación se analiza analiza un problema problema de herencia herencia donde será será posible observar observar la utilidad del polimorfismo paramétrico. Se requiere crear una clase llamada: EcuacionLineal, EcuacionLineal, que permitirá calcular la expresión: y=ax+b
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
42
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Tendrá un método llamado evalua(), evalua(), que recibirá como parámetro “a” , “b” y “x”, y regresará el valor de “y” . El código se muestra a continuación:
EcuacionCuadratica, con el método evalua(), evalua(), que Se definirá una nueva clase llamada, EcuacionCuadratica, recibirá como parámetros “a” , “b”, “c” y “x”, y devolverá el valor de “y” , según la siguiente relación: y = a x2 + b x + c Esta clase será derivada de la anterior. Finalmente, se creará una clase llamada EvaluaEcuaciones que EvaluaEcuaciones que heredará las anteriores y permitirá evaluar ecuaciones cuadráticas y lineales. Esto puede observarse en el siguiente diagrama de herencia:
Clase EcuacionLineal
Clase EcuacionCuadratica
Clase EvaluaEcuaciones
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
43
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
EcuacionCuadratica se muestra a continuación:
EvaluaEcuaciones tendrá la siguiente definición:
Se obtiene una clase que permitirá evaluar las siguientes expresiones:
y=3x+5
Para x=3
y = 4 x2 – 4 x + 3
Para x=3.3
El programa principal tiene la siguiente definición:
Al ejecutar ejecutar el programa programa se mostrará mostrará la siguiente siguiente salida:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
44
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Ec. Lineal: y=14 Ec. Cuadrática: y=33.36 Como pudo observarse, la clase EvaluaEcuaciones tiene EvaluaEcuaciones tiene dos métodos polimórficos por herencia; éste es uno de los usos del polimorfismo. Cuando polimorfismo. Cuando una clase hereda de otra y tienen los mismos métodos, pero sus parámetros son diferentes en número, lo que hace la clase derivada es acumular los métodos. Para concluir, es necesario recordarlos siguientes puntos: 1) Un método está sobrecargado cuando tiene el mismo número de parámetros, pero de diferente tipo. 2) Un método es polimórfico cuando tiene diferente número de parámetros sin importar si son del mismo o de diferente tipo. En ambos casos los métodos deben tener el mismo nombre, sin importar el tipo de información que devuelven. Polimorfismo de inclusión Según el MSDN (2013 i), “A través de la herencia , una clase puede utilizarse como su propio tipo o como cualquier tipo de una clase padre” . Cuando un objeto se utiliza como un tipo que no es ella misma sino de una clase padre, se tiene un polimorfismo a nivel clase. Este concepto será más fácil de entender con el ejemplo que se expone a continuación. Una clase abstracta, llamada abstracta, llamada Figura, tendrá Figura, tendrá dos métodos miembro, Perimetro() Perimetro() y Area(), Area(), ambos abstractos. Esta clase tendrá un constructor que recibirá un valor de tipo doble y lo guardará en un dato miembro protegido. Se heredará a una clase hija llamada Circulo, Circulo, que recibirá en su constructor el radio e implementará los métodos: Perimetro() Perimetro() Area(), que calcularán el perímetro y el área del círculo. El diagrama de herencia se y Area(), observa a continuación. <> Figura
Clase Circulo
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
45
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
La implementación de la clase abstracta puede observarse a continuación:
La clase derivada círculo será definida así.
Se observa un ejemplo de polimorfismo, a nivel objeto, en el programa principal: División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
46
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Si se ejecuta el programa la salida será la siguiente: 28.2744 63.6174 Lo anterior es un ejemplo de polimorfismo a nivel objeto (también llamado de inclusión, redefinición o subtipado) (Troelsen, 2010). Es posible hacer polimorfismo a nivel objeto desde cualquier nivel de herencia. Por ejemplo, si se cuenta con la siguiente jerarquía. Clase Persona
Clase Docente
Es válido hacer lo siguiente: Persona p = new Docente(); Docente(); Persona presenta Persona presenta polimorfismo a nivel objeto como la clase Docente. Docente. Y si se solicitan, los Docente. métodos que se pueden utilizar en la instancia p, serán los métodos de Docente. Lo contrario no es válido. División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
47
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Docente d = new Persona(); Este tipo de polimorfismo no puede realizarse, no está permitido en C Sharp ni en otros lenguajes como Java. ¿Cuál es su uso? Son dos, principalmente: 1) Es posible instanciar clases abstractas (las cuales se caracterizan por no ser instanciada), de esta manera se logra un mayor grado de generalización. En el último ejemplo se utiliza una Figura que se comporta como un círculo. 2) Es posible utilizar métodos que apliquen objetos polimórficos para que las funciones sean lo más genéricas posibles. Esto se explicará en el siguiente subtema.
2.2.2. Métodos genéricos El mayor grado de polimorfismo se logra con los métodos genéricos (la máxima representación del polimorfismo para un lenguaje orientado a objetos), porque representan el nombre de una función y un grupo de parámetros de los que no se conoce el tipo. Un método genérico se declara con parámetros de tipo en lugar de los primitivos (int, float, char, etcétera) u objetos (MSDN, 2013 f). Pero ¿qué es un parámetro de tipo? Esto se explica con el siguiente ejemplo. Este es un método definido de manera tradicional:
Se observa que sus parámetros son dos variables de tipo primitivo int, int, los cuales se utilizan como parte de los procesos dentro del método. Un parámetro tipo es tipo es un símbolo que se puede definir y utilizar como una variable, y adquiere su valor definitivo en el momento en que se utiliza el método, tal como se
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
48
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
muestra en el siguiente ejemplo. Una clase, llamada ClaseGenerica, ClaseGenerica, recibe dos parámetros mediante un método, los guarda en la clase y muestra el par de parámetros recibidos. Tal como se ilustra a continuación:
Al inicio de de la clase se observa la definición , en en la que se muestra que se utilizarán dos parámetros tipo; son genéricos porque pueden ser cualquier tipo que se necesiten en el momento de la implementación. A lo largo de todo el código se utilizaron estos parámetros. En el siguiente ejemplo se requiere guardar un par de datos formado por un número entero y un nombre de persona; lo cual se logra de la siguiente manera:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
49
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Si se ejecuta el programa, la salida será la siguiente: (1, MANUEL) En el momento de la instanciación se utiliza la definición , string>, donde se indica el tipo de valor que se necesita. Ahora se integrará un nuevo uso pero formado por dos datos string, string, para guardar el nombre y apellido. Esto se definirá de la siguiente manera:
Si se ejecuta esta nueva versión la salida será la siguiente: (JUAN,LOPEZ). Como puede observarse, sólo se cambia la definición del tipo al momento de instanciarse . string>. Se logró una clase sobrecargada de forma infinita, la clase, en este caso
Actividad 3. Métodos polimórficos Esta actividad tiene como propósito que identifiques los usos de polimorfismo de métodos mediante ejemplos de uso. La actividad es colaborativa, por lo que tu Facilitador(a) te asignará un número de equipo para trabajar.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
50
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Realiza las siguientes actividades junto con tu equipo de trabajo: 1. Menciona un Menciona un mínimo de tres ejemplos donde sean de utilidad los métodos polimórficos. Recurre a Recurre a problemas que se hayan presentado en alguna de tus asignaturas anteriores, problemas que observes en observes en aplicaciones reales o algunos que tú propongas, en propongas, en los cuales pueda plantearse un polimorfismo como solución. Para el desarrollo de este paso es necesario que se establezca comunicación a través del Foro general de la asignatura , donde tu Facilitador(a) te hará llegar las indicaciones necesarias sobre el trabajo, conformarás el equipo y llegarás a acuerdos con tus compañeros(as). 2. Consulta la Consulta la Rúbrica de participación en foros , que se encuentra disponible en la sección Material de apoyo. Al ingresar al al foro: 3. Comenta de Comenta de manera individual un ejemplo que hayan investigado al interior del equipo. 4. El representante del equipo deberá ingresar al al foro pata compartir la la justificación y el ejemplo ejemplo que, consideren, consideren, aporta mayores mayores elementos elementos sobre el tema de polimorfismo y la solución de problemas. 5. Una vez que compartan su aportación, revisa y revisa y comenta la comenta la participación de al menos dos compañeros(as), la pertinencia de los ejemplos expuestos, tus propias experiencias, conocimiento y la aportación que te dejan las participaciones en el foro. elabora conclusiones 6. Con base en las aportaciones de tus compañeros(as), elabora conclusiones deja tu evidencia en el foro. individuales y deja tu *No olvides, consultar el documento Criterios de evaluación de las actividades de la Unidad 2, para conocer los parámetros.
2.3. Sobreescritura en C Sharp
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
51
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
En este tema se revisará el concepto de sobreescritura. Se dice que una clase hija sobreescribe un método de la clase padre cuando lo define con las mismas características (nombre, número y tipo de argumentos) que el de la superclase. En ese caso, el método al que se tiene acceso es al último, el que redefinió al primero. Para decirlo de una forma simple, “una sobreescritura es la capacidad que tienen las clases derivadas para cambiar la funcionalidad que han heredado de sus clases padre, mediante la modificación del código que tiene en su definición ” (Griffiths, 2010, p. 112) (. Existen dos formas de realizar una sobreescritura en C Sharp: mediante los indicadores virtual y virtual y override. override. En ambos casos, la idea es cambiar la funcionalidad de un método previamente escrito dentro de una clase padre. La sobreescritura, junto con la característica de polimorfismo, son dos herramientas que permiten ajustar los objetos para que representen de una manera más fiel el mundo real.
2.3.1. Modificador virtual Como se recordará, la herencia permite definir métodos que serán enviados a las clases virtual, además de derivadas. Lo que ahora se explicará es que mediante el modificador virtual, definir los métodos que se enviarán a las clases derivadas, es posible cambiar dicha definición en la clase hija; para ello, la definición de dicho método en la clase padre virtual. Este tipo de métodos se llama necesita estar precedida con la palabra reservada virtual. virtual, virtual, y Microsoft lo define como: “La palabra clave virtual se virtual se utiliza para modificar un método y permite reemplazar a cualquiera de estos en una clase derivada ” (MSDN, 2013 g). Según el MSDN (2013 g), la sintaxis que se usa para definirlos es la siguiente: virtual virtual () { } virtual, también se asumen varios conceptos Cuando se define un método como virtual, importantes: 1) El método debe ser modificado por cualquier clase que lo herede. No puede ser tomado tal y como se declara.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
52
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
2) Se controla la reutilización, se limita lo que se desea y lo que no debe ser modificado.
2.3.2. Modificador override virtual, visto en el tema anterior, trabaja a la par con el modificador El modificador virtual, override. override. De esta manera, es posible decir qué métodos pueden ser sobreescritos y cuál es el código con el que se sobreescriben. código> del método, Si en alguna clase hija se requiere dar una nueva definición del < código> virtual por simplemente se volvería a definir, pero sustituyendo la palabra reservada virtual por override. override. Es decir, se utilizaría la siguiente sintaxis (MSDN, 2013 h): override override () { } Es importante reafirmar que sólo puede cambiarse el código de un método en su clase virtual. En caso contrario, el hija si en la clase padre el método fue definido como virtual. compilador mostrará un error al intentar redefinirlo. override. En el siguiente ejemplo se observará el uso del modificador override. Dimensiones se definirá una constante PI, que contendrá el valor En una clase llamada Dimensiones se de 3.1416 y dos variables protegidas de tipo doublé, “x” y “y”. Esta clase tendrá un virtual que devuelva un valor double llamado double llamado Area(), Area(), que calculará el área de un método virtual que cuadrado.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
53
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Se crea una clase llamada Círculo que hereda de hereda de dimensiones y sobreescribe el sobreescribe el método Área de la clase dimensiones. dimensiones. Este código se muestra a continuación:
Se crea una clase llamada Esfera que Esfera que hereda dimensiones y sobreescribe el método Área de la clase dimensiones. dimensiones. Este código se puede analizar a continuación:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
54
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Cilindro que herede de dimensiones y sobreescriba el método Se crea una clase llamada Cilindro que virtual Área de la clase dimensiones. dimensiones. El código es el siguiente:
virtuales: El programa principal muestra el uso de las clases virtuales:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
55
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Cuando el programa se ejecuta muestra los siguientes resultados: Área de un rectángulo: rectángulo: 12.88 Área de un círculo: 36.316896 36.316896 Área de una una esfera: esfera: 98.520576 98.520576 Área de un cilindro: 277.9687 277.968768 68 virtual se ha redefinido por cada una de las derivadas. Como puede observarse, la clase virtual se En conclusión puede decirse que la sobreescritura, en la programación orientada a objetos, es una de las mejores formas de reutilización de código. Desde el inicio de esta unidad se ha comentado que esta metodología de desarrollo de programas se enfoca en la reutilización de lo ya realizado en materia de programación. Antes de esta propuesta, la única solución era que cada programador reescribiera lo que otros habían realizado. Con esta técnica es posible utilizar de manera completa o parcial (incluso reescribir desde cero) lo ya realizado por otras clases; todo depende de lo solicitado en el desarrollo de software y la experiencia del programador.
Autoevaluación Antes de desarrollar la evidencia evidencia de aprendizaje, aprendizaje, realiza realiza la autoevalua autoevaluación ción con el fin de realizar un repaso general de la unidad; así como detectar aquellos temas que no has
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
56
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
comprendido en su totalidad y que requieras revisar nuevamente, o bien consultar con tus compañeros(as) y Facilitador(a). Para realizar la Autoevaluación, ingresa al listado de actividades en el aula.
Evidencia de aprendizaje. Herencia simple, polimorfismo y sobreescritura El propósito de la actividad es que soluciones un problema donde sea necesario desarrollar clases con métodos virtuales, sobreescritura y sobreescritura y las instrucciones de C Sharp. Para el desarrollo de la actividad tu Facilitador(a) te hará llegar un problema respecto a un diseño de herencia en el cual realizarás los siguientes pasos: 1. Construye una Construye una clase abstracta. 2. Integra un Integra un constructor. 3. Integra métodos Integra métodos virtuales. virtuales. 4. Construye clases Construye clases con ciertas características de herencia. 5. Agrega una Agrega una clase que herede de la clase abstracta. 6. Integra métodos Integra métodos polimórficos Otorga funcionalidad según las especificaciones que te indique tu Facilitador(a). 7. Otorga funcionalidad Integra un archivo de texto en el cual muestres las capturas de pantalla de cada 8. Integra un uno de los pasos de este proceso. 9. Una vez realizado el programa, empaca todo empaca todo el proyecto en un archivo .zip; incluye el archivo de texto con las capturas de pantalla del procedimiento realizado. Guarda la actividad con el nombre DPRN2_U2_EA_XXYZ. Sustituye las XX por 10. Guarda la las dos primeras letras de tu primer nombre, la Y por tu primer apellido y la Z por tu segundo apellido. División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
57
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
11. Envía el Envía el archivo a tu Facilitador(a) para recibir retroalimentación. *No olvides, consultar el documento Criterios de evaluación de las actividades de la Unidad 2 para para conocer los parámetros de esta actividad.
Cierre de la unidad En esta unidad se muestra la aplicación de conceptos tales como herencia, polimorfismo y sobreescritura en lenguaje C Sharp. La herencia es uno de los pilares de la programación orientada a objetos, porque permite la reutilización del código y la generación de clases derivadas más especializadas. En una relación de herencia el primer elemento se llama clase padre o base; el segundo, clase hija o derivada; este último puede usar los métodos, propiedades y variables de la primera. También es capaz de modificar los métodos y crear así un nuevo comportamiento. El polimorfismo significa que conviven varios métodos con el mismo nombre, pero con comportamientos diferentes, lo que permite crear distintas funcionalidades. La sobreescritura es consecuencia de la herencia. Una clase hija puede reescribir, recodificar, los métodos heredados, darles una funcionalidad diferente para lo que fueron definidos. En esta unidad se han revisado conceptos que permiten otorgar mayor funcionalidad a los programas que realizarás en otras materias y, en un futuro próximo, en la industria. Otros temas más complejos de la programación orientada a objetos se revisarán en la Unidad 3. Manipulación de errores y conjuntos de objetos.
Para saber más En esta sección encontrarás algunos recursos que es recomendable consultes, pues ofrecen más información acerca de los principales conceptos revisados, tales como herencia, polimorfismo, interfaces, sobreescritura:
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
58
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
MSDN. Microsoft Developer Network. (2013). Herencia (Guía de programación de C#).Recuperado de http://msdn.microsoft.com/eses/library/ms173149(v=vs.80).aspx MSDN. Microsoft Developer Network. (2013). Clases y miembros de clase abstractos y sellados (Guía de programación de C#) . Recuperado de http://msdn.microsoft.com/es-es/library/ms173150(v=vs.80).aspx En el portal oficial de C Sharp en español de Microsoft encontrarás la explicación de los conceptos de herencia, polimorfismo e interfaces con varios ejemplos. La página está en inglés, pero puedes apoyarte en alguna de las diversas herramientas de traducción para acceder a la información y observar los videos. Fue desarrollada para la versión de C Sharp 2005, pero es válida para cualquier versión desde 2008 hasta 2010. El enlace es http://msdn.microsoft.com/enus/vstudio//bb798022.aspx El libro de José Antonio González Seco, El lenguaje de programación C# , es un desarrollo libre. Aunque es una versión muy anterior, los conceptos fundamentales no han cambiado. Se encuentra disponible en la sección Material de apoyo y también lo puedes obtener de http://dis.um.es/~bmoros/privado/bibliografia/LibroC Sharp.pdf
Fuentes de consulta
fondo C# , 2010 . Madrid: McGraw-Hill. Archer, T. (2010). A fondo
Deitel, H. y Deitel, P. (2007). Cómo programar en C Sharp , 2a. ed. Madrid: Pearson.
Ferguson J., Patterson B. y Beres J. (2005). La biblia de C Sharp . Madrid: Anaya.
Griffiths, Ian; Adams, Matthew & Liberty, Jesse (2010). Programming C# 4.0. Editorial O’Reilly, Estados Unidos
González J. (2004). Lenguaje de programación en C# . Recuperado de http://dis.um.es/~bmoros/privado/bibliografia/LibroC Sharp.pdf
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
59
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Michaells, M. (2010). Essential C# 4 .0 . Estados Unidos: Addison Wesley. Microsoft Corporation. (1999-2007), C# Language Specification Version 3 .0 , /C Recuperado de d ownload .m i c r o s o f t .com/ ... ... /C Sharp%20Language%20Specification .doc MSDN. Microsoft Developer Network (2013 a). Clases selladas. Recuperado de http://msdn.microsoft.com/es-MX/library/aa645616%28v=vs.71%29.aspx MSDN. Microsoft Developer Network (2013 b). Clases y miembros de clase abstractos y sellados (Guía de programación de C #). Recuperado de http://msdn.microsoft.com/es-es/library/ms173150%28v=VS.80%29.aspx MSDN. Microsoft Developer Network (2013c). Herencia y clases derivadas (C# y Java). Recuperado de http://msdn.microsoft.com/eses/library/ms228387%28v=VS.80%29.aspx
__________________________________d. Interface (Referencia de C#) . Recuperado de http://msdn.microsoft.com/eses/library/87d83y5b%28v=VS.80%29.aspx
__________________________________e. Métodos abstractos . Recuperado de http://msdn.microsoft.com/es-es/library/aa664435%28v=VS.71%29.aspx
__________________________________f. Métodos genéricos (Guía de programación programación de C#). Recuperado de http://msdn.microsoft.com/eses/library/twcad0zb(v=vs.80).aspx
__________________________________g. Virtual (Referencia de C#) . Recuperado de http://msdn.microsoft.com/esMX/library/9fkccyh4%28v=vs.80%29.aspx __________________________________h. Override (Referencia de C#) Recuperado de http://msdn.microsoft.com/es-es/library/ebca9ah3(v=vs.80).aspx
__________________________________i. Polimorfismo en C# http://msdn.microsoft.com/es-es/library/ebca9ah3(v=vs.80).aspx
Accelerated C# 2010 2010 . Estados Unidos de América: Apress. Nash, T. (2010). Accelerated
Sharp, John. (2010). Microsoft Visual C# 2010 . Estados Unidos: Microsoft Press.
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
60
Programación .NET II Unidad 2. Herencia y polilmorfismo en el lenguaje de programación CSharp
Troelsen, A. (2010). Pro C# 2010 and the .NET 4 Platform. Estados Unidos: Apress. Universidad de Salamanca (2011). Diccionario médico-biológico , histórico y etimológico. Recuperado de: http://dicciomed.eusal.es/palabra/polimorfismo
División de Ciencias Exactas, Ingeniería y Tecnología | Ingeniería en Desarrollo de Software
61