Buscar

Programação Orientada a Objetos - Poli 2016 - C++ - Aula04 Encapsulamento

Prévia do material em texto

Escola Politécnica da Universidade de São Paulo 
Laboratório de Programação Orientada a 
Objetos para Engenharia Elétrica 
Aula 4: Encapsulamento 
PCS 3111 
Agenda 
 
1.  Princípios da modularização 
2.  Encapsulamento 
•  Métodos e Atributos Públicos e Privados 
3.  Coesão 
4.  Acoplamento 
5.  Métodos Setters/Getters 
6.  Processo de Compilação e Ligação 
7.  Organização de Arquivos: extensões .cpp e .h 
8.  Primitivas de Compilação: include e ifndef 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Princípios da modularização 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Introdução 
!  Uma boa prática no desenvolvimento de 
software é quebrar a solução em módulos 
(discutido nas aulas anteriores); 
!  Um dos critérios (princípios) para modularização 
é a ocultação da informação. 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Ocultação de Informações 
!  Uma solução modular esconde detalhes do 
módulo de outros módulos 
!  Especifica um módulo do ponto de vista externo 
!  Separa o propósito de um módulo de sua 
implementação 
!  Restringe o acesso de outros módulos a 
detalhes de implementação e a qualquer 
estrutura de dados do módulo; 
!  Em desenvolvimento de software a ocultação de 
informações é definida como Encapsulamento. 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Encapsulamento 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Encapsulamento 
Encapsulamento em programação orientada a 
objetos é capacidade de ocultação de detalhes de 
implementação de uma classe por parte de outras 
classes que a manipulam. 
 
!  O encapsulamento esconde detalhes da classe 
que não essenciais para compreender suas 
características; 
!  O encapsulamento permite o acesso a membros 
privados da classe (atributos e métodos) de uma 
interface bem definida de acesso (métodos). 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Encapsulamento 
 
!  Encapsulamento em classes de objetos é 
implementado em C++ utilizando-se: Private e 
Public. 
Membros da Classe 
(Exemplo: atributos) 
Interface de acesso (Exemplo: métodos) 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Private e Public em C++ 
class X { // Classe de nome X 
 public: // Membros Públicos – 
 // interface para acesso externo 
 // a Classe X. 
 // Métodos e atributos. 
 
 private: // Membros privados – 
 // detalhes de implementação da Classe, 
 // acessível somente pelos membros 
 // dessa classe. 
 // Métodos e atributos. 
 }; 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo em C++ 
…		
	8		class	Carro	{	
	9		private:	
10				string	fabricante;	
11				int	quilometragem;	
12		public:	
13				string	cor;	
14				void	iniciaCarro	(string	f,	string	c);	
15				void	exibeCarro();	
16		};	
17			
18		void	Carro::iniciaCarro	(string	f,	string	c)	{	
19				fabricante	=	f;	
20				cor	=	c;	
21				quilometragem	=	0;	
22		}	
23			
24		void	Carro::exibeCarro()	{	
25				cout	<<	"Dados	do	Carro:	"	<<	endl;	
26				cout	<<	"fabricante:	"	<<	fabricante	<<	endl;	
27				cout	<<	"cor:	"	<<	cor	<<	endl;	
28				cout	<<	"quilometragem:	"	<<	quilometragem	<<	endl;	
29		}	
EX01 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Private e Public em C++ 
!  Membros de Classes são privados por default. Ex: 
 class X { 
 int mf(); 
 // … 
 }; 
!  Significa: 
 class X { 
 private: 
 int mf(); 
 // … 
 }; 
!  Assim: 
 X *x; // Variável x referencia um objeto da Classe X 
 x = new X; 
 int y = x->mf(); // erro: mf é private(inacessível fora 
 // da classe X) 
 
EX02 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Coesão 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Coesão 
!  Definição: é o grau em que as responsabilidades de um 
único componente formam uma unidade significativa. 
(Budd, 2005) 
 
!  Coesão avalia o quanto os membros (atributos e 
métodos) de uma classe estão relacionados entre si. 
 
!  Coesão é uma métrica que pode ser classificada como 
Alta (membros fortemente relacionados) ou Baixa 
(membros pouco relacionados). 
 
!  Coesão Alta é imprescindível em programação modular. 
!  Entende-se que uma classe tem Coesão Alta quando os 
membros de uma classe estão relacionados a um tema 
comum e tem o mesmo objetivo. 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Coesão Alta 
. 
 
 
 
class	Relogio	{	
private:	
		int	hora;	
		int	minuto;	
		int	segundo;	
public:	
		void	iniciaRelogio	(int	h,	int	m,	int	s);	
		void	incrementaMinuto();	
		void	exibeHora();	
}	
!  Observe que todos os membros da Classe 
estão relacionados com Relógio. 
EX03 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Coesão Baixa 
class	Relogio	{	
private:	
		int	hora;	
		int	minuto;	
		int	segundo;	
		bool	acesa;	
public:	
		void	iniciaRelogio	(int	h,	int	m,	int	s);	
		void	incrementaMinuto();	
		void	exibeHora();	
		void	ligaLampada();	
};	
!  Observe que os membros acesa e ligaLampada não 
estão relacionados com o conceito de Relógio e sim 
com Lâmpada. 
 
 
 
 
 
EX04 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Coesão Baixa 
!  Observe que a classe Aluno inclui também o 
conceito de notas e cálculo de média. 
 
	7		class	Aluno	{	
	8		private:	
	9				string	nome;	
10				int	p1,	p2,	p3;	
11			
12		public:	
13				void	setNome	(string	nome);	
14				string	getNome();	
15				void	iniciaAvaliacao	(int	p1,	int	p2,	int	p3);	
16				int	calculaMedia();	
17		};	
EX05 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Coesão Alta 
 
!  Observe que as classes Aluno e Avaliacao foram 
definidas separadamente. 
 
 
 
 
 
	7		class	Avaliacao	{	
	8		private:	
	9				int	p1,	p2,	p3;	
10			
11		public:	
12				void	iniciaAvaliacao	(int	p1,	int	p2,	int	
p3);	
13				int	calculaMedia();	
14		};	
15			
16		class	Aluno	{	
17		private:	
18				string	nome;	
19				Avaliacao	*avaliacao;	
20			
21		public:	
22				void	setNome	(string	nome);	
23				string	getNome();	
24				void	setAvaliacao	(Avaliacao	*nota);	
25		};	
EX06 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Acoplamento 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Acoplamento 
!  Definição: descreve a relação entre os componentes de 
software (Budd, 2005). 
!  Acoplamento avalia o inter-relacionamento entre as classes. 
!  Acoplamento é uma métrica e pode ser classificado como 
Alto/Forte (alta interdependência entre as classes) ou Baixo/ 
Fraco (baixa interdependência entre as classes). 
 
!  Classes que têm um Acoplamento Baixo são mais 
independentes entre si. O inverso vale para Acoplamento 
Alto. 
 
!  Como regra geral deve-se minimizar sempre que possível o 
acoplamento entre classes. 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Acoplamento 
Observe os seguintes 
aspectos de acoplamento: 
!  A classe Lampada tem 
acesso direto ao atributo do 
objeto da classe Relogio; 
!  A classe Lampada utiliza 
diretamente um valor de 
atributo da classe Relogio 
para decidir se é noite. 
 
 
 
 
 
17		class	Lampada	{	
18		private:	
19				bool	acesa;	
20		public:	
21				void	ligar();	
22				void	desligar();	
23				void	ligarNoite	(Relogio	*horaAtual);	
24		};	
25			
26		void	Lampada::ligar()	{	
27				acesa	=	true;	
28		}	
29			
30		void	Lampada::desligar()	{	
31				acesa	=	false;	
32		}	
33			
34		void	Lampada::ligarNoite	(Relogio	*horaAtual)	{	
35				int	hora;	
36				hora	=	horaAtual->hora;	
37			
38				if	(hora	>=	18)	acesa	=	true;	
39				else	acesa	=	false;	
40		}	
EX07 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Acoplamento 
!  . 
	7		class	Relogio	{	
	8		private:	
	9				int	hora,	minuto,segundo;	
10		public:	
11				bool	ehNoite();	
12		//	outros	metodos..	
13		};	
14			
15		class	Lampada	{	
16		private:	
17				bool	acesa;	
18		public:	
19				void	ligar();	
20				void	desligar();	
21				void	ligarNoite	(Relogio	*horaAtual);	
22		};	
23			
24		bool	Relogio::ehNoite()	{	
25				return	hora	>=	18;	
26		}	
27			
28		void	Lampada::ligarNoite	(Relogio	*horaAtual)	{	
29				if	(horaAtual->ehNoite())	acesa	=	true;	
30				else	acesa	=	false;	
31		}	
Solução para diminuir o 
Acoplamento da Classe Lampada: 
!  Remoção do código que 
acessa diretamente o atributo 
do objeto da classe Relogio. 
!  A classe Lampada não 
necessita conhecer quais 
valores específicos da hora 
que determinam se é noite. A 
definição de noite ficou restrita 
à classe Relogio. 
EX08 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Acoplamento 
16		class	Lampada	{	
17		private:	
18				bool	acesa;	
19		public:	
20				void	ligar();	
21				void	desligar();	
22				void	ligarNoite	(bool	ehNoite);	
23				bool	isAcesa();	
24		};	
...		
44		void	Lampada::ligarNoite	(bool	ehNoite)	{	
45				acesa	=	ehNoite;	
46		}	
…	
52		int	main	()	{	
53				Lampada	*l	=	new	Lampada;	
54				l->desligar();	
55				Relogio	*r	=	new	Relogio();	
...	
58				l->ligarNoite(r->ehNoite());	
...	
61		}	
	
	
Outra solução com 
acoplamento ainda menor: 
!  A classe Lampada não 
depende mais do Relogio 
(nem sabe que o Relogio 
existe) 
!  Alguém (o main no caso) é 
quem passa a informação 
para a Lampada 
 
EX09 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de Acoplamento 
!  Existem várias possíveis soluções 
•  Qual é a melhor? Receber o relógio ou um booleano? 
!  ...depende se é importante separar completamente Relógio 
de Lâmpada... 
•  Projeto OO 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Métodos Setters/Getters 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Uso de métodos Setters/Getters 
!  Os métodos Mutators (setters) e Accessors (getters) 
são utilizados para alterar e acessar atributos 
declarados como privados. 
 
!  Os métodos setNome/getNome são utilizados para 
encapsular a manipulação direta dos atributos de 
uma classe. 
!  Esses métodos permitem esconder detalhes 
específicos de inicialização, validação e acesso aos 
atributos. 
!  Em C++ os métodos setNome/getNome podem ser 
utilizados para manipular os atributos declarados 
como privados. 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de uso de setNome/getNome 
class Quadrado {	
private:	
 double lado;	
public:	
 bool setLado (double l);	
 double getLado();	
};	
bool Quadrado::setLado (double l) {	
 if (l <= 0) return false	
 else {	
 lado = l;	
 return true;	
 }	
}	
double Quadrado::getLado() {	
 return lado;	
}	
int main() {	
 Quadrado *square = new Quadrado;	
 square->setLado (6.0);	
 cout << Quadrado de lado: " << square->getLado(); 	
}	
!  Atributo local da classe 
declarado como privado. 
!  Métodos setLado/getLado 
para inicialização e acesso 
ao atributo lado. 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Exemplo de uso de setNome/getNome 
class Pessoa {	
private:	
 string nome;	
 int idade;	
public:	
 void setNome (string nome);	
 string getNome();	
 void setIdade (int idade);	
 int getIdade();	
};	
void Pessoa::setNome (string n) {	
 nome = n;	
}	
string Pessoa::getNome() {	
 return nome;	
}	
void Pessoa::setIdade (int i) {	
 idade = i;	
}	
int Pessoa::getIdade() {	
 return idade;	
}	
!  Atributos locais da classe 
declarados como privados. 
!  Métodos setNome/getNome 
para inicialização e leitura 
de cada atributo. 
 
 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Processo de Compilação e Ligação 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Compilação e Ligação 
!  Código escrito em C++ (Código Fonte) – legível pelos humanos 
•  Arquivos com extensões: .cpp ou .h (headers) 
!  O compilador traduz o Código Fonte em Código Objeto (também 
chamado de “Código de Máquina") 
•  Arquivo com extensão .obj (Windows) ou .o (Unix); 
!  O ligador liga seu Código Objeto com outras bibliotecas de Códigos 
Objetos já existentes. Exemplos: bibliotecas de entrada/saída, código do 
Sistema Operacional, etc. 
•  Arquivos com extensão: .obj (Windows) ou .o (Unix) e .lib; 
!  O resultado é um Programa Executável 
•  Arquivo com extensão .exe (Windows) ou a.out em Unix. 
Compilador C++ 
Código Fonte C++ 
Código Objeto 
Ligador 
Programa Executável 
Biblioteca de Código Objeto 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Organização de Arquivos: 
extensões .cpp e .h 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Classes e Arquivos 
!  C++ permite definir e implementar mais de uma 
classe em um mesmo arquivo 
•  Exemplo: sistema bancário 
class	ContaCorrente	{...	
};	
int	main	(int	argc,	char**	argv)	{...	
}	
class	Agencia	{...	
};	
void	ContaCorrente::depositar	(double	valor)	{...	
}	
void	Agencia::adicionar	(ContaCorrente	c)	{...	
}	
class	Correntista	{...	
};	
bool	ContaCorrente::retirar	(double	valor)	{	
		...	
}	
	
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Classes e Arquivos 
!  Como organizar as classes em um arquivo? 
!  Quantas classes devem ser colocadas em cada 
arquivo? 
!  Boa prática 
•  Crie um arquivo separado para cada definição e 
implementação 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Definição 
!  Arquivo de cabeçalho: ".h" 
•  Exemplo: ContaCorrente.h 
class	ContaCorrente	{	
private:	
		double	saldo	=	0.0;	
public:	
		void	depositar	(double	valor);	
		bool	retirar	(double	valor);	
};	
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Implementação 
!  Arquivo .cpp 
•  Necessário fazer um #include	do ".h" 
•  Exemplo: ContaCorrente.cpp 
#include	"ContaCorrente.h"	
		
void	ContaCorrente::depositar	(double	valor)	{	
		saldo	+=	valor;	
}	
		
bool	ContaCorrente::retirar	(double	valor)	{	
		if	(saldo	<	valor)	return	false;	
		saldo	-=	valor;	
		return	true;	
}	
Inclui a definição 
da Classe ContaCorrente 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Implementação 
!  Arquivo main.cpp 
 
!  Para compilar e ligar manualmente: 
#include	<iostream>	
#include	"ContaCorrente.h"	
using	namespace	std;	
int	main()	{	
		ContaCorrente	*conta	=	new	ContaCorrente();	
		conta->depositar(1000);	
		cout	<<	conta->saldo	<<	endl;	
}	
g++	-c	-std=c++11	contacorrente.cpp	-o	contacorrente.o	
g++	-c	-std=c++11	main.cpp	-o	main.o	
g++	contacorrente.o	main.o	-o	main.exe	
	
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Primitivas de Compilação: include e 
ifndef 
 
 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Diretivas de Compilação 
!  As Diretivas de Compilação utilizadas em C++ 
iniciam com o símbolo ‘#’, tais como: #include e 
#ifndef 
!  As Diretivas são utilizadas numa etapa inicial da 
compilação denominada pré-processamento. 
!  Nessa etapa as Diretivas de Compilação são 
processadas, incluindo ou removendo código 
fonte do arquivo compilado. 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Inclusão 
!  Indica para o compilador onde o arquivo a ser 
incluído está: 
•  O arquivo pode estar em pastas diferentes; 
•  Quando se inclui cabeçalhos da biblioteca padrão usa-
se o "<" e ">" 
!  O compilador procura o arquivo onde as bibliotecas ficam 
!  Arquivos de cabeçalho também podem fazer 
inclusões 
•  Exemplo: Agencia.h inclui a ContaCorrente.h 
#include <iostream>	
#include "ContaCorrente.h"	
	
	
Do projeto 
Da biblioteca padrão 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Diretiva ifndef	
!  Problema: múltipla inclusão de um cabeçalho 
•  Exemplo: tanto a Agênciaquanto o Correntista 
incluem a ContaCorrente 
•  Gera um erro de compilação! 
!  (Compiladores de outras linguagens evitam esse erro) 
!  Solução: diretiva #ifndef	
#ifndef CONTACORRENTE_H	
#define CONTACORRENTE_H	
 	
class ContaCorrente {	
 ...	
};	
 	
#endif	
Se CONTACORRENTE_H	não estiver 
definido, define-o 
Fim do ifndef 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Classes e Arquivos 
!  Exemplo: arquivos de um sistema bancário 
•  ContaCorrente.h e ContaCorrente.cpp 
•  Agencia.h e Agencia.cpp 
•  Correntista.h e Correntista.cpp 
•  main.cpp 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4 
Bibliografia 
!  STROUSTRUP B. Princípios e práticas em 
programação com C++. Bookman. 2012. 
1216p 
!  BUDD, T. An Introduction to Object-Oriented 
Programming. 3rd Edition. Addison-Wesley. 
2001. 
!  Craig Larman, C. Applying UML and Patterns: 
An Introduction to Object-Oriented Analysis 
and Design and Iterative Development (3rd 
Edition) 3rd Edition., 2005 
 
© PCS / EP / USP 2016 – PCS 3111 – Aula 4

Continue navegando