Вы находитесь на странице: 1из 29

DcimooctavaSesin

Metodologas y Tcnicas de Programacin II

Programacin Orientada a Objeto (POO) C++

Herencia II
1

EstadodelPrograma
Introduccin a la POO Repaso de Conceptos
Historia de la Programacin Conceptos de POO Estndares de Programacin Punteros y Memoria C++ Mi primera Clase E/S Control y Operadores

Clases y Objetos en C++


Uso y aplicacin Constructores Constantes e inline

Funciones Amigas Sobrecarga de Funciones

Sobrecarga
De Operadores Creacin Dinmica de Objetos

Herencia.

Tipos de Visibilidad

Herencia Mltiple

Polimorfismo
Funciones Virtuales Polimorfismo y Sobrecarga.

Plantillas

Contenedores

Iteradores

18.1Repaso
Herencia y Composicin Formas de reutilizacin sistemtica. Mejor. Ms concienzudas. Composicin: Creamos objetos de la clase existente dentro de la nueva clase que estamos creando. La nueva clase est compuesta por objetos de clases existentes. Herencia: Se toma la forma de la clase existente y se aade cdigo sin modificar la clase existente. La nueva clase se crea como un tipo de la existente. Casi todo el trabajo lo realiza el compilador. La herencia es una propiedad de la Programacin Orientada a Objeto. Nos permite: Crear nuevas clases a partir de clases existentes. Conservando las propiedades de la clase original. Aadir nuevos mtodos y atributos a la clase original.
3

18.1Repaso
Herencia Cuando una clase deriva de ms de una clase base: Herencia Mltiple. Este tipo de relaciones nos permite crear Jerarquas de Clases.
Persona

Empleado

Alumno

Profesor

Administrativo

class <clase_derivada> : [public|private] <base1> [,[public|private] <base2>] {}; Clase base: La clase base es la clase ya creada, de la que se hereda. Tambin se la denomina clase madre o superclase. Clase derivada: es la clase que se crea a partir de la clase base. Se dice que es la clase que hereda. Tambin se la denomina clase hija o subclase.
4

18.2Repaso
Control de Acceso en la Herencia class <clase_derivada> : [public|private] <base1> [,[public|private] <base2>] {};
Persona

Alumno

TipodeDatoClaseBase Private Protected Public

Herenciaconpublic Herenciaconprivate Otros NoaccesibledirectamenteNoaccesibledirectamenteNoaccesible Protected Private Noaccesible Public Private Accesible(.>)

18.2Herencia
Herencia: Miembros que no se heredan automticamente La clase derivada hereda todos los atributos y todos los mtodos, excepto: Constructores Destructor Operador de asignacin Constructores y destructor: Si en la subclase no estn definidos, se crea un constructor por defecto y un destructor, aunque sin que hagan nada en concreto. Operador de asignacin: Si en la subclase no est definido, se crea uno el operador de asignacin de la superclase. por defecto que se basa en

Se deben crear los constructores y el destructor en la subclase. Se debe definir el operador de asignacin en la subclase.

18.2Herencia
Herencia: Constructores y Lista de Inicializacin En C++ es muy importante la correcta inicializacin de los objetos y variables. Cuando se crea un objeto el compilador garantiza la ejecucin de todos los constructores para cada uno de los subobjetos. Qu ocurre..? - Si uno de los subobjetos no tiene un constructor por defecto. - Si queremos cambiar los parmetros por defecto de un constructor. La solucin: - Ejecutamos nosotros la llamada al constructor. - Utilizamos los inicializadores o listas de inicializacin. Esto ya lo hemos usado (solo que con tipos predefinidos): Alumno::Alumno(int nota, int edad) : nota_(nota), edad_(edad) {}; Alumno::Alumno(int nota, int edad) : Persona(edad), nota_(nota) {};
7

18.2Herencia
Constructores
classClaseBase { protected: intb1; intb2; public: intb3; ClaseBase(inta=0,intb=0,intc=0); ... }; classClaseDerivada:publicClaseBase { private: floats1; chars2; public: ClaseDerivada(floatd,chare); };

Cuando se llama al constructor de la clase derivada, el compilador ejecuta el constructor por defecto de la clase Base, a no ser que especifiquemos uno en concreto. ClaseDerivadad(8.2,'A'); b10s18.2 b20s2A b30

18.2Herencia
Constructores
classClaseBase { protected: intb1; intb2; public: intb3; ClaseBase(inta=0,intb=0,intc=0); ... }; classClaseDerivada:publicClaseBase { private: floats1; chars2; public: ClaseDerivada(inta,intb,intc, floatd,chare); };

Si queremos que los atributos heredados tomen un valor determinado:

ClaseDerivada::ClaseDerivada (inta,intb,intc,floatd,chare) :ClaseBase(a,b,c) { s1=d; s2=e; };

ClaseDerivadad(6,7,48.2,'A'); b16s18.2 b27s2A b34


9

18.2Herencia
Herencia: Llamadas automticas al destructor A menudo es necesario realizar llamadas explcitas a los constructores en la inicializacin como hemos visto. Nunca ser necesario realizar una llamada explcita a los destructores: Slo existe un destructor para cada clase. No tiene parmetros.

El compilador asegura que todos los destructores son llamados. Esto signica que todos los destructores de la jerarqua, desde el destructor de la clase derivada y retrocediendo hasta la raz, sern ejecutados.

10

18.2Herencia
Orden de llamada de constructores y destructores
#defineCLASS(ID)classID{\ public:\ ID(int){out<<#ID"constructor\n";}\ ID(){out<<#ID"destructor\n";}\ }; CLASS(Base1); CLASS(Member1); CLASS(Member2); CLASS(Member3); classDerived1:publicBase1 { Member1m1; Member2m2; public: Derived1(int):m2(1),m1(2), Base1(3){ out<<"Derived1constructor\n"; } Derived1(){ out<<"Derived1destructor\n"; } }; classDerived2:publicDerived1 { Member3m3; public: Derived2():m3(1),Derived1(2) { out<<"Derived2constructor\n"; } Derived2() { out<<"Derived2destructor\n"; } };

11

18.2Herencia
Orden de llamada de constructores y destructores
intmain() { Derived2d2; }

SALIDAPORPANTALLAEsCorrecta? ==================================== Base1constructor Member1constructor Member2constructor Derived1constructor Member3constructor Derived2constructor Derived2destructor Member3destructor Derived1destructor Member2destructor Member1destructor Base1destructor
12

18.2Herencia
Orden de llamada de constructores y destructores El orden de las llamadas al constructor para los objetos miembro no se ve afectado por el orden de las llamadas en la lista de inicializadores de un constructor. Es determinado por el orden en que los objetos miembros son declarados en la clase. Si pudiramos cambiar el orden del constructor en la lista de inicializadores de un constructor, podramos tener dos secuencias diferentes de llamada en dos constructores diferentes, pero el destructor no sabra como invertir el orden para llamarse correctamente y nos encontraramos con problemas de dependencias.

13

18.2Herencia
Orden de llamada de constructores Cuando se crea un objeto de la clase derivada, ocurre lo siguiente: 1 Se invoca el constructor de la superclase. La invocacin del constructor de la superclase se realiza con los argumentos que se especifiquen. Si no hay argumentos, se usa el constructor predeterminado. 2 Se ejecuta el constructor de la clase derivada.

Constructor de la Clase Base

Constructor de la Clase Derivada

FIN

14

18.2Herencia
Orden de llamada de destructores Cuando se destruye un objeto de la clase derivada, ocurre lo siguiente: 1 Se invoca el destructor de la clas derivada. 2 Se ejecuta el destructor de la clase base.

Destructor de la Clase Base

Destructor de la Clase Derivada

FIN

15

17.2Herencia
Operador Asignacin Recordemos que el operador asignacin NO se hereda.
operator= Clase Derivada

Existe? NO operator= Clase Base

SI

FIN

Existe? NO

SI Copia Bit a Bit

16

18.2Herencia
Operador Asignacin
ClaseBase&ClaseBase:: operator=(ClaseBasec) { b1=c.b1; b2=c.b2; b3=c.b3; return*this; }; ClaseDerivada&ClaseDerivada:: operator=(ClaseDerivadad) { s1=d.s1; s2=d.s2; return*this; }; ClaseDerivadaob1(6,7,4,8.2,f); ClaseDerivadaob2(0,0,0,0,h); ob2=ob1;

Qu mtodo se ejecuta? b16s18.2 b27s2f b34 b10s10 b20s2h b30

b10s18.2 b20s2f b30

17

18.2Herencia
Operador Asignacin
ClaseBase&ClaseBase:: operator=(ClaseBasec) { b1=c.b1; b2=c.b2; b3=c.b3; return*this; }; ClaseDerivada&ClaseDerivada:: operator=(ClaseDerivadad) { b1=d.b1; b2=d.b2; b3=d.b3; s1=d.s1; s2=d.s2; return*this; };

Una Solucin: Podemos aadir al operador asignacin de la clase derivada cada una de las asignaciones que nos faltan en el anterior caso. Qu pasa si tenemos 120 atributos en la clase base? Me tengo que preocupar de si se aaden o quitan atributos a una clase que puede que ni siquiera mantengamos nosotros?

18

18.2Herencia
Operador Asignacin
ClaseBase&ClaseBase:: operator=(ClaseBasec) { b1=c.b1; b2=c.b2; b3=c.b3; return*this; }; ClaseDerivada&ClaseDerivada:: operator=(ClaseDerivadad) { ClaseBase::operator=(d); s1=d.s1; s2=d.s2; return*this; }; ClaseDerivadaob1(6,7,4,8.2,f); ClaseDerivadaob2(0,0,0,0,h); ob2=ob1;

Ejecutamos el operador asignacin de la superclase. b16s18.2 ob1 b27s2f b34 b10s10 ob2 b20s2h b30

ob2 b16s18.2 b27s2f b34

19

18.2Herencia
Ejemplo de Combinacin de Composicin y Herencia
classA { inti; public: A(intii):i(ii){}; A(){}; voidf()const{}; }; classB { inti; public: B(intii):i(ii){}; B(){}; voidf()const{}; }; intmain() { Cc(47); c.f(); } classC:publicB//Herencia { Aa;//Composicin public: C(intii):B(ii),a(ii){}; C(){};//LlamaaA()andB() voidf()const//Redefinicin { a.f(); B::f(); } };

20

18.2Herencia
Ejemplo de Herencia
ClassAlumno:publicPersona { private: intcurso; public: Alumno(char*,int=0,char*, char*,int); Alumno&operator=(Alumno&); ~Alumno();//Destructor intmcurso(); voidmcurso(int); }; // intAlumno::mcurso() { returncurso; } voidAlumno::mcurso(intc) { curso=c; } Alumno&Alumno::operator=(Alumnoa) { Persona::operator=(a); curso=a.curso; return*this; } Alumno::Alumno(char*n,inte,char* nom,char*ape,intc) :Persona(n,e,nom,ape) { curso=c; }

21

18.2Herencia
Herencia y Redefinicin de Mtodos Vimos que con la Herencia podemos: Heredar y reutilizar atributos y mtodos. Ampliar atributos o mtodos. Redefinir Mtodos. Tiene sentido redefinir atributos? En la clase derivada se puede redefinir algn mtodo ya definido en la clase base: redefinicin o superposicin de mtodos. Para redefinir un mtodo en la subclase, basta con declarar una funcin miembro con el mismo nombre. Por ejemplo: El mtodo mostrar() de Persona no tiene sentido para Alumno. Redefinimos el mtodo mostrar() en Alumno.
22

18.2Herencia
Redefinicin de Mtodos
voidPersona::mostrar() { cout<<nif; cout<<Nombre:<<nombre; } voidAlumno::mostrar() { Persona::mostrar(); cout<<Curso:<<curso; } intmain() { Personap1(89411N,33, Luis,Fernan); Alumnoalum(77777R,20, Ana,Ruiz,3); p1.mostrar(); alum.mostrar(); }

En el constructor de alum se llamar al constructor de Persona (porque as lo programamos). alum y p1 quedan adecuadamente inicializados. Lasalidaes: 89411NNombre:Luis 77777RNombre:AnaCurso:3

23

18.2Herencia
Herencia, Jerarquas de clases y Redefinicin de Mtodos Hemos visto un ejemplo sencillo: Clase Base (Persona) y Derivada (Alumno) Cmo funciona todo esto aqu?
Persona

Empleado

Alumno

Profesor

Administrativo

Hay diferentes situaciones dependiendo implementado en mtodo mostrar:

de

cmo

puede

estar

admin.mostrar();//ObjetodelaclaseAdministrativo...

24

17.2Herencia
Pasos de Mensaje con Herencia Ejercicio: alum.mostrar(); alum.felizcumple(); alum.matricular();
Buscamos mtodo en la clase

Existe? NO SI Buscamos en la primera Superclase

SI

FIN

Hay ms Clases en la jerarqua?

Existe? NO

SI

NO

ERROR 25

18.2Herencia
Tipos de Vinculacin Vinculacin esttica: se trata del intento de vincular el mensaje con el mtodo correspondiente en tiempo de compilacin. Si se produce error de vinculacin, ser en tiempo de compilacin

Vinculacin dinmica: la vinculacin entre mensaje y mtodo se realiza en tiempo de ejecucin. Si se produce error de vinculacin, ser en tiempo de ejecucin

26

18.2Herencia
Problemas con la Vinculacin
voidPersona::felizcumple() { edad++; cout<<Felicidades!!; mostrar(); } intmain() { Alumnoalum(77777R,20, Ana,Ruiz,3); alum.felizcumple(); }

Elmtodofelizcumple()noest definidoenAlumno. Se busca encuentra. en persona, y se

El mensaje mostrar() se vincula con la clase Persona en lugar de con la clase Alumno. Lasalidaes: Felicidades!! 77777RNombre:Ana (*)Nosfaltaelcurso.

27

18.3Ejercicios
1.Compilaryejecutarelsiguientecdigo.Explicarloqueocurre. classBase { public: intf()const { cout<<"Base::f()\n"; return1; } intf(string)const{return1;} voidg(){} }; classDerived1:publicBase { public: voidg()const{} }; classDerived2:publicBase { public: intf()const { cout<<"Derived2::f()\n"; return2; } }; classDerived3:publicBase { public: voidf()const//Atentos {cout<<"Derived3::f()\n";} }; classDerived4:publicBase { public: //Haycambios?? intf(int)const{ cout<<"Derived4::f()\n"; return4; } }; strings("hello"); Derived1d1; intx=d1.f(); d1.f(s); Derived2d2; x=d2.f(); Derived3d3; Derived4d4; x=d4.f(1);

28

18.3Ejercicios
2.Compilayejecutaelcdigodelaspginas11y12.Compruebasilasalidapor pantallaescorrecta.Comentaloqueocurre. 3. Crea dos clases, A y B, con constructores por defecto que muestren por pantallatrazadequehansidollamados.UnanuevaclasellamadaCqueheredade A, y cree un objeto miembro B dentro de C, pero no cree un constructor para C. CreaunobjetodelaclaseCenmain()yobservalosresultados. 4.Creaunajerarquaadeclasesdetresnivelesconconstructorespordefectoy con destructores, ambos noticndose utilizando cout. Vericar que el objeto ms alto de la jerarqua, los tres constructores y destructores son ejecutados automticamente.Explicarelordenenquehansidorealizados. 5.Describeestosconceptosdeformabreve: a)Herencia. b)Composicin. c)HerenciaMltiple. d)ClaseBase e)ClaseDerivada 6.Implementalasclases: Punto,CrculoyCilindroutilizandolaHerencia. Todosdebentenerconstructorbasadoenclasebase,destructorymostrar().

29

Вам также может понравиться