1 Polimorfismo y Funciones Virtuales Agustín J. González ELO329.

Slides:



Advertisements
Presentaciones similares
Curso de java básico (scjp)
Advertisements

CJ02 – Técnicas avanzadas en java 1.4 y 5.0
Genéricos en Java Jaime Ramírez, Ángel Lucas González
Informática II 1 Diego Fernando Serna RestrepoSemestre 2011/2.
Tema 7: Polimorfismo Antonio J. Sierra. Índice Introducción. Sobrecarga de métodos. Objetos como parámetros. Paso de argumentos. Devolución de objetos.
Métodos Algoritmos y Desarrollo de Programas I. Cuando utilizar métodos  Los métodos se utilizan para romper un problema en pedazos de forma que este.
Material de apoyo Unidad 2 Estructura de datos
Abstracción de los datos y Orientación a Objeto Clase 13.
Clases y objetos La unidad fundamental de programación OO son las clases. Conjunto de métodos y semántica Qué se va a hacer POO Clase: que define la implementación.
Tema 6: Clases Antonio J. Sierra.
1 Herencia en Java Agustín J. González Diseño y Programación Orientados a Objetos.
Variables polimórficas (plantillas): definición, uso y aplicación
1 Interfaces Agustín J. González ELO Introducción En C++ se permite la herencia múltiple; es decir, es posible derivar una clase de dos o más clases.
1 Chapter 15 Pointers, Dynamic Data, and Reference Types Dale/Weems/Headington.
Introducción a los punteros
Plantillas (Templates)‏ Agustín J. González ELO-329.
ELO3201 Vectores (Vector) Agustín J. González ELO320.
Programación Orientada a Objetos usando CONSTRUCTORES DESTRUCTORES.
1 Polimorfismo y Métodos Virtuales Agustín J. González ELO329.
1 Asignación Dinámica de Memoria Agustín J. González Versión original de Kip Irvine ELO 329.
Clases en C++ Agustín J. González ELO329.
1 Introducción a Clases Agustín J. González ELO329.
Herramientas de polimorfismo y herencia en C++
Manejo de Punteros y objetos en memoria dinámica en C++
1 Manejo de Excepciones y otros Agustín J. González ELO-329.
1 Herencia Agustín J. González ELO Motor ElectricMotor Motor y ElectricMotor Consideremos dos clases que tienen algo en común.
1 Introducción a Clases Agustín J. González Versión original de Kip Irvine ELO329.
1 Herencia en Java Agustín J. González Diseño y Programación Orientados a Objetos.
1 Definición y Conversión de datos Agustín J. González ELO-329.
1 Herencia Agustín J. González Versión original de Kip Irvine ELO320: Seminario II 2do. Sem 2001.
1 Polimorfismo y Funciones Virtuales Agustín J. González Versión original de Kip Irvine ELO329.
Herencia. Introducción La idea básica es poder crear clases basadas en clases ya existentes. Cuando heredamos de una clase existente, estamos re-usando.
Punteros Recomendado: 1. Nivelación Funciones
1 Asignación Dinámica de Memoria Agustín J. González ELO 329.
Polimorfismo y Métodos Virtuales Agustín J. González ELO329.
ELO3291 Manejo de Excepciones Agustín J. González ELO329.
1 Interfaces Agustín J. González ELO Introducción En C++ se permite la herencia múltiple; es decir, es posible derivar una clase de dos o más clases.
1 Miembros Estáticos (Static) de Clases y Funciones Amigas (Friend)‏ Agustín J. González ELO329.
Programación orientada a objetos Capítulo 9 Algo mas sobre herencias.
1 Herencia Agustín J. González ELO padre hijo Como en biología, los niños heredan características de su padre Clasificación de Objetos En un intento.
MEMORIA DINÁMICA.
1 Definición y Conversión de datos Agustín J. González ELO-329.
Algunas Características de C++ no presentes en C Agustín J. González ELO-329.
Herencia en C++ Agustín J. González ELO329. Diseño y Programación Orientados a Objetos 2 Motor ElectricMotor Motor y ElectricMotor Consideremos dos clases.
1 La sobrecarga de funciones y operadores le da al programador la oportunidad de asignar nuevos significados a las funciones y a los operadores.
Métodos en Java. Estructura de un programa en Java ► La relación con la vida misma la podemos ver en el siguiente comentario: Imaginemos que dos clases.
Prof. Manuel B. Sánchez.  El origen del término polimorfismo es simple: proviene de las palabras griegas poly (muchos) y morphos (forma) multiforme.
Polimorfismo en C++, ligado dinámico y Métodos Virtuales
Polimorfismo y Funciones Virtuales
Polimorfismo y Métodos Virtuales
Polimorfismo en C++, ligado dinámico y Métodos Virtuales
Polimorfismo y Métodos Virtuales
Herencia Agustín J. González ELO329.
Manejo de Punteros y objetos en memoria dinámica en C++
Manejo de Punteros y objetos en memoria dinámica en C++
Herencia en C++ Agustín J. González ELO329.
Manejo de Punteros y objetos en memoria dinámica en C++
Herencia en C++ Agustín J. González ELO329.
Manejo de Punteros y objetos en memoria dinámica en C++
Polimorfismo en C++, ligado dinámico y Métodos Virtuales
Herencia en C++ Agustín J. González ELO329.
Herencia en C++ Agustín J. González ELO329.
Manejo de Punteros y objetos en memoria dinámica en C++
Polimorfismo en C++, ligado dinámico y Métodos Virtuales
Herencia en C++ Agustín J. González ELO329.
Agustín J. González Versión original de Kip Irvine ELO329
Polimorfismo en C++ y Métodos Virtuales
Herencia Agustín J. González ELO329.
Herencia en C++ Agustín J. González ELO329.
Transcripción de la presentación:

1 Polimorfismo y Funciones Virtuales Agustín J. González ELO329

2 Motor ElectricMotorGasMotor Jerarquía de clases Motor Consideremos la jerarquía de clases establecida en la sesión sobre Herencia:

3 La definición de la clase CMotor: Clase CMotor class CMotor { public: CMotor() { } CMotor( const string & id ); string get_ID() const; void set_ID(const string & s); void Display() const; void Input(); private: string m_sID; };

4 Clase CElectricMotor class CElectricMotor : public CMotor { public: CElectricMotor(); CElectricMotor(const string & id, double volts); void Display() const; void Input(); void set_Voltage(double volts); double get_Voltage() const; private: double m_nVoltage; };

5 Clase CGasMotor class CGasMotor :public CMotor { public: CGasMotor(); CGasMotor(const string & id, int cylinders); void Display() const; void Input(); private: int m_nCylinders; };

6 Es fácil definir objetos dinámicos de una clase derivada usando un puntero de tipo específico: Punteros a objetos de clases derivadas CElectricMotor * pC = new CElectricMotor; pC->set_ID(" "); pC->set_Voltage(110.5); pC->Display(); delete pC;

7 Polimorfismo También podemos declarar punteros a una clase base, y luego asignarle la dirección de un objeto de una clase derivada. Esta técnica es llamada polimorfismo. Polimorfismo es un concepto donde un mismo nombre puede denotar objetos de clases diferentes que están relacionadas por una clase base común. CMotor * pM; pM = new CElectricMotor; Este tipo de asignación es llamada “ligado” dinámico “dynamic binding” porque el tipo exacto asignado al puntero es desconocido hasta el momento de la ejecución.

8 Sin embargo, hay un pequeño problema cuando usamos ligado dinámico. Si no somos cuidadosos, el compilador C++ puede llamar las funciones Input and Display de las clase CMotor: Problema de ligado dinámico CMotor * pM; // base pointer type pM = new CElectricMotor; pM->Input(); // calls CMotor::Input() pM->Display(); // calls CMotor::Display() // esta es una diferencia con Java donde // el ligado dinámico es la opción por omisión // more...

9 Funciones Virtuales (Virtual) La solución al problema de la trasparencia previa es fácil de solucionar declarando las funciones Input and Display como virtuales. El calificativo virtual le dice al compilador que genere código que mire al tipo del objeto en tiempo de ejecución y use esta información para seleccionar la versión apropiada de la función. class CMotor {... virtual void Display() const; virtual void Input();... };

10 Funciones Virtuales Es recomendable definir también como virtuales las funciones en la clase derivada, en las clases CGasMotor y CElectricMotor en este caso. class CGasMotor :public CMotor { public:... virtual void Display() const; virtual void Input();... };

11 Funciones Virtuales Ahora las funciones Display e Input son correctamente llamadas desde la clase CElectricMotor: CMotor * pM; pM = new CElectricMotor; pM->Input(); // CElectricMotor::Input() pM->Display(); // CElectricMotor::Display()

12 Funciones Virtuales A menudo, un puntero será pasado a una función que pide un puntero a la clase base. Cuando la función es llamada, podemos pasar cualquier puntero como parámetro actual, siempre y cuando éste apunte a una instancia derivada de la clase base (“subtipo”). void GetAndShowMotor( CMotor * pC ) { pC->Input(); cout << "\nHere's what you entered:\n"; pC->Display(); cout << "\n\n"; }

13 Funciones Virtuales Ejemplo de llamados a GetAndShowMotor con diferentes tipos de punteros. CGasMotor * pG = new CGasMotor; GetAndShowMotor( pG ); CElectricMotor * pE = new CElectricMotor; GetAndShowMotor( pE ); CMotor * pM = new CGasMotor; GetAndShowMotor( pM ); // view output...

14 (Salida de la diapositiva previa) [GasMotor]: Enter the Motor ID: Enter the number of cylinders: 3 Here's what you entered: [GasMotor] ID=234323, Cylinders=3 [ElectricMotor]: Enter the Motor ID: Voltage: 220 Here's what you entered: [ElectricMotor] ID=234324, Voltage=220 [GasMotor]: Enter the Motor ID: Enter the number of cylinders: 5 Here's what you entered: [GasMotor] ID=44444, Cylinders=5

15 Un vector de punteros CMotor puede contener punteros a cualquiera tipo de objeto derivado de CMotor. Creación de un vector de Motores vector vMotors; CMotor * pMotor; pMotor = new CElectricMotor("10000",110); vMotors.push_back(pMotor); pMotor = new CGasMotor("20000",4); vMotors.push_back(pMotor); pMotor = new CElectricMotor("30000",220); vMotors.push_back(pMotor); pMotor = new CGasMotor("40000",2); vMotors.push_back(pMotor);

16 La función que despliega tales vectores no necesita saber exactamente qué tipo de puntero están en el vector mientras se llame a funciones virtuales. Despliegue de Vectores void ShowVector( const vector & vMotors ) { cout << "---- Vector of Motor Pointers ----\n"; for(int i=0; i < vMotors.size(); i++) { cout << (i+1) << ": "; vMotors[i]->Display(); // virtual }

17 La función ShowVector llama a la versión apropiada de la función virtual Display() para cada puntero en el vector. Salida de la función ShowVector Vector of Motor Pointers : [ElectricMotor] ID=10000, Voltage=110 2: [GasMotor] ID=20000, Cylinders=4 3: [ElectricMotor] ID=30000, Voltage=220 4: [GasMotor] ID=40000, Cylinders=2

18 Debemos liberar el almacenamiento usado por cada objeto motor. Este bucle remueve los punteros uno por uno. El operador delete accede a información que le permite saber exactamente cuanto almacenamiento liberar por cada puntero (aún cuando los motores ocupan distintos tamaños). Liberación de almacenamiento for(int i=0; i < vMotors.size(); i++) { delete vMotors[i]; // delete each motor }

19 Una función virtual pura no tiene implementación. Esto es identificado con un "= 0" al final de la declaración. Una función virtual pura requiere que la función sea implementada en la clase derivada. Funciones Virtuales Puras class CMotor { public: //... virtual void Display() const = 0; virtual void Input() = 0; //...

20 Una clase que contiene una o más funciones virtuales puras pasa a ser una clase abstracta. NO es posible crear instancias de una clase abstracta. Clases Abstractas (Abstract Classes) CMotor M; // error CMotor * pM = new CMotor; // error