Herencia y polimorfismo

En este capítulo se construirá parcialmente una jerarquía de preguntas para un juego de trivia, las cuales se muestra en el siguiente diagrama:

Diagrama UML con una jerarquía de diversos tipos de preguntas para un juego de Trivia

Herencia

El siguiente código muestra la clase base Pregunta y la clase hija PreguntaSeleccionUnica. Ambas son capaces de cargarse de un archivo de texto.

]]>
Archivo de texto con preguntas de seleccion unica
]]>
]]>
]]>
]]>
]]>
Programa que carga preguntas de selección única de un archivo de texto. Las preguntas utilizan herencia. Obtener código fuente.

Polimorfismo

La función main() en la sección anterior contenía un arreglo que únicamente podía tener preguntas de selección única. Pero lo esperable es que las preguntas sean de diferente naturaleza. Para poder mantener en un contenedor objetos de distinta clase, se debe utilizar herencia. El contenedor tendría punteros o referencias a la clase base. Con estos punteros o referencias, sólo se puede acceder a la parte "base" de cada objeto. El polimorfismo es una funcionalidad provista por los compiladores de C++ para hacer que un método, al ser invocado con un puntero o referencia a la clase base, se invoque la versión de la clase hija (con la que fue construida el objeto) y no con la clase base. Los métodos que tienen este comportamiento se llaman métodos virtuales y C++ crea tablas de punteros a funciones virtuales (vtable) para implementar este mecanismo.

Los siguientes listados agregan la clase PreguntaAbierta a la jerarquía y modifican el método imprimir() para que sea virtual. Si se retira el comentario del método virtual puro aplicar(), la clase Pregunta se convierte en abstracta. Este método será necesario para aplicar una pregunta al jugador.

]]>
Archivo de texto con preguntas abiertas y de selección única
]]>
]]>
]]>
]]>
]]>
]]>
]]>
Introducción de polimorfismo en la jerarquía de preguntas. Obtener código fuente.

Si se hace el método leer() virtual en la clase Pregunta, se puede simplificar ligeramente la creación de objetos pregunta en el main(). Una función crearPregunta() se encarga de crear un objeto Pregunta de acuerdo al tipo encontrado en el archivo de texto. Esta función libre lleva sobre sí la parte menos polimórfica del programa. En caso de agregarse una nueva pregunta, se debe modificar crearPregunta() para considerar el nuevo tipo. El resto del programa debería mantenerse inalterado.

]]>
]]>
]]>
]]>
]]>
]]>
]]>
La lectura de las preguntas se puede hacer también polimórifica. Obtener código fuente.

Ejemplo: Población universitaria

Ejemplo de una jerarquía de personas que conforman la población universitaria:

]]>
]]>
]]>
]]>
]]>
]]>
]]>
]]>
Jerarquía de clases que representan los roles de las personas involucradas con una universidad. Obtener código fuente.