Buscar

Programação Orientada a Objetos - Poli 2016 - C++ - Aula08 Classes Abstratas e Heranca Multipla

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 41 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 41 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 41 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Escola Politécnica da Universidade de São Paulo Escola Politécnica da Universidade de São Paulo 
Laboratório de Programação 
Orientada a Objetos para 
Engenharia Elétrica 
Aula 8: Classe Abstrata e 
Herança Múltipla 
PCS3111 
Agenda 
1.  Classe abstrata 
2.  Herança múltipla 
3.  Atributos e métodos estáticos 
2 
Agenda 
1.  Classe abstrata 
2.  Herança múltipla 
3.  Atributos e métodos estáticos 
 
3 
Abstração 
!  Em uma hierarquia, às vezes é útil representar 
conceitos abstratos 
•  Representa uma abstração de um ou mais conceitos 
•  Não existe uma instância deste conceito 
!  Exemplo: ordem Carnivora da biologia 
•  Não existe um mamífero que seja dessa ordem mas 
que não pertença a uma de suas espécies 
4 
Classe abstrata 
!  Não pode ser instanciada 
•  Serve de base para a criação de outras classes 
!  Pode não estar completamente implementada 
•  Define o comportamento, mas não como ele é 
implementado 
!  Métodos abstratos 
!  Exemplo 
5 
retirar(valor)
depositar(valor)
transferirPara(destino, valor)
getSaldo
numero
saldo
ContaCorrente
retirar(valor)
getLimite()
limite
ContaEspecial
retirar(valor)
getSaldo()
numeroDeTransacoes
ContaSalário
Como funciona 
o retirar? 
Saldo negativo 
até um limite 
Saldo não 
negativo 
Classe abstrata 
!  Permite aproveitar os benefícios da herança 
•  Reaproveitar código 
•  Substituição 
!  Princípio da substituição 
6 
Alguns usos 
1.  Para ser uma base para herança 
•  Comportamento comum 
•  Conceitualmente, uma classe abstrata pode não ter 
métodos abstratos 
7 
ContaCorrente getNome()
setNome()
getEndereco()
setEndereco()
getTelefone()
setTelefone()
nome
endereço
telefone
Cliente
getCPF()
getDataDeNascimento()
cpf
dataDeNascimento
Pessoa
getCNPJ()
cnpj
Empresa
* 1
Cliente é a classe abstrata – identificador em itálico 
Associação entre classes – notação UML – Um Cliente pode ter várias ContaCorrente (*) - 
 Uma ContaCorrente pertence a um só Cliente (1) 
Alguns usos 
2.  Para simplificar o relacionamento com classes 
que sejam comuns a todas as subclasses 
•  ...e podem ser representadas por um conceito geral 
8 
class	Cliente	{	
public:	...	
protected:	
		ContaCorrente*	contas[MAX];	
		Seguro*	seguros[MAX];	
		Previdencia*	previdencias[MAX];	
};	
Cliente
ContaCorrente
Seguro
Previdência
*
*
*
class	Cliente	{	
public:	...	
protected:	
		Produto*	produtos[MAX];	
};	
Cliente
ContaCorrente
Seguro
Previdência
*
Produto
Alguns usos 
3.  Para permitir a escolha do método em tempo 
de execução 
•  Uma classe é abstrata se tiver, pelo menos um, 
método abstrato. 
•  Uma classe abstrata pode ter todos os métodos 
abstratos 
9 
Classes filhas 
redefinem o 
método retirar	
retirar(valor)
depositar(valor)
transferirPara(destino, valor)
getSaldo
numero
saldo
ContaCorrente
retirar(valor)
getLimite()
limite
ContaEspecial
retirar(valor)
getSaldo()
numeroDeTransacoes
ContaSalário
Classe abstrata em C++ 
!  Não há uma declaração direta de classe abstrata 
•  Uma classe é abstrata quando pelo menos um de 
seus métodos é abstrato 
!  Terminologia C++: método puramente virtual (virtual e =	0) 
10 
…	
	4		class	ContaCorrente	{	
	5		public:	
	6				ContaCorrente	(int	numero);	
	7				virtual	~ContaCorrente();	
	8				virtual	bool	retirar	(double	valor)	=	0;	
	9				virtual	void	depositar	(double	valor);	
…	
14		protected:	
15				double	saldo;	
16		private:	
17				int	numero;	
18		};	
EX01 
Método abstrato 
Método concreto com 
ligação dinâmica	
Classe abstrata em C++ 
!  Classe abstrata é uma classe normal 
•  Pode ter uma classe pai 
•  Pode ter atributos e métodos concretos 
•  Pode ter um construtor 
!  C++ não permite criar uma classe abstrata em 
que todos os métodos são concretos 
•  Mas é possível que ela tenha apenas métodos 
abstratos 
11 
O método abstrato não deve ser colocado na 
implementação da classe abstrata 
Classe abstrata em C++ 
!  Uma classe filha precisa implementar todos os 
métodos abstratos 
•  Ou ela também deve ser abstrata 
•  O método abstrato deve ser colocado na declaração 
da classe 
12 
…	
	6		class	ContaEspecial	:	public	ContaCorrente	{	
	7		public:	
	8				ContaEspecial	(int	numero,	double	limite);	
	9				virtual	~ContaEspecial();	
10				bool	retirar	(double	valor);	
11				virtual	double	getLimite();	
12		private:	
13				double	limite;	
14		};	
Método era abstrato na 
superclasse. Aqui é concreto! 
EX01 
!  Equipamento é uma classe abstrata 
 
!  As classes Carga e Fonte fazem sentido “no contexto” de 
Smart Grids. Uma Carga pode ser uma Lâmpada e uma 
Fonte pode ser uma Bateria. 
 
Exemplo no contexto de Smart Grids 
13 
Ela tem duas filhas: 
-  Carga 
-  Fonte 
Quem é essa classe? 
O que ela faz? 
Apenas se sabe que: 
-  pode ser programada; 
-  tem um estado; 
-  possui uma hora de ligar e 
de desligar. 
EX02 
Agenda 
1.  Classe abstrata 
2.  Herança múltipla 
3.  Atributos e métodos estáticos 
 
14 
Herança múltipla 
!  Uma classe tem 2 ou mais classes-mãe 
•  Exemplo 
!  Qual é o problema disso? 
15 
retirar(valor)
depositar(valor)
retirar(valor, investimento)
investir(valor, investimento)
saldo
ContaInvestimento
retirar(valor)
depositar(valor)
transferirPara(destino, valor)
getSaldo
saldo
ContaCorrente
retirar(valor)
getLimite()
limite
ContaEspecial
superclasses 
ContaEspecial, nesse caso, 
além de ser herdeira de 
ContaCorrente, herda também 
de ContaInvestimento. 
Problema: ambiguidade 
!  Se um nome estiver definido em mais de uma 
classe pai qual nome usar? 
•  Exemplo 
16 
retirar(valor)
depositar(valor)
retirar(valor, investimento)
investir(valor, investimento)
saldo
ContaInvestimento
retirar(valor)
depositar(valor)
transferirPara(destino, valor)
getSaldo
saldo
ContaCorrente
retirar(valor)
getLimite()
limite
ContaEspecial
Qual saldo	usar? Qual método 
depositar	é	usado? 
Problema: ancestral comum 
!  Quantos atributos a classe deve ter? 
•  Problema do diamante 
17 
retirar(valor)
retirar(valor, investimento)
investir(valor, investimento)
ContaInvestimento
transferirPara(destino, valor)
getSaldo
ContaCorrente
retirar(valor)
getLimite()
limite
ContaEspecial
retirar(valor)
depositar(valor)
saldo
ContaBancaria
Tem 1 saldo ou 2 
saldos? 
Herança múltipla 
!  Algumas linguagens não permitem a herança 
múltipla 
•  Exemplo: Java e C# 
•  O C++ permite! 
!  Ainda assim é bom evitar a herança múltipla 
!  (Capítulo 13 do livro do Budd) 
!  Discute-se a seguir um exemplo. 
18 
Herança múltipla 
19 
!  Considere-se o seguinte caso de herança 
múltipla, onde não ocorrem problemas de 
ambiguidade. 
Não há atributos nem operações 
com nomes duplicados 
A subclasse tem acesso a todas as 
operações das superclasses 
EX03 
Herança múltipla 
!  A apresentação desse exemplo leva em conta 
alguns cuidados especiais para evitar os 
problemas descritos: 
•  Não haverá ambiguidade de nomes; os nomes dos 
atributos e operações das classes foram escolhidos 
como diferentes em cada classe; 
•  Não há um ancestral comum. 
!  As classes ContaCorrente e ContaInvestimento 
foram construídas de forma muito parecidas 
apenas por simplificação, mas poderiam ser 
adequadas para uma aplicação bancária, 
podendo ser expandidas com novas 
funcionalidades. 
20 
Como declarar a herança múltipla 
21 
	8		class	ContaCorrente	{	
	9		public:10				ContaCorrente	(int	numero);	
11				virtual	~ContaCorrente();	
12			
13				bool	retirarCC	(double	valor);	
14				void	depositarCC	(double	valor);	
15				bool	transferirPara	(ContaCorrente*	destino,	
16																									double	valor);	
17				double	getSaldoCC();	
18				int	getNumeroCC();	
19		protected:	
20				double	saldoCC;	
21				int	numeroCC;	
22		};	
 
A classe ContaCorrente 
pode ser entendida 
como uma conta 
corrente normal, com 
operações simples e 
sem nenhum limite 
extra de crédito. 
 
Somente se pode sacar 
dessa conta, quantias 
menores que o saldo 
disponível, saldoCC. 
EX03 
Como declarar a herança múltipla 
22 
5		#include	"ContaCorrente.h"	
			…	
	9		class	ContaInvestimento	
10		{	
11		public:	
12						ContaInvestimento	(int	numero);	
13						virtual	~ContaInvestimento();	
14			
15						bool	retirarCI	(double	valor);	
16						void	depositarCI	(double	valor);	
17						bool	transferirCIParaCC	(ContaCorrente*	destino,	
18																															double	valor);	
19						double	getSaldoCI();	
20						int	getNumeroCI();	
21		protected:	
22						double	saldoCI;	
23						int	numeroCI;	
24		};	
	
A classe ContaInvestimento 
possui uma operação, 
transferirCIParaCC que necessita 
conhecer características da classe 
ContaCorrente. 
Essa classe tem 
um saldo, 
saldoCI, que 
pode render 
juros, porém a 
operação de 
cálculo de juros 
não foi incluída, 
porque nada 
acrescenta ao 
problema que 
está sendo 
tratado. 
EX03 
 4		#include	"ContaCorrente.h"	
	5		#include	"ContaInvestimento.h"	
	…			
	9		class	ContaGerente	:	public	ContaCorrente,	public	ContaInvestimento	
10		{	
11		public:	
12						ContaGerente	(int	IDgerente,	string	data);	
13						virtual	~ContaGerente();	
14						double	getSaldoTotal();	
15						int	getIDGerente();	
16			
17		private:	
18						double	saldoTotal;	
19						int	IDGerente;	
20						string	data;	
21		};	
Como declarar a herança múltipla 
23 
Incluir a definição das superclasses 
A vírgula marca a 
separação entre os 
nomes das 
superclasses-mãe 
As demais definições - public e private – 
se referem às definições normais de uma 
classe e são feitas como em qualquer 
outra classe. 
EX03 
Como declarar os construtores das 
superclasses 
!  Declaração normal dos construtores das superclasses 
 
!  As duas superclasses-mãe foram construídas de forma 
similar. Elas irão diferir em alguns pontos; por exemplo, 
ContaInvestimento tem rendimento, mas nesse contexto 
essas operações não serão consideradas. 
24 
 7 ContaCorrente::ContaCorrente (int numero) {	
 8 this->numeroCC = numero;	
 9 this->saldo = 0;	
10 }	
 7 ContaInvestimento::ContaInvestimento (int numero) {	
 8 this->numeroCI = numero;	
 9 this->saldo = 0;	
10 }	
EX03 
Como declarar o construtor da classe-
filha 
25 
 7		ContaGerente::ContaGerente(int	IdGerente,	string	data):		
								ContaCorrente	(9990),	ContaInvestimento(9991)	
	8		{	
	9						this->IDGerente	=	IdGerente;	
10						this->data	=	data;	
11		} 
A virgula separa as chamadas dos 
construtores das superclasses 
Observação: optou-se por construir, a título de exemplo, um 
construtor bem simples, que define ele próprio os números 
que são atribuídos às superclasses, respectivamente: 9990 
para a Conta Corrente e 9991 para a Conta Investimento. 
EX03 
Utilização das superclasses 
26 
12				cout	<<	"Teste	da	Conta	Corrente"	<<	endl;	
13				ContaCorrente	*cc	=	new	ContaCorrente	(9990);	
14				cc->depositarCC	(1000);	
15				cout	<<	(cc->retirarCC	(150)	?	"Ok"	:	"NOK")	<<	endl;	
16				cout	<<	"Saldo	da	Conta	Corrente	numero	"	<<	
17									cc->getNumeroCC()	<<	"	=	"	<<	cc->getSaldoCC()	<<	endl;	
18			
19				cout	<<	"Teste	da	Conta	Investimento"	<<	endl;	
20				ContaInvestimento	*ci	=	new	ContaInvestimento	(9991);	
21				ci->depositarCI	(4000);	
22				ci->transferirCIParaCC	(cc,	300);	
23				cout	<<	"Saldo	da	Conta	Corrente	numero	"	<<	
24									cc->getNumeroCC()	<<	"	=	"	<<	cc->getSaldoCC()	<<	endl;	
25				cout	<<	(ci->retirarCI	(150)	?	"Ok"	:	"NOK")	<<	endl;	
26				cout	<<	"Saldo	da	Conta	Investimento	numero	"	<<	
27									ci->getNumeroCI()	<<	"	=	"	<<	ci->getSaldoCI()	<<	endl;	
 
Main.exe EX03 
Utilização das superclasses 
!  Na linha 13 é feita a instanciação de um objeto da 
classe Conta Corrente. O ponteiro “cc” aponta o 
novo objeto criado. Na linha 20 é instanciado um 
objeto da classe ContaInvestimento. O ponteiro “ci” 
identifica esse objeto. 
!  É feito, então, um depósito na Conta Corrente (linha 
14) e em seguida uma retirada (linha 15). A seguir é 
exibido o número da conta e o saldo (linha 16). 
!  Para a Conta Investimento é feito um depósito na 
linha 21 e em seguida uma transferência para a 
conta corrente associada (linha 22). O número da 
conta e o saldo são exibidos (linhas 23 e 24). 
27 
Utilização das superclasses 
!  A saída abaixo mostra os resultados dessas 
operações. 
!  Observe-se que nesse exemplo foram criados 
dois objetos distintos (ponteiros “cc” e “ci”). 
28 
EX03 
Utilização da subclasse 
29 
28				…		
29				cout	<<	"Teste	da	Conta	Gerencial"	<<	endl;	
30			
31				ContaGerente	*cg	=	new	ContaGerente	(	21,	"04/06/2016");	
32				cg->depositarCC	(1000);	
33				cout	<<	(cg->retirarCC	(150)	?	"Ok"	:	"NOK")	<<	endl;	
34				cout	<<	"Saldo	da	Conta	Corrente	numero	"	<<	
35									cg->getNumeroCC()	<<	"	=	"	<<	cg->getSaldoCC()	<<	endl;	
36			
37				cg->depositarCI	(4000);	
38				cg->transferirCIParaCC	(cg,	300);	
39				cout	<<	(cg->retirarCI	(150)	?	"Ok"	:	"NOK")	<<	endl;	
40				cout	<<	"Saldo	da	Conta	Corrente	numero	"	<<	
41									cg->getNumeroCC()	<<	"	=	"	<<	cg->getSaldoCC()	<<	endl;	
42				cout	<<	"Saldo	da	Conta	Investimento	numero	"	<<	
43									cg->getNumeroCI()	<<	"	=	"	<<	cg->getSaldoCI()	<<	endl;	
44				cout	<<	"Saldo	Total	=	"	<<	cg->getSaldoTotal()	<<	endl;	
45				…	
 EX03 
Utilização da subclasse 
!  A instância da Classe Gerente foi criada na linha 
31. O ponteiro “cg” indica esse objeto. Note-se 
que esse objeto é composto por três partes: 
•  uma parte relativa a Classe Gerente (transparência 
23) e tem acesso a todas as suas operações; 
•  uma parte relativa à Conta Corrente (transparência 
21) e acessa todas essas operações ; 
•  uma parte relativa à Conta Investimento 
(transparência 22), com acesso as suas operações. 
!  As operações descritas para os objetos 
apontados por “cc” e “ci” são repetidas nas 
linhas 32 a 44 e a saída é apresentada a seguir. 
30 
Utilização da subclasse 
!  O saldo total apresentado na última linha 
corresponde à soma dos saldos individuais de 
cada conta. 
!  A Conta Gerente se comporta como uma “macro 
conta”, formada por uma conta corrente e por 
uma conta de investimentos, por exemplo, uma 
caderneta de poupança. 
31 
EX03 
Agenda 
1.  Classe abstrata 
2.  Herança múltipla 
3.  Atributos e métodos estáticos 
 
32 
Como instâncias ocupam a memória 
!  Cada instância de uma classe tem um valor 
específico para cada atributo 
•  São diferentes entre as instâncias 
!  O código dos métodos é compartilhado 
•  É o mesmo para todas as instâncias 
•  Usam os valores dos atributos de cada instância 
Atributo 1 
Atributo 2 
Atributo 1 
Atributo 2 
Atributo 1 
Atributo 2 
Método 1 
Método 2 
33 
Atributo estático 
!  Um atributo pode ser declarado como estático 
•  (Ou atributo com escopo de classe) 
•  Apenas um valor é criado para a classe 
!  Não é definido em cada instância 
•  O atributo existe mesmo que não haja instâncias 
•  Ele existe por toda a execução do programa 
34 
static double limiteDeSaque;	
número:	124
saldo:	700
conta1:ContaUniversitária
número:	125
saldo:	500
conta2:ContaUniversitárianúmero:	126
saldo:	10000
conta3:ContaUniversitária
Uso 
!  Permite compartilhar informações entre todas as 
instâncias de uma classe 
!  Exemplos de uso 
•  Identificador sequencial 
•  Contador de quantas instâncias a classe tem 
•  Declaração de constantes (static	const) 
•  Informações comuns a todos os objetos 
35 
Atributo estático em C++ 
!  Declaração: static	
!  Na implementação deve-se atribuir o valor inicial 
36 
	1		#include	"ContaUniversitaria.h"	
	2			
	3		double	ContaUniversitaria::limiteDeSaque	=	0;	
…	
…	
	6		class	ContaUniversitaria	:	public	ContaCorrente	{	
	7		public:	
	8				ContaUniversitaria	(int	numero);	
	9				virtual	~ContaUniversitaria();	
10				bool	retirar	(double	valor);	
…	
13		private:	
14				static	double	limiteDeSaque;	
15		};	
Atributo estático 
EX01 
EX01 
Atributo estático em C++ 
!  Uso 
•  <nome	da	classe>::<nome	do	atributo>	
!  Dentro da classe é possível omitir o <nome	da	classe>	
•  (Mas pode ser confuso) 
•  Exemplo 
37 
…	
12		bool	ContaUniversitaria::retirar	(double	valor)	{	
13				if	(valor	<=	ContaUniversitaria::limiteDeSaque	
14								&&	saldo	>=	valor)	{	
15						saldo	-=	valor;	
16						return	true;	
17				}	
18			
19				return	false;	
20		}	
Acessando o limite 
EX01 
Método estático 
!  Método que não é executado no contexto de um 
objeto específico 
•  Não é preciso ter uma instância para chamar o 
método 
!  Exemplos de uso 
•  Manipular atributos estáticos 
•  Métodos de apoio 
!  Exemplo: arredondar um valor, embaralhar um vetor e 
imprimir um texto em um certo formato na saída 
38 
Método estático em C++ 
!  Declaração: static	
!  Implementação 
39 
…	
	6		class	ContaUniversitaria	:	public	ContaCorrente	{	
	7		public:	
…	
11				static	double	getLimiteDeSaque();	
12				static	void	setLimiteDeSaque	(double	limite);	
13		private:	
14				static	double	limiteDeSaque;	
15		};	
…	
22		double	ContaUniversitaria::getLimiteDeSaque()	{	
23				return	ContaUniversitaria::limiteDeSaque;	
24		}	
Não deve-se colocar o static na 
implementação 
EX01 
EX01 
Método estático em C++ 
!  Chamada de método estático 
•  Usando a instância 
!  (Se confunde com método com escopo de objeto) 
•  Usando o nome da classe (recomendado) 
40 
	
…	
17				ContaUniversitaria*	c	=	new	ContaUniversitaria	(1);	
18				c->depositar	(100);	
19				ContaUniversitaria::setLimiteDeSaque	(50);	
20				c->setLimiteDeSaque	(55);	
Formas possíveis 
EX01 
Bibliografia 
Budd, T. An Introduction to Object-Oriented 
Programming. Addison-Wesley, 3rd ed. 2002. 
•  Classe abstrata: Seção 8.5 
•  Herança múltipla: Capítulo 13 
Savitch, W. C++ Absoluto. Pearson, 1st ed. 2003. 
•  Atributos e métodos estáticos: Seção 7.2. 
41

Continue navegando