Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CARRERA DE COMPUTACIÓN
PROGRAMACIÓN ORIENTADA A OBJETOS
PRACTICA 03: HERENCIA Y POLIMORFISMO
Marco Teórico
La herencia implica una relación de generalización/especialización en la que, una clase derivada
especializa el comportamiento o estructura más general de sus clases bases, Las clases bases
representan abstracciones generalizadas y, las clases derivadas representan especializaciones en
las que, los datos y funciones miembros de la clase base, sufren añadidos, modificaciones o
incluso ocultaciones, Sin herencia cada clase sería una unidad independiente, desarrollada
partiendo de cero; las distintas clases no guardarían relación entre sí.
Polimorfismo. - Mediante el polimorfismo, un nombre (tal como la declaración de una variable)
puede denotar objetos de muchas clases diferentes, relacionadas por una clase base común;
cualquier objeto denotado por este nombre es, por tanto, capaz de responder a algún conjunto
común de operaciones de distintas formas, Existe polimorfismo cuando interactúan la herencia y
el enlace dinámico, Las funciones virtuales no pueden declararse static puesto que, carecen del
puntero this y, las funciones virtuales lo necesitan para la mecánica de su funcionamiento.
ACTIVIDADES PARA DESARROLLAR:
PARTE A
Consulta
1.
Realizar una consulta sobre los siguientes conceptos del lenguaje C++. Para
cada concepto, colocar una definición en sus propias palabras y un ejemplo
simple que muestre su funcionamiento.
• Funciones virtuales
• Funciones friend.
• Objetos dinámicos. Utilización de la palabra reservada new.
•
FUNCIONES VIRTUALES
Como podemos ver las diferentes funciones virtuales son estas las cuales deben
declararse respectivamente en la clase la cual tendrá mayor jerarquía llamándola así
“Clase Base”, debemos iniciar estas funciones con la palabra virtual luego vendrá la
declaración la cual será ordinaria de la función. Como sabemos todas estas funciones
pueden parafrasear dentro de algunas clases las cuales son derivadas y así podemos
actuar polimórficamente correspondiendo la clase.
FUNCIONES FRIEND:
Podemos ver que las funciones “friend” son estas las cuales no tienen que pertenecer a
ninguna clase, sin embargo, obligatoriamente pueden acceder automáticamente a los
miembros privados y protegidos de la clase la cual será el objetivo.
Podemos tener en cuenta que la declaración de dicha función se debe hacer dentro de
una clase en la cual quiere acceder a los miembros privados y también los protegidos de
otra clase.
OBJETOS DINÁMICOS:
Utilización de la palabra reservada (New): El operador reservado llamado “new” es
aquello que designe un espacio el cual será de una memoria dinámicamente a los
objetos y arreglos, podemos ver que el nuevo espacio el cual es asignado y exacto según
el tipo de valor el cual será declarado de una forma (entero, flotante, arreglo, etc.) y así
el tipo de arreglo a declarar, para poder acceder a este nuevo espacio de
almacenamiento se podrá utilizar un puntero el cual devuelve a la dirección llamada
“new”
#include "Persona.h"
string Persona::informacion()
{
return "Nombre: " + nombre + "\nEdad: " + to_string(edad);
}
“Headers”
(Persona.h)
#ifndef HERENCIA_H
#define HERENCIA_H
#include <string>
class Persona
{
private:
string nombre;
int edad;
public:
Persona(string nombre, int edad);
string informacion();
};
#endif // HERENCIA_H
A primera vista las clases “Profesor.h” y “Estudiante.h” los cuales son las clases de las
clases ya mencionadas ya que heredan varios atributos y de igual manera las funciones,
aunque estas clases denominadas “Hijas” se diferencian de igual manera por la
implementación de la librería la cual será la llamada (“#include “Persona.h”), es de esta
manera que el nuevo atributo en cada clase hija, por parte de “Profesor.h” este llamado
salario y por parte de “Estudiante.h” están los llamados “créditos” es de esta manera que
las nuevas funciones las cuales llamen a los atributos los cuales serán heredados y estos
pertenecerán al nuevo atributo, de esta manera sobrescribiéndose a una función de cada
clase.
En la parte del código secundario las clases de las partes las cuales fueron separados en
3 documentos diferentes donde podemos ver que la clase principal llamada “Persona.h”
es la cual por obvias razones tendrá atributos (nombre y edad), además de las funciones
que llamaran a estos ya mencionados atributos.
“Headers”
(profesor.h)
#ifndef PROFESOR_H
#define PROFESOR_H
#include "Persona.h"
public:
Profesor(string nombre, int edad, double salario);
string informacion();
};
#endif // PROFESOR_H
(estudiante.h)
#ifndef ESTUDIANTE_H
#define ESTUDIANTE_H
#include "Persona.h"
public:
Estudiante(string nombre, int edad, int creditos);
string informacion();
};
#endif // ESTUDIANTE_H
“Sources”
(profesor.cpp)
#include "Profesor.h"
#include "Persona.h"
string Profesor::informacion()
{
return Persona::informacion() + "\nSalario: " + to_string(this-
>salario) + "\n";
}
(estudiante.cpp)
#include "Estudiante.h"
#include "Persona.h"
string Estudiante::informacion()
{
return Persona::informacion() + "\ncreditos: " + to_string(this-
>creditos) + "\n";
}
Dado que el código principal en la parte de las clases podemos observar que las
funciones ya están declaradas, en estos copie las declaraciones en los archivos que
son .cpp, en la clase “Persona.cpp” y así específicamente en la función determinada
llamada “información ()” se imprimiría el nombre y de igual manera la edad mediante el
uso de el indicativo to_trsing. Con esto la subclase “Profesor.cpp” y así dentro de la
función “información()” se llamara a la misma función de la clase base, mediante un
llamada to_string y así el puntero this se llamara a un atributo “salario” este será el
mismo caso para la subclase “Estudiante.cpp” con esto en ves de llamarlo con un salario
a un to_string y a su ves con el puntero this se llama a el atributo “créditos”, con esto
puedo decir que “Profesor.cpp” y “Estudiante.cpp” se va incluir en la librería “(#include
“Persona.h”)”.
(main.cpp)
#include <iostream>
#include "Persona.h"
#include "Profesor.h"
#include "Estudiante.h"
int main()
{
Persona objA("Juan", 25);
Profesor objB("Pedro", 35, 1500);
Estudiante objC("Maria", 19, 32);
return 0;
}
Para finalizar dentro del archivo main.cpp se declararán todas las librerías de las
distintas clases al estructurar la base de un código en c++ con la librería #iostream, Aquí
se llaman las diferentes clases Persona, Profesor y estudiante con esto se dará un nuevo
nombre “obj(letra)” en donde la letra será un llamada diferenciador entre objetos, con
esto se llena cada parámetro el cual será designado.
Con esto podemos ver que Persona incluyen un nombre y una edad, mientras que
Profesor se le dará un numero representado con esto el sueldo que gana mientras que en
Estudiante el numero ingresado representara los créditos los cuales posee, con esto los 2
poseen 2 parámetros inicializados ya que son hijas de la clase base llamada “Persona”
con esto el tercer parámetro permitirá su fácil comprensión.
Con esto podemos decir que luego de llamar las clases y dar un nombre diferente a cada
uno, se ejecutaran a imprimir en la pantalla la función “información ()” con esta
ejecución se vería así:
“Ejecución”
“Headers”
(“animal.h”)
#ifndef ANIMAL_H
#define ANIMAL_H
#include <iostream>
#include <string>
class Animal
{
private:
string nombre;
protected:
string queSoy;
public:
Animal();
Animal(string nombre);
string quienEres();
};
#endif // ANIMAL_H
(“perro.h)
#ifndef PERRO_H
#define PERRO_H
#include "animal.h"
#endif // PERRO_H
(“gato.h”)
#ifndef GATO_H
#define GATO_H
#include "animal.h"
(“humano.h”)
#ifndef HUMANO_H
#define HUMANO_H
#include "animal.h"
#endif // HUMANO_H
“Sources”
(“animal.cpp)
#include "animal.h"
}
string Animal::habla()
{
return "Grrrr!";
}
string Animal::quienEres()
{
return "Soy un " + this->queSoy + " y me llamo " + this->nombre;
}
string Perro::habla()
{
return "guau! guau!";
}
(“gato.cpp”)
#include "gato.h"
string Gato::habla()
{
return "miau! miau!";
}
(humano.cpp)
#include "humano.h"
string Humano::habla()
{
return "habla mijín!";
}
Debemos tener en cuenta que dentro de la clase hija las cuales se diferencian en su
nombre como los son (perro gato y humano) se declara el único y el aceptado y
constructor con esto la función habla la cual vendría siendo la función virtual está
siendo heredada de las clase llamada “animal.h” en este archivo cpp el constructor
obtendrá un atributo “queSoy” este nombre será idéntico al nombre del archivo
respectivo y en la función virtual “habla()” vendrían retornando un texto diferente de la
clase principal y de las otras clases hijas con esto cada clase tendrá la misma función
pero actuará diferente esto se da porque inicialmente se declaró como “virtual”.
(main.cpp)
#include <iostream>
#include "animal.h"
#include "perro.h"
#include "gato.h"
#include "humano.h"
// #include <vector>
//#include <array>
int main()
{
// crear un vector de punteros de tipo Animal.
Animal *farm[3];
//vector<Animal> *farm(3);
//array<Animal,3> *farm;
// Instancias dinámicas de objetos
farm[0] = new Perro("Tarzan");
farm[1] = new Gato("Chispas");
farm[2] = new Humano("Juan Carlos");
// recorrer el vector de objetos
for (int i = 0; i < 3; i++)
{
// invocación al metodo definido en clase base
cout << farm[i]->quienEres() << ": ";
// llamada al metodo polimorfico
cout << farm[i]->habla() << endl;
}
return 0;
}
Dando por finalizado el archivo main.cpp De permitir nos declarar librerías las cuales
vamos a utilizar respectivamente se creará un vector el cual inicializaremos con un
puntero que llevará el nombre de la clase principal en consiguiente crearemos instancias
dinámicas una por cada clase hija dándole valor a una clase hija llamándola o
entendiéndola como nueva con esto tienen un nuevo almacenamiento.
después de esto podremos incluir un lazo (for) este pasará por cada elemento del arreglo
de punteros imprimiendo la función “quienEres()” ésta se encarga de almacenar el
nombre de cada clase hija y de la función virtual “habla()” con esto se ejecutará en la
pantalla según la clase hija imprimiendo en la pantalla lo que sería el sonido de cada
animal respectivo al cual se trata de emular.
(Ejecución)
c) Eliminar la palabra “virtual” del método habla de la clase Animal (línea
25). Volver a compilar el código y ejecutar. Explicar razonadamente el resultado obtenido.
#ifndef ANIMAL_H
#define ANIMAL_H
#include <iostream>
#include <string>
class Animal
{
private:
string nombre;
protected:
string queSoy;
public:
Animal();
Animal(string nombre);
string quienEres();
};
#endif // ANIMAL_H
(Ejecución)
PARTE B
Ejercicio de herencia y polimorfismo
El Conservatorio Nacional de Música nos ha contratado para crear un programa que permita
llevar la información de los instrumentos musicales que tiene la institución. Tienen tres
clasificaciones básicas: instrumentos de viento, instrumentos de cuerda e instrumentos de
percusión. Se requiere saber la siguiente información de cada instrumento:
class instrumentos
{
private:
string tipo;
string nombre;
string material;
string estilo;
string clasificacion;
double altura;
double costo;
int numeroInstrumento;
public:
static int nInstrumento;
instrumentos();
instrumentos(string nombre, string material, double costo,
string estilo);
instrumentos(string nombre, string material, string
clasificacion, double costo);
instrumentos(string nombre, string material, double costo,
double altura);
string I1();
string I2();
string I3();
};
#endif // INSTRUMENTOS_H
'
(cuerda.h)
#ifndef CUERDA_H
#define CUERDA_H
#include "instrumentos.h"
#include <vector>
void IDADO();
void LISTAINSTRUMENTOS();
string afinar();
};
#endif // CUERDA_H
(percusión)
#ifndef PERCUSION_H
#define PERCUSION_H
#include "instrumentos.h"
#include <vector>
class percucion : public instrumentos
{
private:
vector <instrumentos> instrumentoTODO;
public:
percucion();
percucion(string nombre, string material, double altura, double
costo);
void IDADO();
void LISTAINSTRUMENTOS();
string afinar();
};
#endif // PERCUSION_H
(viento.h)
#ifndef VIENTO_H
#define VIENTO_H
#include "instrumentos.h"
#include <vector>
class viento : public instrumentos
{
private:
vector <instrumentos> instrumentoTODO;
public:
viento();
viento(string nombre, string material, double costo, string
clasificacion);
void IDADO();
void LISTAINSTRUMENTOS();
string afinar();
};
#endif // VIENTO_H
“Sources”
(instrumentos.cpp)
#include "instrumentos.h"
instrumentos::instrumentos()
{
this->numeroInstrumento = 0;
this->tipo = "";
this->nombre = "";
this->material = "";
this->estilo = "";
this->clasificacion = "";
this->costo = 0;
}
string instrumentos::I1()
{
string ficha = " \t==== INFORMACION DEL INSTRUMENTO ====\n "
"Instrumento numero: " + to_string(this-
>numeroInstrumento) + "\n" +
"Nombre: " + this->nombre + "\n" +
"Material: " + this->material + "\n" +
"Estilo: " + this->estilo + "\n" +
"Costo: "+ to_string(this->costo) + "\n\n";
return ficha;
}
string instrumentos::I2()
{
string ficha = " \t==== INFORMACION DEL INSTRUMENTO ====\n "
"Instrumento numero: " + to_string(this-
>numeroInstrumento) + "\n" +
"Nombre: " + this->nombre + "\n" +
"Material: " + this->material + "\n" +
"Clasificacion: " + this->clasificacion + "\n" +
"Costo: "+ to_string(this->costo) + "\n\n";
return ficha;
}
string instrumentos::I3()
{
string ficha = " \t==== INFORMACION DEL INSTRUMENTO ====\n "
"Instrumento numero: " + to_string(this-
>numeroInstrumento) + "\n" +
"Nombre: " + this->nombre + "\n" +
"Material: " + this->material + "\n" +
"Altura: " + to_string(this->altura) + "\n" +
"Costo: "+ to_string(this->costo) + "\n\n";
return ficha;
}
string instrumentos::afinar()
{
return "Afinando";
(cuerda.cpp)
#include "cuerda.h"
#include "instrumentos.h"
cuerda::cuerda()
{
void cuerda::IDADO()
{
string nombre;
string estilo;
string material;
double costo;
if(estilo == "clasico"){
costo = 150.00;
cout << "El valor del instrumento es: " << costo;
}else if(estilo == "electrico"){
costo = 190.00;
cout << "El valor del instrumento es: " << costo;
}
if(nombre == "violin"){
cout << "\nDe que material esta hecho: ";
getline(cin >> ws, material);
cout << "\nCual estilo quiere (clasico o electronico): ";
getline(cin >> ws, estilo);
if(estilo == "clasico"){
costo = 150.00;
cout << "El valor del instrumento es: " << costo;
}else if(estilo == "electronico"){
costo = 190.00;
cout << "El valor del instrumento es: " << costo;
}
if(nombre == "piano"){
cout << "\nDe que material esta hecho: ";
getline(cin >> ws, material);
cout << "\nCual estilo quiere (vertical o de cola):";
getline(cin >> ws, estilo);
if(estilo == "vertical"){
costo = 250.00;
cout << "El valor del instrumento es: " << costo;
}else if(estilo == "de cola"){
costo = 290.00;
cout << "El valor del instrumento es: " << costo;
}
void cuerda::LISTAINSTRUMENTOS()
{
if(this->IntrumentosGENERAL.empty()){
cout << "No hay ningun instrumento de cuerda\n";
}else{
for(instrumentos c : this->IntrumentosGENERAL){
cout << "\t=== INSTRUMENTOS DE CUERDA ===\n";
cout << c.I1();
}
string cuerda::afinar()
{
string nombre;
return "Nombre: " + nombre + "Ajustando cuerdas";
}
(main.cpp)
#include <iostream>
#include "instrumentos.h"
#include "cuerda.h"
#include "viento.h"
#include "percusion.h"
using namespace std;
int instrumentos::nInstrumento = 0;
int main()
int op = 0;
string tipo;
cuerda c;
viento v;
percucion p;
instrumentos i;
do{
cout << "\n\t ****UNIVERSIDAD POLITECNICA SALESIANA*** \t \
n";
cout << "\n\t \t [Autor:Pedro Vinicio Alajo] \n";
do{
}while(op>5);
switch (op) {
case 1:
}while(op!=5);
cout << " {GRACIAS POR UTILIZAR EL PROGRAMA} \n";
return 0;
}
(percusión.cpp)
#include "percusion.h"
#include "instrumentos.h"
percucion::percucion()
{
void percucion::IDADO()
{
bool altu;
string nombre;
double altura;
string material;
double costo;
}
void percucion::LISTAINSTRUMENTOS()
{
if(this->instrumentoTODO.empty()){
cout << "No hay instrumento de percucion\n";
}else{
for(instrumentos c : this->instrumentoTODO){
cout << "\t {DE PERCUSION}\n";
cout << c.I3();
}
}
string percucion::afinar()
{
string nombre;
return "Nombre: " + nombre + "Tensando tambores";
}
(viento.cpp)
#include "viento.h"
#include "instrumentos.h"
viento::viento()
{
}
viento::viento(string nombre, string material, double costo, string
clasificacion)
: instrumentos(nombre, material, costo, clasificacion)
{
void viento::IDADO()
{
string nombre;
string clasificacion;
string material;
double costo;
cout << "Ey!!! Ingresa el nombre del isntrumento [minusculas]:
";
getline(cin >> ws, nombre);
cout << "\n Material del instrumento: ";
getline(cin >> ws, material);
cout << "\n Clasificacion del Instrumento escoja las siguiente
opciones [(de bisel / de lengueta / dobles / de embocadura)]: ";
getline(cin >> ws, clasificacion);
if(clasificacion == "bisel"){
costo = 125.00;
cout << " LA COTIZACION DEL INSTRUMENTO ES: " << costo;
}
if(clasificacion == "lengueta"){
costo = 135.00;
cout << "LA COTIZACION DEL INSTRUMENTO ES: " << costo;
}
if(clasificacion == "dobles"){
costo = 145.00;
cout << "LA COTIZACION DEL INSTRUMENTO ES: " << costo;
}
if(clasificacion == "embocadura"){
costo = 155.00;
cout << "LA COTIZACION DEL INSTRUMENTO ES: " << costo;
}
instrumentos c(nombre, material, clasificacion, costo);
this->instrumentoTODO.push_back(c);
}
void viento::LISTAINSTRUMENTOS()
{
if(this->instrumentoTODO.empty()){
cout << "NO EXISTE INSTRUMENTO DE VIENTO \n";
}else{
for(instrumentos c : this->instrumentoTODO){
cout << "\t {INTRUMENTO DE VIENTO} \n";
cout << c.I2();
}
string viento::afinar()
{
string nombre;
return "Nombre: " + nombre + "Limpiando valvulas";
Básicamente lo que hicimos en este algoritmo fue lo que hemos venido haciendo en los
en las anteriores prácticas hemos creado distintas clases para para poder declarar las
variables que se nos da solicitado los métodos que utilizamos siguen siendo los virus
declaramos algunos métodos void entre otros lo que en esta práctica utilizamos
fundamentalmente fue la herencia como este método nos permitió declararla misma
variable en diferentes subclases y finalmente declarando todas estas anteriores
mencionadas en la librería “instrumentos.h”
(Listar instrumentos)
(Afinar instrumentos)
(Total de instrumentos)
(Salir)
Conclusión
Para dar por concluido yo pude entender herencia implica una o varias relaciones de
generalización y especialización en la que una clase o varias clases las cuales sean
derivadas se especializan en el comportamiento o la estructura más general de sus clases
bases estas anteriormente ya mencionados representan especializaciones en la que datos
disfunciones de la clase sufren añadiduras modificaciones o también ocultaciones me
pareció una gran ventaja la del mecanismo de derivación de las diferentes clases da
nuevas posibilidades a reutilizar este código sin necesariamente de volver a escribir con
esto puedo decir que las clases derivadas reutilizar y en este código sin tener que
definirse otra vez.
Referencias y bibliografía
Bibliography
Booch, G. (1994). Herencia y Polimorfismo. New Jersey: Desconocida.