Este documento describe los mecanismos de herencia y polimorfismo en C++ que facilitan la reutilización y abstracción de código. La herencia permite que las clases hijas hereden funciones y datos de las clases padre, mientras que el polimorfismo permite que los objetos tomen diferentes formas. Las funciones virtuales son necesarias para lograr polimorfismo al permitir que se invoquen métodos específicos de una clase hija a través de una referencia de la clase base.
Buenas prácticas para la construcción de softwareIker Canarias
Esta presentación sobre "buenas prácticas en la construcción de software" se basa principalmente en los "Principios de buena programación" de Christopher Diggins. Consejos generales sobre buenas prácticas, pero centrados en Java al final de la presentación.
Buenas prácticas para la construcción de softwareIker Canarias
Esta presentación sobre "buenas prácticas en la construcción de software" se basa principalmente en los "Principios de buena programación" de Christopher Diggins. Consejos generales sobre buenas prácticas, pero centrados en Java al final de la presentación.
1. Mecanismos para la Reutilización
y Abstracción del Código -1a
parte
Apoyo SSD5
2. Objetivo
• Este módulo del curso presenta los
mecanismos disponibles que facilitan la
reutilización y abstracción del código en
el lenguaje C++.
Mtl Lourdes Cahuich 2
4. Un Mecanismo para la Abstracción y Reutilización
del Código
• La herencia es un mecanismo en C++
(así como en Java) que facilita la
reutilización y abstracción del código.
Mtl Lourdes Cahuich 4
5. Herencia
• Al usar la herencia, se pueden construir
clases nuevas basadas en clases viejas,
permitiendo que las clases hijo
compartan las funciones y datos
miembro de la clase padre.
• A través de estas relaciones surgen las
ventajas de la abstracción de datos
(generalización y especialización).
Mtl Lourdes Cahuich 5
6. Herencia
• En C++, una clase hijo hereda a todos
los miembros no-privados de los datos
incluyendo constructores.
• Una clase hijo en Java sin embargo,
hereda de su clase padre a todos los
miembros no-privados de los datos
excepto constructores.
Mtl Lourdes Cahuich 6
7. Herencia
• En ambos lenguajes, las clases hijo
heredan todos los miembros no-
privados de los datos
Mtl Lourdes Cahuich 7
9. Herencia
• El listado anterior es un ejemplo de la
herencia en C++ que demuestra como
invocar métodos de una clase padre.
• En este listado, hemos definido una
clase SavingsAccount que hereda de
la clase BankAccount.
Mtl Lourdes Cahuich 9
10. Herencia
• La clase SavingsAccount provee una
manera de añadir interés al dinero
presentado en una cuenta
• La línea 23 invoca al constructor de la
clase padre
• En C++ se usa el nombre de la clase
padre seguida por los parámetros del
constructor en paréntesis
Mtl Lourdes Cahuich 10
11. Niveles de herencia
• C++ tiene tres tipos, o niveles, de
herencia: pública, privada y protegida.
• La herencia pública es el tipo más
común de herencia usado en C++.
• Todos los ejemplos que hemos visto
hasta el momento usan la herencia
pública para modelar la relación quot;es
un...quot; de dos clases.
Mtl Lourdes Cahuich 11
12. Niveles de herencia
• Las herencias privadas y protegidas
modelan un tipo diferente de relación,
llamada relación quot;usa un...quot;.
• Para modelar que un carro usa un
motor, podríamos heredar
privadamente de la clase Engine al
definir la clase Car.
Mtl Lourdes Cahuich 12
13. Niveles de herencia
• La forma más apropiada de modelar
esta relación, sería que nuestra clase
Car contenga una instancia de la clase
Engine
• Modelar la relación quot;usa un...quot; de esta
forma, es conocido como composición.
• Todos los usos de herencia en este
curso se enfocan en las relaciones de
modelación quot;es un...quot;.
Mtl Lourdes Cahuich 13
15. Un Mecanismo para Abstracción
• Una característica fundamental de los
lenguajes de programación orientados a
objetos es el polimorfismo.
• Polimorfismo es la capacidad de un
objeto de tomar diversas formas
Mtl Lourdes Cahuich 15
16. Polimorfismo
• En otras palabras, el polimorfismo
permite que un programador se refiera
a un objeto de una clase como un
objeto de otra clase
• Esto tiene dos aplicaciones principales.
• Primero, podemos crear colecciones de
objetos heterogéneos
Mtl Lourdes Cahuich 16
17. Polimorfismo
• Podemos operar en los objetos
individuales de estas colecciones como
si fueran todos del mismo tipo, sin que
los objetos pierdan sus identidades
reales
• En segundo lugar, podemos codificar
algoritmos que hacen solamente
suposiciones mínimas sobre los objetos
que manipulan
Mtl Lourdes Cahuich 17
18. Polimorfismo
• Esto puede permitir que un algoritmo
continúe funcionando correctamente
aún cuando un programador introduce
nuevas clases hijo en el sistema.
• Ambas aplicaciones ayudan a crear
soluciones más duraderas
Mtl Lourdes Cahuich 18
19. Polimorfismo en C++
• Los programadores se pueden referir a
objetos de una manera que facilite
soluciones elegantes
• En C++, utilizamos funciones virtuales
en conjunto con los apuntadores para
tener acceso a objetos polimórficos
Mtl Lourdes Cahuich 19
20. Funciones virtuales
• Para ilustrar que funciones virtuales son
y por que requerimos el uso de
apuntadores en conjunto, veamos un
ejemplo completo.
• Asume que deseamos implantar un
sistema de gráficas que pueda
desplegar varias formas geométricas en
pantalla.
Mtl Lourdes Cahuich 20
21. Funciones virtuales
• Es normal empezar con una jerarquía
pequeña de gráficas de objetos.
class Shape { /* ... */ };
class Circle: public Shape { /* ... */ };
class Rectangle: public Shape { /* ... */ };
Mtl Lourdes Cahuich 21
22. Funciones virtuales
• Supongamos que debemos tener la
capacidad de mantener un registro de
una colección de esa forma de objetos.
• Suponga que deseamos mantener un
arreglo de formas de cualquier tipo.
• Podríamos intentar un arreglo del tipo
Shape
Mtl Lourdes Cahuich 22
23. Funciones virtuales
• Esto es razonable, puesto que es legítimo
hacer una asignación de una clase hija a una
variable de la clase base.
Circle C(3); // radius 3
Shape S[10];
S[0] = C; // syntactically correct, but ...
Mtl Lourdes Cahuich 23
24. Funciones virtuales
• Desafortunadamente, las partes
adicionales de la clase hija son
simplemente quot;desnudadasquot; durante la
tarea.
• Esto se conoce como el problema de las
rebanadas o slicing problem.
• Perdemos a todos los miembros
adicionales de los datos de la clase hija.
Mtl Lourdes Cahuich 24
25. Funciones virtuales
• El rebanar, sin embargo, no ocurre
cuando tratamos con los apuntadores.
• Por lo tanto, podemos salvar nuestro
proyecto usando un arreglo de
apuntadores a las formas.
Mtl Lourdes Cahuich 25
27. Funciones virtuales
• En seguida, necesitamos la clase
Circle y Rectangle para reemplazar
el método heredado del area()para
proporcionar los detalles específicos
sobre como calcular sus áreas
respectivas.
• Una vez hecho esto, podemos intentar
lo siguiente.
Mtl Lourdes Cahuich 27
29. Funciones virtuales
• El problema es que el tipo estático de
layout[0] es Shape* y, por lo tanto,
el método area() que pertenece a la
clase Shape se invoca, en lugar del
método específico area() para cada
uno de esos objetos del arreglo
Mtl Lourdes Cahuich 29
30. Funciones virtuales
• Lo que necesitamos es un mecanismo
que revise el tipo dinámico de
layout[0], por ejemplo, determina que
es Circle*, y después llama al método
del area() de la clase Circle.
• Esto se logra en C++ usando funciones
virtuales
Mtl Lourdes Cahuich 30
31. • La redefinición apropiada de la clase
Shape, particularmente su método
area().
• El método area() en las clases hijas
no necesita ser redefinido (aunque es
bien visto asociar la palabra reservada
virtual a esos métodos).
Mtl Lourdes Cahuich 31
33. Funciones virtuales
• Asumiendo que Circle y Rectangle
provean su propio método area()
reemplazando el que está en Shape,
obtenemos la salida correcta.
cout << layout[0]->area() << endl;
// prints 28.2743
cout << layout[1]->area() << endl;
// prints 8
Mtl Lourdes Cahuich 33
34. Funciones virtuales puras
• También pudimos modificar Shape
haciendo area()no sólo virtual sino
también indefinida totalmente.
• Una función de este tipo es llamada una
función virtual pura.
Mtl Lourdes Cahuich 34
36. Clase abstracta
• Una clase que contiene una función
virtual pura se conoce como clase
abstracta. Implantaciones en C++
solamente usan clases abstractas en
conjunto con herencia.
• En otras palabras, los programadores
nunca crean instancias de clases
abstractas.
Mtl Lourdes Cahuich 36
37. Clase abstracta
• Existen simplemente para especificar la
interfaz común de las clases hijas y
para tener acceso a estas clases hijas
polimórficas.
• En resumen, para obtener un
comportamiento polimórfico,
necesitamos:
– usar apuntadores en lugar de objetos
directos debido al rebanado
– declarar funciones miembro virtuales
Mtl Lourdes Cahuich 37