Upload
others
View
20
Download
0
Embed Size (px)
Citation preview
Programação de Computadores 277
Herança! Para entender a importância precisamos conhecer a
história da reutilização.! Inicialmente aproveitamento de código já escrito,
adaptando para o novo ambiente " depurar novamente o código " geralmente preferimos escrever tudo de novo.
! Biblioteca de funções " criar elementos de programação na forma de funções " também necessitam de mudanças dependendo do ambiente.
! Biblioteca de classes " novo modelo para reutilização " POO fornece uma forma eficiente para modificar uma classe sem alterar o seu código " herança "derivar uma nova classe a partir de outra.
Programação de Computadores 278
! A classe existente (classe base) não é modificada, mas a nova classe (derivada) pode usar todas as características da classe base e adicionar as suas próprias.
característica A
característica B
característica C
Classe Base
característica A
característica B
característica C
característica D
classe derivada
a seta significa derivada de
Definida na classe base masacessível na classe derivada
Definida somente na classe derivada
Programação de Computadores 279
! Herança em POO espelha o conceito chamado generalização do mundo real
! bicicleta de corrida, bicicleta para trilha, bicicleta de criança " instâncias específicas da classe geral bicicleta " todas tem duas rodas, quadro, freio etc, mas acrescentam características específicas.
! Folha de pagamento de empresa " empregados"operários, gerentes, executivos, etc...
! Mamíferos " gatos , humanos, macacos etc...! Veículos " automóveis, ônibus, caminhões! Computadores " pc e macintosh
Programação de Computadores 280
! Sintaxe: class base{ ... dados e funções membro;};class derivada: public base{ ... dados e funções membro;};
! A classe derivada “herda” todos os dados e funções da classe base
! especificador de acesso : public, private e protected "veremos detalhes mais a frente.
Programação de Computadores 281
class base{ float b ;
public:void bget( ){ cout<<endl<<“Entre com um nro real:”;
cin>>b ;}
void bmostra( ){ cout<< “b=“<<b<<endl; }
};
Programação de Computadores 282
classe derivada:public base{ int d;public:void dget( ){ bget( );cout<<“Entre com um valor inteiro:”;cin>>d;
}void dmostra( ){ bmostra( );
cout<<“d=“<<d<<endl;}
};
Programação de Computadores 283
void main( ){ derivada d;
cout<< “Requisitando dados da classe derivada:”;d.dget( );cout<<“Mostrando o objeto derivado:”;d.dmostra( );
}Requisitando dados da classe derivadaEntre com um valor real: 456.98Entre com um valor inteiro: 23b = 456.98d = 23
Programação de Computadores 284
! Um objeto da classe derivada “herda” todos os dados e funções membro da classe base. Dessa forma no nosso exemplo, a classe derivada contem alem do dado inteiro d, o real b.
! Um objeto da classe derivada pode acessar seu dado através das suas funções dget( ) e dmostra( ) e das funções membro da classe parente fget() e fmostra().
! Apesar do objeto da classe derivada conter os dados definidos na classe base, isso não significa que esses dados são acessíveis diretamente na classe derivada.
Programação de Computadores 285
! Suponha que tivéssemos escrito a função dmostra como a seguir:classe derivada{ ...
void dmostra( ){ cout<<“b=“<<b<<endl;// ERRO: membro
privado da classe basecout<<“d=“<<d<<endl;
}};
Programação de Computadores 286
! Sobrecarga de funções na classe base e derivadaclass base{ float b ;public:void get( ) { cout<<endl<<“Entre com um nro real:”;
cin>>b ; }void mostra( ) { cout<< “b=“<<b<<endl; }
};classe derivada:public base{ int d;public:void get( ) { base::get( );
cout<<“Entre com um valor inteiro:”; cin>>d; }void mostra( ){ base::mostra( ); cout<<“d=“<<d<<endl;}
};
Programação de Computadores 287
//ponto.h#include <iostream.h>#ifndef ponto_h#define ponto_hclass ponto{ protected:
int x, y;//coordenadas de um pontopublic:
ponto( int=0,int=0);void seta_ponto(int,int);int pega_x( ) const {return x;}int pega_y( ) const {return y;}friend ostream& operator<<(ostream&, const ponto&);
};#endif
Programação de Computadores 288
//ponto.cpp#include “ponto.h”#include <iostream.h>ponto::ponto(int a, int b) { seta_ponto(a,b);}void ponto::seta_ponto( int a, int b){ x = a; y = b;}ostream& operator<<(ostream& s,const ponto& p){ s<<“[“<<p.x<<“,”<<p.y<<“]”;
return s;}
Programação de Computadores 289
// circulo.h#ifndef circulo_h#define circulo_h#include <iostream.h>#include “ponto.h”class circulo: public ponto{ protected:
double raio;public:
circulo(double r=0.0, int x=0,int y=0) ;void seta_raio(double r) { raio = r; }double pega_raio( ) const { return raio;}double area( ) const { return 3.14159*raio*raio;}friend ostream& operator<<(ostream&, const circulo&);
};#endif
Programação de Computadores 290
//circulo.cpp#include “circulo.h”#include <iostream.h>#include <iomanip.h>circulo::circulo(double r, int a, int b):ponto(a,b){ seta_raio( r );} ostream& operator<<(ostream& s, const circulo& c){ s <<“Centro= “<< static_cast< ponto >(c)
<< “;Raio=“<<setiosflags(ios::fixed | ios::showpoint)<<setprecision(2)<< c.raio;
return s;}
Programação de Computadores 291
#include "circulo.h"#include "ponto.h"void main( ){ ponto p(30,50);
circulo c(2.7,120,89);cout<<"Ponto p:"<<p<<endl
<<"Circulo c:“<<c<<endl;}
! Note que a sobrecarga do << na classe circulo é capaz de escrever a parte referente a ponto do circulo através da transformação da referência c para um ponto.O resultado é a chamada do operador<< para ponto e a impressão usando a sobrecarga do operador para ponto.
Programação de Computadores 292
! Pode existir mais que dois níveis de herançaclass alfa{ ...};class beta:public alfa{ ...};class gama: public beta{...};class delta: public gama{ ...};
! A classe tem acesso a todos os seus ancestrais. Na herança pública, as funções membros de delta podem acessar os dados públicos e protegidos das classe gama, beta e alfa.
Programação de Computadores 293
classe empregado
classe gerente classe cientista classe operário
classe capataz
Vamos desenvolver um exemplo, partindo de uma classe empregado bastante simples.
Programação de Computadores 294
! classe empregado" nome e número! classe gerente" nome, número, cargo (vice
presidente, presidente, gerente geral, etc...) ! classe cientista " nome, número, número de
patentes! classe operário " nome, número! classe capataz (operários que operam máquinas
perigosas) " nome, número, cota de produção
Programação de Computadores 295
class empregado{ char nome[80]; //nome
unsigned long nro; //númeropublic:void entra_dados( ){ cout<<“Entre com o sobrenome e o nome:”;
cin>>nome;cout<<“Entre com o número:”; cin>>nro;
}void mostra_dados( ){ cout<<endl<<“Nome=“<<nome;
cout<<endl<<“Número=“<<nro;}
};
Programação de Computadores 296
class gerente: public empregado{ char titulo[30];
public:void entra_dados( )
{ empregado::entra_dados( );cout<<“Entre com o cargo:”; cin>>titulo;
}void mostra_dados( )
{ empregado::mostra_dados( );cout<<“Cargo ocupado:”<<titulo;
}};
Programação de Computadores 297
class cientista: public empregado{ int patentes;
public:void entra_dados( )
{ empregado::entra_dados( );cout<<“Entre com o número de patentes:”; cin>>patentes;
}void mostra_dados( )
{ empregado::mostra_dados( );cout<<“Número de patentes:”<<patentes;
}};
Programação de Computadores 298
class operario: public empregado{ };class capataz: public operario{ int cota;
public:void entra_dados( ){ operario::entra_dados( );cout<<“Entra com a cota de produção:”;cin>>cota;
}void mostra_dados( ){ operario::mostra_dados( );
cout<<“Cota de produção:”<<cota;}
};
Programação de Computadores 299
void main( ){ operario op;
capataz ca;cout<<“Entre com os dados do operário:”;op.pega_dados( );cout<<“Entre com os dados do capataz:”;ca.pega_dados( );cout<<“Dados do operario:”<<op.mostra_dados();cout<<“Dados do capataz:”<<ca.mostra_dados( );
}
Programação de Computadores 300
Herança Múltipla! Ocorre quando uma classe é derivada de duas ou
mais classesclass base1{ ...};class base2{ ...};class deriv: public base1, public base2{ ...} ;
Programação de Computadores 301
! Usando a classe empregado e suas derivadas, suponha que queremos incluir as qualificações educacionais de alguns tipos de empregados "podemos desenvolver uma classe chamada nivel_educacional que incorpore os dados necessários e utilizamos essa classe na nossa herança.
! A classe empregado continua exatamente a mesma.
! A classe operário e capataz não mudará.! As classes gerente, cientista terão herança
múltipla.
Programação de Computadores 302
class nivel_educacional{ char escola[80]; //nome da escola
char titulacao[40]; //grau mais alto obtidopublic:
void pega_dados( ){ cout<<“Entre com o nome do Colégio ou da
Universidade:”; cin>>escola;cout<<“Entre com o maior grau obtido (Colegial,
Bacharelado, Mestrado, Doutorado):”;cin>> titulacao;
}void mostra_dados( ){ cout<<endl<<“Colegio ou Universidade:”<<escola;
cout<<endl<<“Maior grau obtido:”<<titulacao;}
};
Programação de Computadores 303
class gerente: public empregado, public nivel_educacional{ char titulo[30];
public:void entra_dados( )
{ empregado::entra_dados( );cout<<“Entre com o cargo:”; cin>>titulo;nivel_educacional::entra_dados( );
}void mostra_dados( )
{ empregado::mostra_dados( );cout<<“Cargo ocupado:”<<titulo;nivel_educacional::mostra_dados( );
}};
Programação de Computadores 304
class cientista: public empregado, public nivel_educacional{ int patentes;
public:void entra_dados( )
{ empregado::entra_dados( );cout<<“Entre com o número de patentes:”;cin>>patentes;nivel_educacional::entra_dados( );
}void mostra_dados( )
{ empregado::mostra_dados( );cout<<“Número de patentes:”<<patentes;nivel_educacional::mostra_dados( );
}};