You are on page 1of 29

Dcimo octava Sesin

Metodologas y Tcnicas de Programacin II

Programacin Orientada a Objeto (POO) C++

Herencia II
1

Estado del Programa


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 O !etos en C++


"so y aplicacin Constructores Constantes e %inline&

#unciones $migas So recarga de #unciones

So recarga
'e Operadores Creacin 'inmica de O !etos

Herencia(

)ipos de *isi ilidad

Herencia M+ltiple

Polimor,ismo
#unciones *irtuales Polimor,ismo y So recarga(

Plantillas

Contenedores

Iteradores

18.1 Repaso
Herencia y Composicin #ormas de reutili.acin sistemtica( Me!or( Ms concien.udas( Composicin/ Creamos o !etos de la clase e0istente dentro de la nue1a clase 2ue estamos creando( 3a nue1a clase est comp!esta por o !etos de clases e0istentes( Herencia/ Se toma la ,orma de la clase e0istente y se a4ade cdigo sin modi,icar la clase e0istente( 3a nue1a clase se crea como !n tipo de la e0istente( Casi todo el tra a!o lo reali.a el compilador( 3a 5erencia es una propiedad de la Programacin Orientada a O !eto( 6os permite/ Crear nue1as clases a partir de clases e0istentes( Conser1ando las propiedades de la clase original( $4adir nue1os m7todos y atri utos a la clase original(
8

18.1 Repaso
Herencia Cuando una clase deri1a de ms de una clase ase/ Herencia M"ltiple# Este tipo de relaciones nos permite crear $erar%!as de Clases#
Persona

Empleado

$lumno

Pro,esor

$dministrati1o

class 9clase:deri1ada; / <pu lic=pri1ate> 9 ase1; <?<pu lic=pri1ate> 9 ase-;> @AB Clase ase/ 3a clase ase es la clase ya creada? de la 2ue se 5ereda( )am i7n se la denomina clase madre o superclase( Clase deri1ada/ es la clase 2ue se crea a partir de la clase ase( Se dice 2ue es la clase 2ue 5ereda( )am i7n se la denomina clase 5i!a o su clase(
C

18.2 Repaso
Control de &cceso en la Herencia class 9clase:deri1ada; / <pu lic=pri1ate> 9 ase1; <?<pu lic=pri1ate> 9 ase-;> @AB
Persona

$lumno

Tipo de Dato Clase Base Private Protected Public

Herencia con public Herencia con private Otros No accesible directamenteNo accesible directamenteNo accesible Protected Private No accesible Public Private Accesible (. ->)

18.2 Herencia
Herencia' Miembros %!e no se (eredan a!tom ticamente 3a clase deri1ada 5ereda todos los atri utos y todos los m7todos? e0cepto/ ) Constr!ctores ) *estr!ctor ) Operador de asignacin Constr!ctores y destr!ctor' Si en la su clase no estn de,inidos? se crea un constructor por de,ecto y un destructor? aun2ue sin 2ue 5agan nada en concreto( Operador de asignacin' Si en la su clase no est de,inido? se crea uno el operador de asignacin de la superclase( por de,ecto 2ue se asa en

Se de en crear los constructores y el destructor en la su clase( Se de e de,inir el operador de asignacin en la su clase(

18.2 Herencia
Herencia' Constr!ctores y +ista de Iniciali,acin En C++ es muy importante la correcta iniciali.acin de los o !etos y 1aria les( Cuando se crea un o !eto el compilador garanti.a la e!ecucin de todos los constructores para cada uno de los su o !etos( FGu7 ocurre((H I Si uno de los su o !etos no tiene un constructor por de,ecto( I Si 2ueremos cam iar los parmetros por de,ecto de un constructor( 3a solucin/ I E!ecutamos nosotros la llamada al constructor( I "tili.amos los iniciali.adores o listas de iniciali.acin( Esto ya lo 5emos usado Jsolo 2ue con tipos prede,inidosK/ $lumno//$lumnoJint nota? int edadK / nota:JnotaK? edad:JedadK @AB $lumno//$lumnoJint nota? int edadK / PersonaJedadK? nota:JnotaK @AB
L

18.2 Herencia
Constr!ctores
class ClaseBase { protected: int b1 ; int b2 ; public: int b3 ; ClaseBase(int a=0,int b=0,int c=0); ... }; class ClaseDerivada : public ClaseBase { private: float s1 ; char s2 ; public: ClaseDerivada(float d, char e); };

Cuando se llama al constructor de la clase deri1ada? el compilador e!ecuta el constructor por de,ecto de la clase Nase? a no ser 2ue especi,i2uemos uno en concreto( ClaseDerivada d(8.2, 'A'); b1 0 b2 0 b3 - 0 s1 - 8.2 s2 - A

18.2 Herencia
Constr!ctores
class ClaseBase { protected: int b1 ; int b2 ; public: int b3 ; ClaseBase(int a=0,int b=0,int c=0); ... }; class ClaseDerivada : public ClaseBase { private: float s1 ; char s2 ; public: ClaseDerivada(int a, int b, int c, float d, char e); };

Si 2ueremos 2ue los atri utos 5eredados tomen un 1alor determinado/


ClaseDerivada :: ClaseDerivada (int a,int b,int c,float d,char e) : ClaseBase(a,b,c) { s1 = d; s2 = e; };

ClaseDerivada d(6,7,48.2, 'A'); b1 6 b2 7 b3 - 4 s1 - 8.2 s2 - A


O

18.2 Herencia
Herencia' +lamadas a!tom ticas al destr!ctor $ menudo es necesario reali.ar llamadas e0plPcitas a los constructores en la iniciali.acin como 5emos 1isto( 6unca ser necesario reali.ar una llamada e0plPcita a los destructores/ Slo e0iste un destructor para cada clase( 6o tiene parmetros(

El compilador asegura 2ue todos los destr!ctores son llamados( Esto signiQca 2ue todos los destructores de la !erar2uPa? desde el destructor de la clase deri1ada y retrocediendo 5asta la raP.? sern e!ecutados(

1R

18.2 Herencia
Orden de llamada de constr!ctores y destr!ctores
#define CLASS(ID) class ID { \ public: \ ID(int) {out<< #ID " constructor\n";}\ ID() {out << #ID " destructor\n"; } \ }; CLASS(Base1); CLASS(Member1); CLASS(Member2); CLASS(Member3); class Derived1 : public Base1 { Member1 m1; Member2 m2; public: Derived1(int) : m2(1), m1(2), Base1(3) { } Derived2() { out << "Derived2 destructor\n"; } }; }; class Derived2 : public Derived1 { Member3 m3; public: Derived2() : m3(1), Derived1(2) { out << "Derived2 constructor\n"; } } Derived1() { out << "Derived1 destructor\n"; out << "Derived1 constructor\n";

11

18.2 Herencia
Orden de llamada de constr!ctores y destr!ctores
int main() { Derived2 d2; }

SALIDA POR PANTALLA - Es Correcta? ==================================== Base1 constructor Member1 constructor Member2 constructor Derived1 constructor Member3 constructor Derived2 constructor Derived2 destructor Member3 destructor Derived1 destructor Member2 destructor Member1 destructor Base1 destructor
1-

18.2 Herencia
Orden de llamada de constr!ctores y destr!ctores El orden de las llamadas al constructor para los o !etos miem ro no se 1e a,ectado por el orden de las llamadas en la lista de iniciali.adores de un constructor( Es determinado por el orden en 2ue los o !etos miem ros son declarados en la clase( Si pudi7ramos cam iar el orden del constructor en la lista de iniciali.adores de un constructor? podrPamos tener dos secuencias di,erentes de llamada en dos constructores di,erentes? pero el destructor no sa rPa como in1ertir el orden para llamarse correctamente y nos encontrarPamos con pro lemas de dependencias(

18

18.2 Herencia
Orden de llamada de constr!ctores Cuando se crea un o !eto de la clase deri1ada? ocurre lo siguiente/ 1S Se in1oca el constructor de la superclase( 3a in1ocacin del constructor de la superclase se reali.a con los argumentos 2ue se especi,i2uen( Si no 5ay argumentos? se usa el constructor predeterminado( -S Se e!ecuta el constructor de la clase deri1ada(

Constructor de la Clase -ase

Constructor de la Clase *eri.ada

#I6

1C

18.2 Herencia
Orden de llamada de destr!ctores Cuando se destruye un o !eto de la clase deri1ada? ocurre lo siguiente/ 1S Se in1oca el destructor de la clas deri1ada( -S Se e!ecuta el destructor de la clase ase(

'estructor de la Clase -ase

'estructor de la Clase *eri.ada

#I6

1D

17.2 Herencia
Operador &signacin Recordemos 2ue el operador asignacin 6O se 5ereda(
operatorT Clase *eri.ada

E0isteH 6O operatorT Clase -ase

SI

#I6

E0isteH 6O

SI Copia Nit a Nit

1E

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

FGu7 m7todo se e!ecutaH b1 6 b2 7 b3 - 4 b1 0 b2 0 b3 - 0 s1 - 8.2 s2 - f

s1 - 0 s2 - h

b1 0 b2 0 b3 - 0

s1 - 8.2 s2 - f

1L

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

"na Solucin/ Podemos a4adir al operador asignacin de la clase deri1ada cada una de las asignaciones 2ue %nos ,altan& en el anterior caso( FGu7 pasa si tenemos 1-R atri utos en la clase aseH FMe tengo 2ue preocupar de si se a4aden o 2uitan atri utos a una clase 2ue puede 2ue ni si2uiera mantengamos nosotrosH

1M

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

E!ecutamos el operador asignacin de la superclase( b1 6 o 1 b2 7 b3 - 4 b1 0 o - b2 0 b3 - 0 s1 - 8.2 s2 - f s1 - 0 s2 - h

o - b1 6 b2 7 b3 - 4

s1 - 8.2 s2 - f

1O

18.2 Herencia
/jemplo de Combinacin de Composicin y Herencia
class A { int i; public: A(int ii) : i(ii) {}; A() {}; void f() const {}; }; class B { int i; public: B(int ii) : i(ii) {}; B() {}; void f() const {}; }; } int main() { C c(47); c.f(); }; } class C : public B // Herencia { A a; public: C(int ii) : B(ii), a(ii) {}; C() {}; // Llama a A() and B() void f() const // Redefinicin { a.f(); B::f(); // Composicin

-R

18.2 Herencia
/jemplo de Herencia
Class Alumno : public Persona { private: int curso; public: Alumno(char * , int = 0, char *, char * , int ); Alumno& operator=( Alumno &); ~Alumno (); int mcurso (); void mcurso (int ); }; //-----------------------------------int Alumno :: mcurso () { return curso; } } void Alumno :: mcurso (int c) { curso = c ; } // Destructor } Alumno :: Alumno (char * n, int e, char * nom, char * ape , int c ) : Persona (n, e, nom, ape) { curso = c; Alumno & Alumno ::operator= (Alumno a) { Persona :: operator = (a); curso = a.curso; return *this;

-1

18.2 Herencia
Herencia y 0ede1inicin de Mtodos *imos 2ue con la Herencia podemos/ Heredar y reutili.ar atri utos y m7todos( $mpliar atri utos o m7todos( Rede,inir M7todos( 2Tiene sentido rede1inir atrib!tos3 En la clase deri1ada se puede rede,inir alg+n m7todo ya de,inido en la clase ase/ rede,inicin o superposicin de m7todos( Para rede,inir un m7todo en la su clase? asta con declarar una ,uncin miem ro con el mismo nom re( Por e!emplo/ El m7todo mostrarJK de Persona no tiene sentido para $lumno( Rede,inimos el m7todo mostrarJK en $lumno(
--

18.2 Herencia
0ede1inicin de Mtodos
void Persona :: mostrar() { cout << nif; cout << Nombre: << nombre; } void Alumno :: mostrar() { Persona::mostrar(); cout << Curso: } int main() { Persona p1(89411N, 33, Luis, Fernan); Alumno alum (77777R, 20, Ana , Ruiz, 3 ); p1.mostrar(); alum.mostrar(); } << curso;

En el constructor de alum se llamar al constructor de Persona (porque as lo programamos). alum y p1 2uedan adecuadamente iniciali.ados( La salida es: 89411N Nombre: Luis 77777R Nombre: Ana Curso: 3

-8

18.2 Herencia
Herencia4 $erar%!as de clases y 0ede1inicin de Mtodos Hemos 1isto un e!emplo sencillo/ Clase Nase JPersonaK y 'eri1ada J$lumnoK FCmo ,unciona todo esto a2uPH
Persona

Empleado

$lumno

Pro,esor

$dministrati1o

Hay di,erentes situaciones dependiendo implementado en m7todo mostrar/

de

cmo

puede

estar

admin.mostrar(); // Objeto de la clase Administrativo...

-C

17.2 Herencia
Pasos de Mensaje con Herencia E!ercicio/ alum(mostrarJKB alum(,eli.cumpleJKB alum(matricularJKB
Nuscamos m7todo en la clase

E0isteH 6O SI Nuscamos en la primera Superclase

SI

#I6

FHay ms Clases en la !erar2uPaH

E0isteH 6O

SI

6O

ERROR -D

18.2 Herencia
Tipos de 5inc!lacin 5inc!lacin est tica' se trata del intento de 1incular el mensa!e con el m7todo correspondiente en tiempo de compilacin( Si se produce error de 1inculacin? ser en tiempo de compilacin

5inc!lacin din mica' la 1inculacin entre mensa!e y m7todo se reali.a en tiempo de e!ecucin( Si se produce error de 1inculacin? ser en tiempo de e!ecucin

-E

18.2 Herencia
Problemas con la 5inc!lacin
void Persona :: felizcumple() { edad++; cout << Felicidades!!; mostrar(); } int main() { Alumno alum (77777R, 20, Ana , Ruiz, 3 ); alum.felizcumple(); }

El mtodo felizcumple() no est definido en Alumno. Se usca encuentra( en persona? y se

El mensa!e mostrarJK se 1incula con la clase Persona en lugar de con la clase $lumno( La salida es: Felicidades!! 77777R Nombre: Ana (*) Nos falta el curso.

-L

18.3 Ejercicios
1.- Compilar y ejecutar el siguiente cdigo. Explicar lo que ocurre. class Base { public: int f() const { cout << "Base::f()\n"; return 1; } int f(string) const { return 1; } void g() {} }; class Derived1 : public Base { public: void g() const {} }; class Derived2 : public Base { public: int f() const { cout << "Derived2::f()\n"; return 2; } }; class Derived3 : public Base { public: void f() const // Atentos { cout << "Derived3::f()\n"; } }; class Derived4 : public Base { public: // Hay cambios?? int f(int) const { cout << "Derived4::f()\n"; return 4; } }; string s("hello"); Derived1 d1; int x = d1.f(); d1.f(s); Derived2 d2; x = d2.f(); Derived3 d3; Derived4 d4; x = d4.f(1);

-M

18.3 Ejercicios
2.- Compila y ejecuta el cdigo de las pginas 11 y 12. Comprueba si la salida por pantalla es correcta. Comenta lo que ocurre. 3.- Crea dos clases, A y B, pantalla traza de que han sido A, y cree un objeto miembro B Crea un objeto de la clase C en con constructores por defecto que muestren por llamados. Una nueva clase llamada C que hereda de dentro de C, pero no cree un constructor para C. main() y observa los resultados.

4.- Crea una jerarquaa de clases de tres niveles con constructores por defecto y con destructores, ambos noticndose utilizando cout. Vericar que el objeto ms alto de la jerarqua, los tres constructores y destructores son ejecutados automticamente. Explicar el orden en que han sido realizados. 5.- Describe estos conceptos de forma breve: a) Herencia. b) Composicin. c) Herencia Mltiple. d) Clase Base e) Clase Derivada 6.- Implementa las clases: Punto, Crculo y Cilindro utilizando la Herencia. Todos deben tener constructor basado en clase base, destructor

y mostrar().

-O

You might also like