• Nenhum resultado encontrado

Herança Múltipla

No documento Apostila3LinguagemCeC++ (páginas 128-132)

16 Herança

16.9 Herança Múltipla

Uma classe pode herdar as características de mais de uma classe. Este processo é chamado de herança múltipla. A construção de hierarquias de herança múltipla envolve mais complexidade do que as hierarquias de herança simples. Esta complexidade diz respeito ao desenho da construção das classes e não à sintaxe de uso. A sintaxe de múltiplas heranças é similar àquela de uma única herança. Eis um exemplo que representa os imóveis à venda de uma imobiliária :

// Heranca Multipla #include <iostream> #include <cstdio> #include <iomanip> #include <string> using namespace std; class Cadastro { private:

char nome[30], fone[20]; public:

Cadastro() { nome[0] = fone[0] = '\0'; } Cadastro(char n[], char f[]) { strcpy(nome, n); strcpy(fone, f); } void GetData() { cout << "\n\tNome: "; cin.getline(nome, 30); cout << "\tFone: "; cin.getline(fone, 20); } void PutData() {

cout << "\n\tNome: " << nome; cout << "\n\tFone: " << fone; }

};

class Imovel {

private:

char end[30], bairro[20]; float AreaUtil, AreaTotal; int quartos; public: Imovel() { end[0] = bairro[0] = '\0'; AreaUtil = AreaTotal = 0; quartos = 0; }

Imovel(char e[], char b[], float au, float at, int q) {

Curso de Linguagem Computacional C/C++

strcpy(end, e); strcpy(bairro,b); AreaUtil = au; AreaTotal = at; quartos = q; } void GetData() {

cout << "\n\tEnd: "; cin.getline(end, 30); cout << "\tBairro: "; cin.getline(bairro, 20); cout << "\tArea Util: "; cin >> AreaUtil; cout << "\tArea Total: "; cin >> AreaTotal; cout << "\tNo. Quartos: "; cin >> quartos; }

void PutData() {

cout << "\n\tEnd : " << end;

cout << "\n\tBairro : " << bairro;

cout << "\n\tArea Util : " << setiosflags(ios::fixed) << setprecision(2) << AreaUtil

<< "\n\tArea Total : " << AreaTotal << "\n\tQuartos : " << quartos; } }; class Tipo { private:

char tipo[20]; // Residencial, Loja, Galpao public: Tipo() { tipo[0] = '\0'; } Tipo(char t[]) { strcpy(tipo, t); } void GetData() { cout << "\n\tTipo : "; cin.getline(tipo, 20); } void PutData() {

cout << "\n\tTipo: " << tipo; }

};

class Venda : private Cadastro, public Imovel, public Tipo {

private:

float valor; public:

Venda() : Cadastro(), Imovel(), Tipo() {valor = 0;} Venda(char n[], char f[], char e[], char b[],

float au, float at, int q, char t[], float v) : Cadastro(n,f), Imovel(e,b,au,at,q), Tipo(t) { valor = v; }

void GetData() {

Curso de Linguagem Computacional C/C++

cout << "\n ...Proprietarios: "; Cadastro::GetData(); cout << "\n ...Imovel: "; Imovel::GetData(); Tipo::GetData();

cout << "\tValor R$ : "; cin >> valor; } void PutData() { cout << "\n ...Proprietario: "; Cadastro::PutData(); cout << "\n ...Imovel: "; Imovel::PutData(); Tipo::PutData();

cout << "\n\tValor R$ : " << valor; }

};

int main(int argc, char* argv[]) {

Venda C,V("Eduardo Mattos", "3203322", "Rua Rocha, 33", "Coqueiros", 50.0, 75.0, 2, "Comercial", 80000.0 );

cout << "\n\n* Imovel Para Venda : "; V.PutData();

cout << "\n\n Digite um Imovel para Vender!\n"; C.GetData(); C.PutData();

return 0; }

Através da declaração:

class Venda : private Cadastro, public Imovel, public Tipo { ... };

notificamos o compilador que a classe Venda é derivada das classes Cadastro, Imovel e

Tipo. Cadastro tem derivação do tipo privada enquanto que as demais classes têm derivações do tipo públicas. Muitas vezes podemos substituir uma herança por um objeto da classe-base. A escolha de qual método devemos aplicar depende muito do modelo adotado e do desempenho esperado. Uma boa modelagem pode definir claramente quais serão as classes criadas e como elas deverão iteragir.

Os construtores da classe Venda são os seguintes:

Venda() : Cadastro(), Imovel(), Tipo() {valor = 0;} Venda(char n[], char f[], char e[], char b[],

float au, float at, int q, char t[], float v) : Cadastro(n,f), Imovel(e,b,au,at,q), Tipo(t) { valor = v; }

Note que a definição de um construtor de uma classe com herança múltipla é muito similar ao construtor de uma classe com herança simples. Ao chamar os construtores das classes-bases, devemos lembrar que os nomes dos construtores são colocados após os dois-pontos e separados por vírgulas. A ordem de chamada é a mesma da ordem em que eles aparecem escritos. Parâmetros podem ser passados assim como em qualquer outro construtor.

As funções GetData() e PutData() da classe Venda incorporam a chamada às funções correspondentes das classes Cadastro, Imovel e Tipo empregando o operador de resolução de escopo (::) para efetuar a chamada das funções das classes base:

Curso de Linguagem Computacional C/C++

Cadastro::GetData(); Imovel::GetData(); Tipo::GetData(); Cadastro::PutData(); Imovel::PutData(); Tipo::PutData();

Alguns tipos de problemas podem aparecer em certas situações envolvendo herança múltipla. O mais comum é quando duas classes-base têm, cada uma delas, uma função de mesmo nome (protótipo), enquanto a classe derivada destas duas não tem nenhuma função com este nome. Quando a função é acessada por meio de um objeto da classe derivada, o compilador não reconhecerá qual das duas estará sendo chamada. Para informar ao compilador qual das duas funções está sendo solicitada, devemos utilizar o operador de resolução de escopo (::). Por exemplo, podemos chamar a função PutData() da classe Imovel com um objeto da classe

Venda através da instrução:

C.Imovel::PutData();

Caso a classe derivada não contivesse esta função, este seria o único método de acesso a esta função sem causar um erro de ambiguidade.

16.10

Exercícios

16.1 No início começamos discutindo a modelagem de um banco orientado a objetos. Termine o programa que modela as pessoas que compõem o ambiente banco : acionista, cliente, funcionário, cliente-universitário, pessoa-física, pessoa-jurídica, etc.

16.2 Crie uma classe Empresa capaz de armazenar os dados de uma empresa (Nome, End, Cidade, Estado, CEP, CGC, Fone e E-mail). Use a classe Empresa como base para criar a classe Restaurante. Inclua o tipo de comida, o preço médio de um prato, funções para adquirir os seus dados e para imprimí-los na tela. Sobrecarrega o operador ostream <<.

16.3 Imagine que você deva escrever um programa para armazenar veículos. Primeiramente, crie a classe Motor que contém NumCilindro e Potencia. Inclua um construtor com argumentos com valores default que inicialize os dados com zeros e um construtor de cópia. Escreva a classe Veículo contendo peso, velocidade máxima e preço. Crie a classe CarroPasseio usando as classes Motor e Veículo como base. Inclua cor e modelo. Crie a classe caminhão derivada das classes Motor e Veículo. Inclua a carga máxima, altura máxima e comprimento. Crie um programa para o controle de um estacionamento que tenha uma área fixa e controle o acesso de veículos no estacionamento. Verifique se um veículo pode ou não estacionar antes de permitir a entrada. Se puder, indique onde este deve estacionar. Reflita sobre o problema, crie um modelo e decida quais propriedades dos veículos devem ser descritas. Aceite as propriedades propostas como sugestões mas crie o seu próprio programa.

16.4 Um robô pode ser composto por três tipos de motores : motor de corrente contínua, motor de passo e motor assíncrono. Um robô pode conter juntas com movimento angular (geram uma variação no ângulo entre dois elos), transversal (geram um deslocamento linear dos elos) ou juntas que não geram movimento nenhum, simplesmente ligam dois elos. Cada elô pode ser uma barra reta ou uma curva suave de 90 graus. Um robô pode ter uma garra para pegar objetos, uma garra para fazer operações de soldagem e uma garra para fazer operações de pintura. Modele um robô segundo as considerações acima, definindo a geometria do robô e como será o movimento deste. Crie um robô que seja capaz de pintar a parte superior de uma mesa, soldar em cima desta uma caixa. A mesa esta a 50 cm na frente do robô e a caixa está a 50 cm à direita do robô.

Curso de Linguagem Computacional C/C++

No documento Apostila3LinguagemCeC++ (páginas 128-132)

Documentos relacionados