AULA 10 - Programação II - Graduação
HERANÇA
Herança é um dos pontos chave de programação orientada a objetos (POO).
Ela fornece meios de promover a extensibilidade do código, a reutilização e uma maior coerência lógica no modelo de implementação.
Estas características nos possibilitam diversas vantagens, principalmente quando o mantemos bibliotecas para uso futuro de determinados recursos que usamos com muita frequência.
Uma classe de objetos "veiculo", por exemplo, contém todas as características inerentes aos veículos, como:
- combustível,
- autonomia,
- velocidade máxima,
- etc.
Agora podemos dizer que "carro" é uma classe que têm as características básicas da classe "veículo" mais as suas características particulares.
Analisando esse fato, podemos concluir que poderíamos apenas definir em "carro" suas características e usar "veículo" de alguma forma que pudéssemos lidar com as características básicas. Este meio chama-se herança.
Agora podemos definir outros tipos de veículos como:
- moto,
- caminhão,
- trator,
- helicóptero,
- etc,
sem ter que reescrever a parte que está na classe "veículo". Para isso define-se a classe "veículo" com suas características e depois cria-se classes específicas para cada veículo em particular, declarando-se o parentesco neste instante.
Exemplo:
Imagine que já exista uma classe que defina o comportamento de um dado objeto da vida real, por exemplo, animal. Uma vez que eu sei que o leão é um animal, o que se deve fazer é aproveitar a classe animal e fazer com que a classe leão derive (herde) da classe animal as características e comportamentos que a mesma deve apresentar, que são próprios dos indivíduos classificados como animais.
Ou seja, herança acontece 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).
Através da herança, cria-se novas classes, chamadas de SUB-CLASSES ou CLASSES DERIVADAS, baseadas em uma classe já existente, chamada de SUPER-CLASSE ou CLASSE-BASE.
A classe derivada “herda” todas as características da classe-base, além de poder incluir suas características próprias.
Em resumo, o maior objetivo do uso do mecanismo de herança é a REUTILIZAÇÃO DE CÓDIGO, para facilitar o desenvolvimento e também para criação de BIBLIOTECAS.
É preciso ter o arquivo de código-objeto da super-classe (não o arquivo-fonte).
Sintaxe:
Para declarar uma classe derivada de outra já existente, procedemos de forma a declarar o parentesco e o grau de visibilidade (acesso) que a classe derivada terá dos membros de sua classe base.
Para isso seguimos o seguinte código sintático:
class NomeSubclasse: [Modificador de acesso] NomeSuperclasse
{ ...
//Características próprias da subclasse
...
};
Repare que temos o operador ":" ( dois pontos ) como elo entre as duas classes. Este operador promove o "parentesco" entre as duas classes quando é usado na declaração de uma classe derivada.
O termo [Modificador de acesso] é opcional, mas se estiver presente deve ser public, private ou protected. Por "defaut" (padrão) temos o private, ou seja, se o modificador não estiver presente, o compilador usará "private" durante a interpretação do código.
Ele define o grau de visibilidade dos membros da classe base quando a classe derivada precisar acessá-los.
Exemplo:
Na implementação acima temos a classe base veiculo_rodoviario e duas classes derivadas “:” caminhao e automovel.
Podemos notar que as características comuns a todos os tipos de veículos, rodas e passageiros, estão na classe base, enquanto as características exclusivas de cada tipo de veículo estão nas classes derivadas.
Desta forma podemos definir procedimentos especializados para cada classe, fazendo com que todas as eventuais modificações feitas ao longo da implementação na classe base sejam estendidas a todos os objetos criados a partir das classes derivadas no programa.
Repare ainda um pormenor: tanto a classe "caminhao" quanto a automovel têm como função membro o método mostrar(), mas uma não interfere com a outra. Isto ilustra um outro aspecto da orientação a objeto, o polimorfismo. Este será exposto em mais detalhe nos capítulos subsequentes.
Também no Visual C++ utilizamos herança. Na verdade, o próprio aplicativo utiliza herança para gerar os controles dos projetos visuais. Por exemplo, quando criamos um novo projeto no VC++, um formulário da classe Form1 é criado.
Esta classe é, na verdade, uma herança da classe mais geral Form:
class Form1 : public Form
{
...
};
Exercício:
- Expanda as classes carro e caminhao, para que tenham construtores, e os atributos e métodos possam ser colocados como privados.
- Expanda a classe veiculorodoviario, para que esta também tenha um construtor. O que acontece aqui? Analise quando o construtor da classe-mãe será chamado.
- Sobrecarregue os construtores das classes carro e caminhao para que leiam ou atribuam valores padrão aos atributos.
Código da Classe Veículos e sub-classes
Modificadores de Acesso:
Quando uma classe herda outra, os membros da classe base são incorporados como membros da classe derivada.
Devido à separação das classes e do controle de acesso às variáveis em cada classe, devemos pensar como as restrições de acesso são gerenciadas em classes diferentes, principalmente o acesso a membros da classe base a partir das classes derivadas.
O acesso dos membros da classe base à classe derivada é determinado pelo especificador de acesso: public, private e protected.
Assim ficamos com as possíveis combinações
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).
Como as classes derivadas não têm acesso a membros PRIVADOS da classe base, utiliza-se o modificador PROTECTED. Assim, as subclasses podem ALTERAR atributos da superclasse, sem torná-los publicos.
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.
Classe base herdada como Protected:
- Membros públicos (public) da clase base:
Se comportam como se tivéssemos copiado-os como protegidos (protected) 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:
Se comportam como se estivéssemos copiado-os como protegidos (protected) na classe derivada.
As classes derivadas não têm acesso aos membros privados da classe base.
Para que as subclasses possam alterar atributos da superclasse, sem torná-los públicos: definí-los como protected.
Exemplo:
class Base {
public: int publico;
private: int privado;
protected: int protegido;
};
class Derivada : public Base
{ public: int a, b, c;
Derivada( ) {
a = publico; // Ok!
b = protegido; //Ok!
c = privado; } // ERRO!
};
Aqui está um exemplo muito simples:
Em suma, estas regras podem ser sintetizadas em uma regra muito simples:
Prevalece o atributo mais restritivo.
Para isto basta-nos listar os atributos por ordem de restrições decrescente:
- private
- protected
- public
Assim, temos todas as combinações definidas quando colocamos um atributo combinado com o outro, bastando para isto escolher sempre o mais restritivo na combinação.
Por exemplo: Quando temos uma variável pública na base e a herança é privada, a combinação resulta em uma variável privada na classe derivada.
Implementação da classe derivada:
Existem algumas particularidades na implementação de uma subclasse:
Construtor da classe derivada
Pode utilizar o construtor da classe base. Exs:
class Quadrado : public Retangulo
{ public:
Quadrado() : Retangulo() { ...}
Quadrado(int x1, int y1, int x2, int y2) : Retangulo(x1, y1, x2, y2) {...}
...
};
class Quadrado : public Retangulo
{ public:
Quadrado(int x1, int x2, int y1, int y2)
{
if(abs(x2 – x1) == abs(y2 – y1))
Retangulo::Retangulo(x1, y1, x2, y2);
else
ShowMessage(“Coordenadas inválidas para quadrado”);
...
};
Métodos da classe derivada também podem chamar métodos (públicos ou protegidos) da classe base usando a sintaxe
Classe_base::Método_classe_base( );
Se a classe derivada não possuir construtor – construtor da classe base é chamado.
Se este construtor da classe base não for default, ou não possuir valores default e não forem passados argumentos ⇒ ERRO!
Além de herança simples, uma classe pode ser derivada de mais de uma classe base ⇒ Herança múltipla!
Um método na classe derivada pode sobrecarregar um método da classe base : redefinir usando mesmo nome!
Ex:
class Quadrado : public Retangulo
{ public: // Métodos da classe base sobrecarregados na derivada:
long int Calcula_Area( );
long int Calcula_Perimetro( );
...
};
long int Quadrado::Calcula_Area( )
{ return(base*base); }
long int Quadrado::Calcula_Perimetro()
{ return(4*base); }
Heranças Múltiplas
A herança múltipla entre classes ocorre sempre que uma subclasse possui duas ou mais superclasses imediatas, ou seja, é "filha" de mais de uma classe.
Através da herança múltipla é possível combinar as características de várias superclasses existentes como um ponto de partida para a definição de uma nova classe.
A sintaxe de definição de uma classe com múltiplas superclasses é a seguinte:
class <nome_classe_derivada> : <especif_acesso> <nome_classe_base1>, <especif_acesso> <nome_classe_base2>, ..., <especif_acesso> <nome_classe_baseN>
{ //membros da classe };
, onde
- <especif_acesso> pode ser private, public ou protected.
Caso não seja colocado nenhum especificador de acesso, assume-se private como default.
Para exemplificar, considere a definição de uma classe "clock", cujos objetos armazenam o tempo, e uma classe "calendar", cujos objetos armazenam a data. Pode-se então usar a herança múltipla para derivar uma nova classe "clock_calendar", cujos objetos armazenam ambos, o tempo e a data.
A figura mostra a hierarquia destas três classes.
Exemplo de herança múltipla
A classe "clock" é definida da seguinte maneira:
class clock {
protected:
int hr;
int min;
int sec;
int is_pm;
public:
clock(int h, int m, int s, int pm);
void set_clock (int h, int m, int s, int pm);
void read_clock (int &h, int &m, int &s, int &pm);
void advance();
};
Nesta classe, as variáveis "hr", "min" e "sec" guardam, respectivamente, as horas, os minutos e os segundos.
A variável "is_pm" é 0 para A.M. e 1 para P.M.
O construtor "clock()" cria um novo relógio e determina a hora de acordo com os parâmetros recebidos; "set_clock()" seta a hora corrente para a hora passada como parâmetro; "read_clock()" retorna a hora corrente através de seus parâmetros de referência; e "advance()" avança o relógio em um segundo.
A classe "calendar" é similar à "clock":
class calendar {
protected:
int mo;
int day;
int yr;
public:
calendar(int m, int d, int y);
void set_calendar (int m, int d, int y);
void read_calendar (int &m, int &d, int &y);
void advance();
};
As variáveis "mo", "day" e "yr" guardam a data, isto é, mês, dia e ano, respectivamente.
O construtor "calendar()" cria um calendário e determina a data de acordo com os parâmetros recebidos; "set_calendar()" seta um calendário existente para a data passada como parâmetro; "read_calendar()" retorna a data corrente através de seus parâmetros de referência; e "advance()" avança a data em um dia.
Agora pode-se definir a classe "clock_calendar":
class clock_calendar : public clock, public calendar {
public:
clock_calendar(int mt, int d, int y, int h, int mn, int s, int pm);
void advance();
};
É possível observar que, após o nome da classe e os dois pontos, aparece uma lista de todas as superclasses a partir das quais a classe é derivada. Cada superclasse pode ser especificada individualmente como public, private ou protected.
Como é desejado que "clock_calendar" ofereça as funções herdadas de "clock" e "calendar", ambas são declaradas como públicas.
Torna-se importante salientar que, analogamente ao que ocorria na herança simples, a subclasse em
uma herança múltipla pode acessar os construtores de suas superclasses. Para efetivar as chamadas, deve-se
generalizar a sintaxe vista no estudo de herança simples.
A definição do construtor de uma subclasse de mais de uma superclasse pode fazer chamadas a construtores da base.
Para tal, o construtor da derivada deve ter como parâmetros os que ele mesmo usa e os que deseja passar aos construtores das bases.
Exemplo 1:
Outra implementação da herança múltipla, para uma classe de hora e data:
#include <iostream>
#include <stdlib.h>
using namespace std;
class Horario { /***** SUPER CLASSE Horario*****/
private:
void VerificaHorario();
protected:
int horas;
int minutos;
int segundos;
public:
Horario();
};
Horario::Horario() //Construtor de Horario
{
VerificaHorario();
}
void Horario::VerificaHorario()
{ int horavalida = 0, minutovalido = 0, segundovalido = 0;
while(!horavalida)
{ cout << "\nInforme a hora (0-23)" << endl;
cin >> horas;
if(horas <0 || horas>23)
cout<< "\nErro na hora fornecida!!! Entre com um valor entre 0 e 23\n\n";
else{ horavalida = 1; }
}
while(!minutovalido) {
cout << "\nInforme os minutos (00-59)" << endl; //*********
cin >> minutos;
if(minutos<0 || minutos > 59)
cout<< "\nErro nos minutos fornecidos!!! Entre com um valor entre 0 e 59\n\n";
else
minutovalido = 1;
}//while
while(!segundovalido)
{
cout << "\nInforme os segundos" << endl;
cin >> segundos;
if (segundos <0 || segundos > 59)
cout<< "\nErro nos segundos fornecidos!!! Entre com um valor entre 0 e 59\n";
else
segundovalido = 1;
}
cout << "\nHorario Atual:" << ((horas<10)?" 0":" ") <<horas<< ":"<< ((minutos<10)?" 0":" ")<<minutos << ":" << ((segundos<10)?" 0":" ")<<segundos<< endl;
cout << "\n";
}
class Calendario { /***** SUPER CLASSE Calendario *****/
public:
void VerificaData();
protected:
int dia;
int mes;
int ano;
public:
Calendario();
};
Calendario::Calendario() //Construtor de Calendario
{
VerificaData();
}
void Calendario::VerificaData()
{ int diavalido = 0, mesvalido = 0, anovalido = 0;
while(!diavalido)
{ cout << "\nInforme o dia (1-31)" << endl;
cin >> dia;
if(dia <1 || dia>31)
cout<< "\nErro no dia fornecido!!! Entre com um valor entre 1 e 31\n\n";
else{ diavalido = 1; }
}
while(!mesvalido) {
cout << "\nInforme o mes (1-12)" << endl; //*********
cin >> mes;
if(mes<1 || mes > 12)
cout<< "\nErro no mes fornecido!!! Entre com um valor entre 1 e 12\n\n";
else
mesvalido = 1;
}//while
while(!anovalido)
{
cout << "\nInforme o ano (0-2019)" << endl;
cin >> ano;
if (ano <0 || ano > 2020)
cout<< "\nErro no ano fornecido!!! Entre com um valor entre 0 e 2018\n";
else
anovalido = 1;
}
cout << "\nHoje \202 dia: " << dia ;
switch(mes)
{ case 1: cout <<" de Janeiro "; break;
case 2: cout << " de Fevereiro "; break;
case 3: cout << " de Março "; break;
case 4: cout << " de Abril "; break;
case 5: cout << " de Maio "; break;
case 6: cout << " de Junho "; break;
case 7: cout << " de Julho "; break;
case 8: cout << " de Agosto "; break;
case 9: cout << " de Setembro "; break;
case 10: cout << " de Outubro "; break;
case 11: cout << " de Novembro "; break;
case 12: cout << " de Dezembro "; break;
}
cout << " de " << ano << ".\n\n";
}
class DataHora: public Horario, public Calendario{ /*** HERANÇA MULTIPLA ***/
};
int main() //Código Cliente
{ DataHora hoje; /*** Objeto da Classe-filha DataHora, herança de Horario e Calendario ***/
cout << "\n\n" << endl;
return 0;
}
Exemplo 2:
Implementar a classe caminhao como herança múltipla de veiculorodoviario e também de maquina:
class caminhao: public veiculorodoviario, public maquina{
...
}
#include <iostream>
#include <stdlib.h>
using namespace std;
enum tipouso {cargas, pessoas, animais};
enum tipomecanismo {mecanico, eletronico, automatico};
enum tipoalimentacao {eletricidade, gasolina, diesel};
class maquina{ /***** SUPER CLASSE *****/
protected:
tipouso ItemTransportado;
tipomecanismo Mecanismo;
tipoalimentacao Combustivel;
public:
maquina();
};
maquina::maquina()
{
char c;
cout<<"\nEntre com o tipo de item que o caminhao transporta: "<<endl;
cout<<"\t\t(1) CARGA \n"<< endl;
cout << "\t\t(2) PESSOAS \n"<< endl;
cout << "\t\t(3) CARGA VIVA (ANIMAIS) \n"<< endl;
cin>> c;
switch(c)
{
case '1':
case 'c':
case 'C': ItemTransportado = cargas; break;
case '2':
case 'p':
case 'P': ItemTransportado = pessoas; break;
case '3':
case 'V':
case 'v': ItemTransportado = animais; break;
default: ItemTransportado = cargas;
}
cout<<"\nEntre com as caracteristicas do caminhao: "<<endl;
cout<<"\t\t(1) Totalmente Mecanico \n"<< endl;
cout << "\t\t(2) Eletronico \n"<< endl;
cout << "\t\t(3) Automatico \n"<< endl;
cin>> c;
switch(c)
{
case '1':
case 'm':
case 'M': Mecanismo = mecanico; break;
case '2':
case 'e':
case 'E': Mecanismo = eletronico; break;
case '3':
case 'A':
case 'a': Mecanismo = automatico; break;
default: Mecanismo = mecanico;
}
cout<<"\nEntre com o tipo de combustivel ou tracao "<<endl;
cout<<"\t\t(1) CAMINHAO ELETRICO \n"<< endl;
cout << "\t\t(2) MOVIDO A GASOLINA \n"<< endl;
cout << "\t\t(3) MOVIDO A OLEO DIESEL \n"<< endl;
cin>> c;
switch(c)
{
case '1':
case 'c':
case 'C': Combustivel = eletricidade; break;
case '2':
case 'p':
case 'P': Combustivel = gasolina; break;
case '3':
case 'V':
case 'v': Combustivel = diesel; break;
default: Combustivel = diesel;
}
}
class veiculo_rodoviario{ /***** SUPER CLASSE *****/
private:
int nrodas;
int npassageiros;
public:
veiculo_rodoviario();
void setanrodas(int n)
{nrodas = n;}
int pegarodas()
{return nrodas;}
void setanpassageiros(int m){npassageiros = m;}
int pegapassageiros(){return npassageiros;}
};
veiculo_rodoviario::veiculo_rodoviario()
{ int x;
cout<< "\n\n **** REGISTRO DE NOVO VEICULO RODOVIARIO **** \n"<<endl;
cout<<"Entre com o numero de rodas do veiculo: "<<endl;
cin>> x;
setanrodas(x);
cout<<"\nEntre com o numero de passageiros que o veiculo pode transportar: "<<endl;
cin>> x;
setanpassageiros(x);
}
/***** CLASSE DERIVADA CAMINHAO - HERANÇA MÚLTIPLA *****/
class caminhao: public veiculo_rodoviario, public maquina{
int carga;
void setacarga(int c)
{carga = c;}
int pegacarga()
{return carga;}
public:
caminhao();
void Mostra();
};
caminhao::caminhao()
{ int x;
cout<<"\nEntre com a carga maxima, em toneladas, que o veiculo suporta "<<endl;
cin>> x;
setacarga(x);
}
void caminhao::Mostra()
{ static int n=1;
cout<< "\n\n\n*** CAMINHAO REGISTRADO #"<< n++<< ": ***\n"<< endl;
switch(ItemTransportado)
{
case cargas: cout << " TRANSPORTE DE CARGA \n"<< endl; break;
case pessoas: cout << " TRANSPORTE DE HUMANOS\n"<< endl; break;
case animais: cout << " TRANSPORTE DE ANIMAIS\n"<< endl; break;
}
switch(Mecanismo)
{
case mecanico: cout << " Modelo Mecânico \n"<< endl; break;
case eletronico: cout << " Controle Eletrônico\n"<< endl; break;
case automatico: cout << " Automático\n"<< endl; break;
}
switch(Combustivel)
{
case eletricidade: cout << " Motor ELÉTRICO \n"<< endl; break;
case gasolina: cout << " Movido a Gasolina\n"<< endl; break;
case diesel: cout << " Movido a Óleo Diesel\n"<< endl; break;
}
cout<< "\nNumero de rodas: "<< pegarodas() << endl;
cout<< "\nNumero de passageiros: "<< pegapassageiros() << endl;
cout<< "\nCarga suportada [ton]: "<< pegacarga() << endl;
cout << "\n\n";
}
/***** CLASSE DERIVADA AUTOMOVEL *****/
enum tipocarro {carro, van, SUV};
class automovel: public veiculo_rodoviario{
enum tipocarro tipo;
void setatipo(tipocarro t){tipo = t;}
enum tipocarro pegatipo(){return tipo;}
public:
automovel();
void Mostra();
};
automovel::automovel()
{
char c;
tipocarro t;
cout<<"\nEntre com o tipo de automovel: "<<endl;
cout<<"\t\t(1) CARRO \n"<< endl;
cout << "\t\t(2) VAN ou MINI-VAN \n"<< endl;
cout << "\t\t(3) SUV ou utilitario \n"<< endl;
cin>> c;
switch(c)
{
case '1':
case 'c':
case 'C': t = carro; break;
case '2':
case 'v':
case 'V': t = van; break;
case '3':
case 's':
case 'S': t = SUV; break;
default: t =carro;
}
setatipo(t);
}
void automovel::Mostra()
{ static int n=1;
cout<< "\n\n\n*** AUTOMOVEL REGISTRADO #"<< n++<< ": ***\n"<< endl;
cout<< "\nNumero de rodas: "<< pegarodas() << endl;
cout<< "\nNumero de passageiros: "<< pegapassageiros() << endl;
cout<< "\ntipo de automovel: ";
switch(pegatipo())
{
case carro: cout << " CARRO \n"<< endl; break;
case van: cout << " VAN ou MINI-VAN \n"<< endl; break;
case SUV: cout << " SUV ou utilitario \n"<< endl; break;
}
cout << "\n\n";
}
int main() /***** CÓDIGO-CLIENTE *****/
{ caminhao c1, c2;
automovel a1;
veiculo_rodoviario v;
c1.Mostra();
c2.Mostra();
a1.Mostra(); //POLIMORFISMO
system("pause");
return 0;
}
Exemplo de Heranças Múltiplas - programa VEICULAR
Classe maquina
maquina.h:
#pragma once
enum tipouso {cargas, pessoas, animais};
enum tipomecanismo {mecanico, eletronico, automatico};
enum tipoalimentacao {eletricidade, gasolina, diesel};
ref class maquina
{ protected:
tipouso ItemTransportado;
tipomecanismo Mecanismo;
tipoalimentacao Combustivel;
public:
maquina();
maquina(char, char, char);
};
maquina.cpp:
#include "StdAfx.h"
#include "maquina.h"
maquina::maquina()
{
ItemTransportado = cargas;
Mecanismo = mecanico;
Combustivel = diesel;
}
maquina::maquina(char c, char m, char b)
{
switch(c)
{
case '1': ItemTransportado = cargas; break;
case '2': ItemTransportado = pessoas; break;
case '3': ItemTransportado = animais; break;
default: ItemTransportado = cargas;
}
switch(m)
{
case '1': Mecanismo = mecanico; break;
case '2': Mecanismo = eletronico; break;
case '3': Mecanismo = automatico; break;
default: Mecanismo = mecanico;
}
switch(b)
{
case '1': Combustivel = eletricidade; break;
case '2': Combustivel = gasolina; break;
case '3': Combustivel = diesel; break;
default: Combustivel = diesel;
}
}
Classe veiculorodoviario
veiculorodoviario.h:
#include "maquina.h"
#pragma once
ref class veiculorodoviario: public maquina //HERANÇA PUBLICA
{ protected:
int nrodas;
int npassageiros;
public:
veiculorodoviario();
veiculorodoviario(int, int);
};
veiculorodoviario.cpp:
#include "StdAfx.h"
#include "veiculorodoviario.h"
veiculorodoviario::veiculorodoviario()
{
nrodas = 2;
npassageiros = 4;
}
veiculorodoviario::veiculorodoviario(int x, int y)
{
nrodas = x;
npassageiros = y;
}
Classe caminhao
caminhao.h:
#pragma once
#include "veiculorodoviario.h"
#include "maquina.h"
ref class caminhao : public veiculorodoviario
{
public:
String ^ TipoTransportado;
String ^ TipoCombustivel;
String ^ TipoControle;
int cargatoneladas;
caminhao(void);
caminhao(char, char, char, int, int, int);
};
caminhao.cpp:
#include "StdAfx.h"
#include "caminhao.h"
caminhao::caminhao(void)
{
}
caminhao::caminhao(char c, char m, char b, int nr, int np, int t)
{
nrodas = nr;
npassageiros = np;
cargatoneladas = t;
switch(c)
{
case '1': ItemTransportado = cargas; TipoTransportado = "Transporte de Cargas"; break;
case '2': ItemTransportado = pessoas; TipoTransportado = "Transporte de Humanos"; break;
case '3': ItemTransportado = animais; TipoTransportado = "Transporte de Animais - Carga Viva"; break;
default: ItemTransportado = cargas; TipoTransportado = "Transporte de Cargas";
}
switch(m)
{
case '1': Mecanismo = mecanico; TipoControle = "Controle Mecânico"; break;
case '2': Mecanismo = eletronico; TipoControle = "Controle Eletrônico"; break;
case '3': Mecanismo = automatico; TipoControle = "Controle Automático"; break;
default: Mecanismo = mecanico; TipoControle = "Controle Mecânico";
}
switch(b)
{
case '1': Combustivel = eletricidade; TipoCombustivel = "Movido a Eletricidade";break;
case '2': Combustivel = gasolina; TipoCombustivel = "Movido a Gasolina"; break;
case '3': Combustivel = diesel; TipoCombustivel = "Movido a Diesel"; break;
default: Combustivel = diesel; TipoCombustivel = "Movido a Diesel";
}
}
Classe automovel
automovel.h:
#pragma once
#include "veiculorodoviario.h"
using namespace System;
using namespace std;
enum tipocarro {carro, van, SUV};
ref class automovel :
public veiculorodoviario
{
public:
String ^TipoCarro;
String ^TipoCombustivel;
String ^TipoControle;
enum tipocarro tipo;
automovel(void);
automovel(int, char, char, int, int);
};
automovel.cpp:
#include "StdAfx.h"
#include "automovel.h"
automovel::automovel(void)
{
}
automovel::automovel(int t, char m, char b, int nr, int np)
{
switch(t)
{
case 1: tipo = carro; TipoCarro = "Carro Comum"; break;
case 2: tipo = van; TipoCarro = "Van - transporte passageiros"; break;
case 3: tipo = SUV; TipoCarro = "SUV/Utilitário"; break;
default: tipo =carro; TipoCarro = "Carro Comum";
}
switch(m)
{
case '1': Mecanismo = mecanico; TipoControle = "Mecânico"; break;
case '2': Mecanismo = eletronico; TipoControle = "Eletrônico";break;
case '3': Mecanismo = automatico; TipoControle = "Automático"; break;
default: Mecanismo = mecanico; TipoControle = "Mecânico";
}
switch(b)
{
case '1': Combustivel = eletricidade; TipoCombustivel = "Elétrico"; break;
case '2': Combustivel = gasolina; TipoCombustivel = "Gasolina"; break;
case '3': Combustivel = diesel; TipoCombustivel = "Diesel"; break;
default: Combustivel = diesel; TipoCombustivel = "Diesel";
}
nrodas = nr;
npassageiros = np;
}
Interface Gráfica e Form1.h:
No Visual C++ 2010 - Interface gráfica criada para objetos das classes caminhao e automovel:
#include "maquina.h"
#include "veiculorodoviario.h"
#include "caminhao.h"
#include "automovel.h"
#pragma once
namespace VEICULAR {
using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing;
...
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
char c1, c2, c3; int x, y, t;
x= System::Convert::ToInt16(maskedTextBox1->Text);
y= System::Convert::ToInt16(maskedTextBox2->Text);
t= System::Convert::ToInt16(maskedTextBox3->Text);
if(radioButton1->Checked)
c1 = '1';
else if(radioButton2->Checked)
c1 = '2';
else if(radioButton3->Checked)
c1 = '3';
else c1 = '1';
if(radioButton1->Checked) c2 = '1'; else if(radioButton2->Checked) c2 = '2'; else if(radioButton3->Checked) c2 = '3'; else c2 = '1';
if(radioButton1->Checked) c3 = '1'; else if(radioButton2->Checked) c3 = '2'; else if(radioButton3->Checked) c3 = '3'; else c3 = '1';
caminhao ^PtrCaminhao2 = gcnew caminhao(c1, c2, c3, x, y, t);
MessageBox::Show("Novo Caminhão criado!!! \n" + PtrCaminhao2->TipoTransportado + "\n" + PtrCaminhao2->TipoCombustivel +"\n" + PtrCaminhao2->TipoControle +"\n Capaz de transportar: "); //+ PtrCaminhao2->cargatoneladas);
}
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
char c2, c3;
int c1, y, x;
x= System::Convert::ToInt16(maskedTextBox6->Text); //numero de rodas do automovel
y= System::Convert::ToInt16(maskedTextBox5->Text); //numero de passageiros do automovel
if(radioButton18->Checked)
c1 = 2;
else if(radioButton17->Checked)
c1 = 1;
else c1 = 1;
if(radioButton13->Checked)
c2 = '1';
else if(radioButton14->Checked)
c2 = '2';
else if(radioButton15->Checked)
c2 = '3';
else c2 = '1';
if(radioButton10->Checked)
c3 = '1';
else if(radioButton11->Checked)
c3 = '2';
else if(radioButton12->Checked)
c3 = '3';
else c3 = '1';
automovel ^PtrCarro1 = gcnew automovel(c1, c2, c3, x, y);
MessageBox::Show("Novo Automóvel criado!!! \n" + PtrCarro1->TipoCarro + "\n" + PtrCarro1->TipoCombustivel +"\n" + PtrCarro1->TipoControle);
}
private: System::Void button2_Click_1(System::Object^ sender, System::EventArgs^ e) {
if(radioButton19->Checked)
{ panel1->Visible = 1;
panel2->Visible = 0;}
else
{ panel2->Visible = 1;
panel1->Visible = 0;
}
}
};
}
EXERCÍCIO:
A partir da classe Pessoa derive as classes:
- Cliente - com o atributo particular CPF e o método privado ValidaCPF()*, e com os métodos de inicialização e atualização destes atributos;
- Empregado - com os atributos particulares IdEmpresa, TotalVendas e Salario, os métodos de inicialização e atualização destes atributos, além de um método privado CalculaComissao( ).
* Número de inscrição no CPF
O número de inscrição no CPF é composto de onze dígitos decimais, sendo os oito primeiros aleatoriamente designados no momento da inscrição.
Já o nono (antepenúltimo) dígito indica a região fiscal responsável pela inscrição.
Por fim, o décimo e o décimo-primeiro são dígitos verificadores calculados de acordo com um algoritmo definido pela Receita Federal e publicamente conhecido.
Seja o código do CPF formado por
cpf[8] cpf[7] cpf[6] . cpf[5] cpf[4] cpf[3] . cpf[2] cpf[1] cpf[0] - v1 v2
A computação da expressão acima para o cálculo dos dígitos verificadores podem ser escritas de forma algorítmica tendo como base o seguinte pseudocódigo:
variáveis cpf[0..8] vetor de Inteiros; v1, v2: Inteiro; início # popula a variável 'cpf' de forma inversa (o menor índice deve conter o dígito mais à direita do CPF) # ... para i := 0 até tamanho(cpf)-1 faça v1 := v1 + cpf[i] * (9 - (i mod 10)); v2 := v2 + cpf[i] * (9 - ((i + 1) mod 10)); fim-para v1 := (v1 mod 11) mod 10; v2 := v2 + v1 * 9; v2 := (v2 mod 11) mod 10; escreva(v1); escreva(v2); fim.
Regiões fiscais brasileiras, indicadas pelo cpf[0]:
O terceiro dígito da direita para a esquerda identifica a unidade federativa na qual a pessoa foi registrada:
No exemplo CPF nº 000.000.00X-00
- 0 - Rio Grande do Sul
- 1 - Distrito Federal, Goiás, Mato Grosso do Sul e Tocantins
- 2 - Pará, Amazonas, Acre, Amapá, Rondônia e Roraima
- 3 - Ceará, Maranhão e Piauí
- 4 - Pernambuco, Rio Grande do Norte, Paraíba e Alagoas
- 5 - Bahia e Sergipe
- 6 - Minas Gerais
- 7 - Rio de Janeiro e Espírito Santo
- 8 - São Paulo
- 9 - Paraná e Santa Catarina
Mais informações:
O código CPF - Wikipedia
e Valida Códigos
| Criação dinâmica de objetos << | AULA 10 - Herança | Funções Amigas >> |
|---|








