Baixe o app para aproveitar ainda mais
Prévia do material em texto
AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Entendendo HERANÇA EM C++ AUTOR: SERGIO SOUZA NOVAK AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Herança em C++ da Imagine que você está trabalhando como programador numa fábrica de calçados. Você precisa projetar as classes: CALÇADO e a classe SAPATO SOCIAL. Seria interessante que a classe SAPATO SOCIAL herdasse alguns atributos e funções da classe calçado, uma vez que um sapato social também é um calçado. Para tanto, usamos o conceito de herança: 1. #include<iostream> 2. using namespace std; 3. 4. class CALCADO 5. { 6. protected: 7. int numeracao; 8. char marca[30]; 9. char cor[8]; 10. }; 11. 12. class SAPATO_SOCIAL:public CALCADO 13. { 14. bool presenca_de_salto; 15. 16. }; 17. int main() 18. { 19. CALCADO do_dia_a_dia; 20. SAPATO_SOCIAL de_escritorio; 21. return 0; 22. 23. } A herança é útil quando duas classes são próximas, têm características mútuas mas não são iguais e existe uma especificação de uma delas. Portanto, em vez de escrever todo o código novamente é possível poupar algum tempo e dizer que uma classe herda da outra e depois basta escrever o código para a especificação dos pontos necessários da classe derivada (classe que herdou). nesse caso, temos a seguinte situação: AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com A herança do tipo public permite que a classe SAPATO_SOCIAL herde atributos e métodos da classe mãe, a classe CALCADO. E os dados da classe mãe realmente podem ser acessados, o que pode-se perceber fazendo: 1. #include<iostream> 2. #include<string.h> 3. using namespace std; 4. 5. class CALCADO 6. { 7. protected: 8. int numeracao; 9. char marca[30]; 10. char cor[8]; 11. public: 12. int get_numeracao(); 13. CALCADO(); 14. 15. }; 16. CALCADO::CALCADO() 17. { 18. numeracao=0; 19. strcpy(marca,""); 20. strcpy(cor,""); 21. } 22. 23. class SAPATO_SOCIAL:public CALCADO 24. { 25. bool presenca_de_salto; 26. 27. }; 28. 29. int CALCADO::get_numeracao() 30. { 31. return numeracao; 32. } 33. 34. int main() 35. { 36. CALCADO do_dia_a_dia; 37. SAPATO_SOCIAL de_escritorio; AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com 38. cout<<de_escritorio.get_numeracao(); 39. return 0; 40. 41. } A sintaxe: Para fazer com que uma classe de nome <nome_da_classe> herde atributos e métodos de uma classe de nome <nome_da_classe_mãe>, basta fazer: class <nome_da_classe_mãe> { //atributos //Métodos } class <nome_da_classe_filha> : <palavra_reservada_ao_acesso> <nome_da_classe_mãe> {//atributos //Métodos } A <palavra_reservada_ao_acesso> refere-se as palavras public, protected e private. Podemos restringir o acesso o permiti-lo através dessas palavras. Estudo da classe quanto ao acesso: HERANÇA public: AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Classe base herdada como public: Membros públicos (public) da classe base: É como se copiássemos os membros da classe base e os colocássemos como "public" na classe derivada. No final, eles permanecem como públicos. Membros privados (private) da classe base: Os membros estão presentes na classe, porém ocultos como privados. Desta forma as informações estão presentes, mas só podem ser acessadas através de funções publicas ou protegidas da classe base. Membros protegidos (protected) da classe base: Se tivermos membros protegidos (protected) na classe derivada, eles se comportam como se tivessem sido copiados para a classe derivada como protegidos (protected). EXEMPLO: Munhoz & Mariano é uma dupla sertaneja famosa no meio universitário. Suponha que você está elaborando um modelo de calçado para venda numa turnê da dupla. Você, como bom programador que é elaborou o código fonte do programa que exibe os preços na tela: #include<iostream> using namespace std; class CALCADO { private: float preco_de_custo; protected: int numeracao; char marca[30]; char cor[8]; public: float preco_atual; Figura 1:Munhoz&Mariano AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com char pais_onde_foi_fabricado[20]; void get_pais_onde_foi_fabricado(){cout<<pais_onde_foi_fabricado;} void set_preco_atual(){cin>>preco_atual;} }; class SAPATO_CANTOR_SERTANEJO:public CALCADO { protected: float preco_de_sapato_autografado; public: void exibe_preco_parcelado(); SAPATO_CANTOR_SERTANEJO(){ preco_atual= 1500.00;preco_de_sapato_autografado=8000.00;} void exibe_preco_do_autografado(){ cout<<endl<<"Apenas avista : "<<preco_de_sapato_autografado<<" R$"<<endl;} }; void SAPATO_CANTOR_SERTANEJO::exibe_preco_parcelado() { cout<<endl<<"10 x de "<<float(preco_atual)/10; } int main() { CALCADO do_dia_a_dia; SAPATO_CANTOR_SERTANEJO munhoz_e_mariano; munhoz_e_mariano.exibe_preco_parcelado(); cout<<endl<<"A vista: "<<munhoz_e_mariano.preco_atual; cout<<endl<<"Autografado:"; munhoz_e_mariano.exibe_preco_do_autografado(); return 0; } Percebe-se que o programa pode: 1.Formatar várias formas de pagamento para o preço do sapato normal, pois a variável preco_atual é um dado public , logo o sapato pode ser parcelado várias e várias vezes, sendo possível até, posteriormente criar outras formas de pagamento. AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com 2. Já o preço do sapato autografado só pode ser comprado a vista, pois só podemos operar com os dados da variável preco_de_sapato_autografado através da função exibe_preco_do_autografado. Qualquer dúvida basta rever o diagrama das heranças que está a 2 páginas atrás. HERANÇA private: Imagine agora que o cantor humanitário, Bono Vox, daqueles que politicamente corretos que não gostam de muita exposição e não gostam que a mídia fique sabendo a marca do calçado deles resolve adquirir um sapato na sua indústria de calçados. Você, como bom projetista que é, pensa numa classe de calçados para o artista. Você decidiu usar a herança public: #include<iostream> using namespace std; class CALCADO { protected: int numeracao; char marca[30]; char cor[8]; public: char pais_onde_foi_fabricado[20]; void get_pais_onde_foi_fabricado(){cout<<pais_onde_foi_fabricado;} Resumindo: Normalmente quando se declara uma classe no escopo public se usa de dados protected para os dados serem compartilhados tão somente pelas classes mãe e filha(s), se você usar private na classe mãe, é uma forma de restringir apenas para os objetos do tipo da classe mãe. Figura 2: Bono Vox AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com }; class SAPATO_DO_ARTISTA_HUMANITARIO: public CALCADO { bool presenca_de_salto=0; }; int main() { CALCADO do_dia_a_dia; SAPATO_DO_ARTISTA_HUMANITARIO bono_vox; bono_vox.pais_onde_foi_fabricado; return 0; } O seu código não agradou o cliente, pois, conteúdos externos à classe poderiam acessar qual o país que o calçado do bono_vox foi fabricado. Bem, ai temos um dilema: Não podemos declarar como private na classe_mae, classe CALCADO o dado pais_onde_foi_fabricado, pois o governo precisa de tais informações e você deve deixa-las acessíveis. Uma solução seria declarar como private, da seguinte forma: #include<iostream> using namespace std; class CALCADO { protected: int numeracao; char marca[30]; char cor[8]; public: char pais_onde_foi_fabricado[20]; void get_pais_onde_foi_fabricado(){cout<<pais_onde_foi_fabricado;} }; class SAPATO_DO_ARTISTA_HUMANITARIO: private CALCADO { bool presenca_de_salto=0; }; AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com int main() { CALCADO do_dia_a_dia; SAPATO_DO_ARTISTA_HUMANITARIO bono_vox; // bono_vox.pais_onde_foi_fabricado; fica inacessível return 0; } Observa-se que: 1.os dados do pais_onde_foi_fabricado fica inacessível, obtendo o que o cliente deseja. 2.Classes herdadas posteriores não podem alterar os dados herdados da classe CALCADO. Genericamente: Classe base herdada como private: Membros públicos (public) da classe base: Os membros se comportam como se tivessem sido copiados como privados (private) na classe derivada. Membros privados (private) da classe base: Os membros estão presentes na classe, porém ocultos como privados. Desta forma as informações estão presentes, mas não poderão ser acessadas, a não ser por funções da classe base que se utilizem delas. Membros protegidos (protected) da classe base: Os membros se comportam como se tivessem sido copiados como privados (private) na classe derivada. AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Herança protected: Imagine agora que você vai exibir na tela o preço da nova bota da banda OS SERRANOS, banda gaúcha, Os Serranos é um dos poucos conjuntos de música do sul que ainda preserva o tradicionalismo da cultura gaúcha em suas canções. Você vai criar incluir as versões das botas de 1969, 2003 e 2016. A linha de botas que você vai criar deve mostrar onde o calçado foi fabricado somente em alguns modelos, pois, em alguns momentos foi preciso importar couro do Uruguai, e alguns clientes deixariam de comprar uma bota assim, devido ao tradicionalismo, que estimula o boicote ao couro uruguaio. Você deve manter o tradicionalismo entre as botas, pois este é a característica da banda. Vamos lá: #include<iostream> #include<string.h> using namespace std; class CALCADO { private: float preco_de_custo; protected: int numeracao; char marca[30]; char cor[8]; public: float preco_atual; char pais_onde_foi_fabricado[20]; }; class BOTA_DOS_SERRANOS:protected CALCADO { protected: float salto_em_centimetros; AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com char* qualidade_do_couro; }; class BOTA_DOS_SERRANOS_1969:protected BOTA_DOS_SERRANOS { protected: bool fivela_na_bota; public: BOTA_DOS_SERRANOS_1969() {fivela_na_bota=0;strcpy(pais_onde_foi_fabricado,"URUGUAI"); cout<<endl<<"A primeira bota dos serranos tinha "<<fivela_na_bota<<" fivela(s)"<<endl;} }; class BOTA_DOS_SERRANOS_2003:protected BOTA_DOS_SERRANOS_1969 { public: BOTA_DOS_SERRANOS_2003() {fivela_na_bota=1;strcpy(pais_onde_foi_fabricado,"BRASIL");cout<<endl<<"A segunda bota dos serranos tinha "<<fivela_na_bota<<" fivela(s)"<<endl; cout<<"E eh fabricada no: "<<pais_onde_foi_fabricado<<endl;} }; class BOTA_DOS_SERRANOS_2016:protected BOTA_DOS_SERRANOS_2003 { public: BOTA_DOS_SERRANOS_2016(){fivela_na_bota=0;strcpy(pais_onde_foi_fabricado,"BRAS IL");cout<<endl<<"A terceira bota dos serranos tinha "<<fivela_na_bota<<" fivela(s)"<<endl; cout<<"E era fabricada no: "<<pais_onde_foi_fabricado<<endl;} }; int main() { CALCADO do_dia_a_dia; BOTA_DOS_SERRANOS_2016 bota_que_eu_comprei; return 0; } AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Observe que o código: 1. Dados public de CALCADOS são herdados como protected quando a herança é feita de tipo protected. RESUMO: HERANÇA COM RELAÇÃO A CONSTRUTORES Você observou que no exemplo anterior escrevemos no construtor das classes herdadas. Isso não foi feito em vão. iremos agora analisar o que acontece quanto aos construtores na herança: AUTOR: Sergio Souza Novak e-mail: serginhosnovak@hotmail.com Os construtores são herdados de cima para baixo, ou seja, como no exemplo anterior, das botas do grupo OS SERRANOS, exibíamos onde a bota foi feita em cada construção. Logo percebemos que ao criar um objeto de uma classe herdada, os construtores serão invocados e sobrescritos. Isso se trata da característica de polimorfismo na programação orientada a objeto. Observe o que aconteceu quando criamos o objeto da classe BOTA_DOS_SERRANOS_2016:
Compartilhar