34
10/06/2009 Ing. Daniel Osorio Maldonado 1 TEMA: HERENCIA

Herencia

Embed Size (px)

Citation preview

10/06/2009 Ing. Daniel Osorio Maldonado 1

TEMA: HERENCIA

10/06/2009 Ing. Daniel Osorio Maldonado 2

HERENCIAEs la propiedad que permite a los objetos crearse a partir de otros objetos.Cada subclase comparte características comunes con la clase de la que deriva.La clase original la llamamos clase base y las nuevas clases creadas a partir de ellas, clases derivadas.Si una clase recibe características de mas de una clase se llama herencia múltiple. La herencia la vamos a crear al declarar la clase derivada.

La sintaxis es : class base{//Cuerpo de la clase base};

class derivada :[public/private/protected] base{

//Cuerpo de la clase derivada};

10/06/2009 Ing. Daniel Osorio Maldonado 3

Según el acceso se tiene:Derivación publica (public):-> los miembros públicos de la clase base serán miembros públicos en la clase derivada. Los miembros protegidos de la clase base serán protegidos en la derivada. Los miembros privados de la clase base serán inaccesibles desde la derivada.Derivación protegida (protected)-> todos los miembros públicos y protegidos de la clase base son protegidos en la derivada y los privados serán inaccesibles.Derivación privada (private)-> todos los miembros públicos y protegidos de la clase base serán privados en la derivada. Los privados seguirán siendo inaccesibles en la derivada.

10/06/2009 Ing. Daniel Osorio Maldonado 4

/*Una clase con un lado como base, se va ha derivar el area de un trapecio */#include<iostream.h>#include<conio.h>class lado1{

protected:float x;

public:void setx(float n);void showx();

};void lado1::setx (float n)

{x=n;}void lado1::showx (){cout<<x<<' ';}

10/06/2009 Ing. Daniel Osorio Maldonado 5

//Herencia publicaclass trapecio : public lado1{private:

float y,z;

public:void sety(float n,float m)

{y=n;z=m;}void showy(){cout<<y<<' '<<z;}float Cal_Trape(){return(x+y)*z/2.0;}

};

10/06/2009 Ing. Daniel Osorio Maldonado 6

main(){trapecio ob;int n,m,p;cout<<"\nIngrese la base menor :";cin>>n;ob.setx(n);//miembro de acceso de la clase basecout<<"\nIngrese la base Mayor :";cin>>m;

cout<<"\nIngrese la Altura :";cin>>p;ob.sety(m,p);//miembro de acceso de la clasecout<<"\nLos Valores Mostrados son :";ob.showx();//miembro de acceso de la clase baseob.showy();//miembro de acceso de la clase derivada

cout<<"\nEl Area del Trapecio es ="<<ob.Cal_Trape ();cout<<endl;

getch(); }

10/06/2009 Ing. Daniel Osorio Maldonado 7

// la clase base rectángulo servirá de base para calcular el área del trapecio#include<iostream.h>#include<conio.h>class rectangulo {protected:float a,b;public:rectangulo(int x,int y) //constructor sobrecargado{a=x; b=y;}float area_REC(){return a*b; }~rectangulo(){cout<<"\nDestruyendo al objeto ";}};class trapecio:public rectangulo {protected:float basem, h, baseM;

10/06/2009 Ing. Daniel Osorio Maldonado 8

public:trapecio(int p,int q,int r):rectangulo(p,q){basem=p;h=q;baseM=r; }float areaT(){return ((basem+baseM)/2.0)*h;}

void mostrar(){ cout<<"\nEl largo y el ancho del rectangulo es :"<<basem<<" "<<h<<endl;cout<<"\nEl area del rectangulo es :"<<area_REC()<<endl;cout<<"\nbase menor base mayor y altura del trapecio es: "<<basem<<"\t"<<baseM<<"\t"<<h;cout<<"\n\n\el area del trapecio es :"<<areaT();}};

10/06/2009 Ing. Daniel Osorio Maldonado 9

main(){trapecio t(12,10,15);t.areaT();t.mostrar();cout<<endl;getch();}//Como Tarea haga el ingreso de datos desde teclado//Genere aleatoriamente los lados y resuelva para cuando //la altura o algunos de los lados llegue a tomar un valor //cero

10/06/2009 Ing. Daniel Osorio Maldonado 10

#include<iostream.h>class base{

private:int x;

public:void setx(int n){x=n;}void showx(){cout<<x<<' ';}

};class derived : public base{

int y;public:

10/06/2009 Ing. Daniel Osorio Maldonado 11

void sety(int n){y=n;}void showy() {cout<<y<<' ';}

};main(){

derived ob;int n,m;cout<<"\nIngrese el valor de n:";cin>>n;ob.setx(n);//miembro de acceso de la clase basecout<<"\nIngrese el valor de m:";cin>>m;ob.sety(m);//miembro de acceso de la clasecout<<"\nLos Valores Mostrados son :";ob.showx();//miembro de acceso de la clase baseob.showy();//miembro de acceso de la clase derivada}

10/06/2009 Ing. Daniel Osorio Maldonado 12

#include<iostream.h>#include<conio.h>class base{

protected:int a;

public:base(int);~base();int doble();};

base::base(int x){ a=x; cout<<"\nCONSTRUCTOR BASE "; }

base::~base(){ //solo para punteros para datos miembrocout<<"\nDESTRUCTOR BASE ";}

10/06/2009 Ing. Daniel Osorio Maldonado 13

int base::doble(){ return a*2; }class derivada: public base{

int b;public:derivada(int);

~derivada();void mostrar();

};derivada::derivada(int y):base(y){

b=y;cout<<"\nCONSTRUCTOR DERIVADA";

}derivada::~derivada(){

cout<<"\nDESTRUCTOR DERIVADA";}

10/06/2009 Ing. Daniel Osorio Maldonado 14

void derivada :: mostrar(){cout<<"\nEl doble de "<<a<<" es "<<doble();cout<<"\nEl triple de "<<b<<" es "<<b*3;}

main(){clrscr();derivada d(5);d.mostrar( );getch();}

10/06/2009 Ing. Daniel Osorio Maldonado 15

//CLASE BASE Vehiculo y se va ha derivar a otra clase “moto”#include <iostream.h> class vehiculo {

protected: //tipo protegido a los datos para que se pasen a la variantefloat peso; //Variable tipo decimal que guardara el pesoint ruedas; //Variable tipo intero que guardara el nº de ruedas

public: void iniciar(float p,int r) { peso = p; ruedas = r; };

float ob_peso( ) { return peso; }; int ob_ruedas( ) { return ruedas; };};

10/06/2009 Ing. Daniel Osorio Maldonado 16

class motocicleta:public vehiculo //Declaramos la clase variante llamada motocicleta{ //Hacemos que se pase todo lo protegido y publico a esta variante con :public vehiculoprivate: //Aunque por defecto si no se pone el tipo es private, pero lo ponemosint pasajeros; //Variable de tipo entero que guardara el # de pasajerosint combustible; //Variable de tipo entero que guardara el combustiblechar tipo; //Variable de tipo caracter que guardara una teclapublic: //Le ponemos tipo publico a los constructores para poder utilizarlos en

// todo el programavoid iniciar(int pj,int com,int r,float p) //Este constructor se dedica a enlazar las{ //variables del main principal con las de las clases por eso se pasan por parametros

pasajeros = pj; //La variable pasajeros sera igual a pjcombustible = com; //La variable combustible sera igual a comruedas = r; //La variable ruedas sera igual a rpeso = p; //La variable peso sera igual a p}; //Fin del constructor iniciarint ob_pasajeros(void) //Constructor tipo entero para obtener el nº de pasajeros{ cout << endl << "Que tipo de moto es ?"; //Datos de salidacout << endl << "Grande: Pulse G - Chica: Pulse C\\n"; //Datos de salidacin >> tipo; //Dato de entrada hacia la variable tipo char llamada tipo

10/06/2009 Ing. Daniel Osorio Maldonado 17

if((tipo == 'g') || (tipo == 'G')) //Si hemos pulsado g o G{ pasajeros=pasajeros+1; } //pasajeros se incrementara 1

if((tipo == 'c') || (tipo == 'C')) //Si hemos pulsado c o C{ pasajeros=pasajeros-1; } //pasajeros se decrementara 1return pasajeros; //Devuelve con return el valor de la variable pasajeros}; //Fin del constructor ob_pasajerosint ob_combustible(void) //Constructor tipo entero para obtener el # de combustib.

{ //Se utiliza el mismo valor anterior con la variable char tipoif((tipo == 'g') || (tipo == 'G')) //Si habiamos pulsado g o G{ combustible=combustible+20; } //El valor de combustible sera 20 masif((tipo == 'c') || (tipo == 'C')) //Si habiamos pulsado c o C{ pasajeros=20; } //El valor de combustible sera 20return combustible; //Devuelve con return el valor de combustible}; //Fin del constructor ob_combustible}; //Fin de la declaracion de la clase variante motocicletamain() //Comienza la funcion principal{int r=2,pj=2,com=20; //Declaramos variables enteras:

//r sera el numero de ruedas//pj sera el numero de pasajeros//com sera el numero de combustible

10/06/2009 Ing. Daniel Osorio Maldonado 18

float p=96.5; //Declaramos variables REAL p será el pesomotocicleta moto; //Declaramos una variable tipo sub-clase moticicleta llamada motomoto.iniciar(pj,com,r,p); //Llamamos al constructor iniciar desde moto, le

// pasamos los parametrospj=moto.ob_pasajeros(); //Asignamos el valor del constructor ob_pasajeros a pj

cout << endl << "Caracteristicas de un ciclomotor"; //Datos de salidacout << endl << "Peso: " << moto.ob_peso() << "kg"; //Datos de salida, llamamos a

ob_pesocout << endl << "Ruedas: " << moto.ob_ruedas(); //Datos de salida, llamamos a

ob_ruedascout << endl << "Pasajeros: " << pj; //Datos de salida, ponemos a mostrar pjcout << endl << "Combustible: " << moto.ob_combustible() << "litros"; //Datos

// de salida, llamamoscout << endl; //a ob_combustiblecin.get(); //Limpia el buffercin.get(); //Espera a que pulses una tecla

} //Fin de la funcion principal

10/06/2009 Ing. Daniel Osorio Maldonado 19

#include<iostream.h>#include<conio.h>#include<math.h>#define PI 2.0*asin(1.0)#include<iomanip.h>

class Punto{protected:float x, y;float radio;float x2, x1, y2, y1;

public:Punto(float r);Punto(float a, float b, float c, float d);double area();double distancia();

};

10/06/2009 Ing. Daniel Osorio Maldonado 20

//Seccion de Implementacion para PuntoPunto::Punto(float r){radio =r;}

Punto::Punto(float a, float b, float c, float d){ x1=a; y1=b; x2=c; y2=d; }

double Punto::area(){ return(0); }

double Punto::distancia(){ return(sqrt(pow(x2-x1,2)+pow(y2-y1,2))) ;}

10/06/2009 Ing. Daniel Osorio Maldonado 21

//declaración de clase donde la clase//Circulo se deriva de Punto

class Circulo: public Punto {protected:float x, y;

public:Circulo (float radio, float m, float n): Punto(radio), x(m), y(n){}double distancia();double area();

};//sección de implementación para el circulo

10/06/2009 Ing. Daniel Osorio Maldonado 22

double Circulo::area( ){ cout<<"(x-"<<x<<")^2+(y-"<<y<<")^2="<<radio<<"^2";return(PI*pow(radio,2)); }

main(){float x1, x2, y1, y2;float a, b, c;

cout<<"\n Las coordenadas del primer punto son: ";cin>>x1;cin>>y1;cout<<"\nLas coordenadas del segundo punto son: ";cin>>x2;cin>>y2;Punto inst(x1,y1,x2,y2);cout<<"\nLa distancia entre estos puntos es:”<<inst.distancia( )<<endl;

10/06/2009 Ing. Daniel Osorio Maldonado 23

cout<<"\nLas coordenadas del circulo son:";cin>>a;cin>>b;

cout<<"\n Ingrese el valor del radio: ";cin>>c;Circulo inst1(a,b,c);cout<<"\n La ecuación y el área del circulo es";inst1.area();

getch();}

10/06/2009 Ing. Daniel Osorio Maldonado 24

Herencia MultipleExisten dos modos en los que una clase derivada puede

heredar mas de una clase base. 1. En el que una clase derivada puede ser usada como

la clase base de otra clase derivada, creándose una jerarquía de clases multinivel. En este caso, se dice que la clase base original es una clase base indirecta de la segunda clase derivada.

2. En el que una clase derivada puede heredar directamente mas de una clase base.

3. En ésta situación, se combinan dos o mas clases bases para facilitar la creación en la clase derivada.

10/06/2009 Ing. Daniel Osorio Maldonado 25

• Cuando se utiliza una clase base para derivar de ellasuna clase, que será empleada como clase base de otra clase derivada, las funciones constructoras de las tres clases son llamadas en el orden de derivación.

• Las funciones destructoras se llaman en orden inverso. • Por lo tanto, si la clase D1 hereda la clase B1 y D2

hereda D1, entonces se llama primero al constructor deB1, seguido del D1 y por último del D2.

• Los destructores son llamados en orden inverso.

• Cuando una clase derivada hereda directamente múltiples clases bases, se utiliza la siguiente sintaxis:

10/06/2009 Ing. Daniel Osorio Maldonado 26

class derived_class_name: acces base1,acces base2,…………….acces baseN

{//.....cuerpo de la clase

}• En esta declaración, base1, hasta baseN son los

nombres de la clase base y access es el especificadordel acceso, que puede ser distinto para cada clasebase.

• Cuando se heredan múltiples clases bases, los constructores se ejecutan de izquierda a derecha, en el que se especifican las clases bases.

• Los constructores se ejecutan en orden opuesto.

10/06/2009 Ing. Daniel Osorio Maldonado 27

• Cuando una clase hereda múltiples clases bases quetienen constructores con argumentos, la clase

derivada les pasa los argumentos que necesitan utilizando la siguiente forma expandida de la función

constructora de la clase derivada:derived_constructor(arg_list):base1(arg_list)

base2(arg_list).......................

baseN(arg_list){//cuerpo del constructor de la clase derivada }

base1 hasta baseN son los nombres de las clasesbases.

• Cuando una clase derivada hereda una jerarquía de clases, cada clase derivada de la cadena debe pasar a su clase base predecesora los argumentos que ésta necesite. Pe:

10/06/2009 Ing. Daniel Osorio Maldonado 28

/*Se muestra una clase derivada que hereda una clase derivada de otra clase. Observe como se pasan los argumentos desde D2 hasta B1 a través de la cadena. */

#include<iostream.h>

#include<conio.h>

class B1{

private: int a;

public: B1(int x){a=x;}

int get_a(){return a;}

};

10/06/2009 Ing. Daniel Osorio Maldonado 29

//Herencia directa de la clase base.

class D1 :public B1{

int b;

public:

D1(int x,int y):B1(y)//paso de y a B1

{ b=x;}

int get_b(){return b;}

};

10/06/2009 Ing. Daniel Osorio Maldonado 30

//Herencia de una clase derivada y de una base indirecta.

class D2 :public D1{

int c;

public:

D2(int x,int y,int z): D1(y,z)//paso de argumentos a D1

{c=x;}

int get_c(){return c;}

/*Puesto que las bases se heredan como publicas, D2 tiene scceso

a los elementos publicos de B1 y D1 */

10/06/2009 Ing. Daniel Osorio Maldonado 31

void show(){

cout<<get_a()<<' '<<get_b()<<' ';

cout <<c<<'\n';}

};

main(){

D2 obje(1,2,3);

//get_a() y get_b() aun no son publicos aqui

cout<<obje.get_a()<<' '<<obje.get_b()<<' '<<obje.get_c();

getch(); } /Resultado : 3 2 1 */

10/06/2009 Ing. Daniel Osorio Maldonado 32

La llamada a obje.show( ) muestra como salida: 3 2 1. • En el Ejemp B1 es una clase indirecta de D2.

•Observe que D2 tiene acceso a los atributos públicos de D1 y de B1. Cuando se heredan los atributos públicos de una clase base, estos se transforman en atributos públicos de la clase derivada. •Por consiguiente, cuando D1 hereda B1, get_a( ) pasa a ser miembro publico de D1 y de D2.•Como muestra el programa, cada clase dentro de una jerarquía de clases debe pasar todos los argumentos necesitados por su clase base precedente. Si así no fuera se generaría un error en tiempo de compilación.

10/06/2009 Ing. Daniel Osorio Maldonado 33

La gerarquia de clases creada por este programa es la siguienteB1

D1

D2Veamos ahora una nueva version del proograma anterior, en la que una clase derivada hereda directamente dos clases base.HERENCIAMULTIPLE2En esta version , D pasa individualmente los argumentos a lasclases B1 y B2.Este programa crea una clase con el siguiente aspecto.

B1 B2

D

10/06/2009 Ing. Daniel Osorio Maldonado 34

El siguiente programa muestra el orden de llamada de las Funciones constructoras y destructoras cuando una clase Derivada hereda directamente multiples clases base.HERENCIAMULTIP3 La salida es: Construccion de B1Construccion de B2Construccion de DDestruccion DDestruccion B2Destruccion B1Se observa que cuando se heredan múltiples clases base de modo directo, los constructores son llamados en el orden, de izquierda a derecha, especificado en la lista de herencia. Los destructores son llamados en orden inverso.