Orientação a Objeto - Visibilidade
Objetivos da seção
- Discutir a encapsulação de informação e a visibilidade de dados de forma mais
detalhada
- Discutir a organização de código em pacotes (packages)
Escopo de variáveis
- Resumo do escopo de variáveis e parâmetros

Encapsulação
- A encapsulação de dados com o código que os manipula em
classes é a principal vantagem da Orientação a Objeto
- No sentido de não quebrar a encapsulação, é muito importante que os membros de uma
classe (atributos e métodos) sejam visíveis apenas onde estritamente necessário
- A lei é: "Não posso quebrar o que não posso acessar"
- Por isso, é comum usarmos "private" como especificador
de controle de acesso para atributos de uma classe
- Já que é frequente querermos que métodos de uma classe sejam chamados por objetos de
outras classes, não é raro usarmos "public" como especificador de controle de
acesso para métodos de uma classe
- Especificadores de controle de acesso controlam a visibilidade
de membros de uma classe
- São aplicados a atributos e métodos
Encapsulação e métodos "accessor" get/set
- Com atributos sendo "private", é frequente usar métodos "accessor"
(get/set) para manipular atributos
- Porém, devemos ter cuidado para não quebrar o encapsulamento
- Se uma classe faz objeto.getAtrib(), manipula o valor do atributo e depois faz
objeto.setAtrib(), o atributo é essencilamente público e estamos quebrando o
encapsulamento
- Mudanças de atributos devem ser conduzidas por métodos da própria classe para
garantir que ela mantenha o estado do objeto consistente
- Tomemos como exemplo um semáforo
- Não devemos efetuar as mudanças de atributos fora do semáforo
- Portanto, não é bom ter um setCor()
- É melhor ter um método muda() que pede uma mudança de cor
- O próprio semáforo deve saber em que sequência mudar as cores do semáforo
public class Semaforo {
public static final int VERMELHO = 0;
public static final int AMARELO = 1;
public static final int VERDE = 2;
private int corAtual;
public Semaforo() {
this(VERMELHO);
}
public Semaforo(int cor) {
corAtual = cor;
}
public void muda() {
switch(corAtual) {
case VERMELHO:
corAtual = VERDE;
break;
case AMARELO:
corAtual = VERMELHO;
break;
case VERDE:
corAtual = AMARELO;
break;
}
}
public int getCorAtual() {
return corAtual;
}
private static String[] nomeCor = {"VERMELHO", "AMARELO", "VERDE" };
public String getNomeCorAtual() {
return nomeCor[getCorAtual()];
}
public String toString() {
return "semaforo esta " + getNomeCorAtual();
}
}
Especificadores de controle de acesso
- Há quatro graus de visibilidade que podemos usar com membros de uma classe
- As palavras chaves usadas são: "public", "private",
"protected", e nenhuma
- Para entender quando usar cada um desses graus de visibilidade, lembre que há vários
papeis que os programadores podem assumir:
- Você, que está escrevendo uma classe
- O programador "cliente" que só quer usar a classe que você criou
- Ele pode nem ter código fonte
- Outros programadores que estão trabalhando num pacote com você
- Várias classes de um mesmo pacote (pacjage) estão sendo feitas por vários
parogramadores
- O programador que poderá estender sua classe no futuro
- Ele normalmente tem o código fonte
A visibilidade public
- Quem tem acesso à classe tem acesso também a qualquer membro com visibilidade public
- O alvo aqui é o programador cliente que usa suas classes
- É raro ter atributos públicos mas é comum ter métodos públicos
A visibilidade private
- O membro private não é acessível fora da classe
- A intenção aqui é permitir que apenas você que escreve a classe possa usar esse
membro
A visibilidade protected
- O membro protected é acessível à classe e a suas subclasses
- A intenção é dar acesso ao programadores que estenderão sua classe
Packages
- O conceito de package (pacote) foi inventado para permitir criar um espaço de nomes
grande em Java
- O que ocorre se você quiser criar uma classe Fita e outro programador já criou uma
classe Fita?
- Será que você vai ser impossibilitado de criar sua classe?
- Não há problema, desde que as classes assim chamadas estejam em packages diferentes
- Os nomes dos packages formam uma árvore, permitindo assim um espaço de nomes muito
grande
- Exemplo: p1.aplic.banco é um nome de package
- Exemplo: p1.aplic.banco.Conta é uma classe deste package
A visibilidade "package"
- Um membro de classe sem especificador de controle de acesso é dito ter a visibilidade
package (ou "friendly")
- É como public, mas somente dentro do package
- Todas as classes do package podem acessar um membro "friendly"
- É usado para permitir acesso mais liberal, mas somente dentro de um mundo controlado e
não pelo usuários da classe
- Deve-se ter cuidado com a visibilidade friendly para atributos pois pode abrir muito o
acesso, principalmente em packages grandes
Um exemplo
- Observe a visibilidade de Agencia.fecharConta()
public class Agencia {
...
/**
* Fecha uma conta.
* @param número O número da conta a fechar.
* @throws NaoPodeFecharContaException se a conta não existir ou tiver saldo
*/
/* observe visibilidade "package": tem que fechar a partir de fechar() da conta */
static void fecharConta(int número) throws NaoPodeFecharContaException {
abrirCaixa();
Conta c = localizarConta(número);
if(c == null) {
throw new NaoPodeFecharContaException(c, "Conta nao existe");
}
if(c.getSaldo() != 0.0) {
throw new NaoPodeFecharContaException(c, "Saldo nao esta zerado");
}
contas.remove(Integer.toString(número));
// tem que repensar o fechamento de contas porque
// do jeito que esta, nao some do arquivo agencia.txt
}
...
}
- Dentro do package p1.aplic.banco, várias classes poderiam chamar Agencia.fecharConta()
- Porém, essa não é um método que queremos deixar público
- Para fechar uma conta, o usuário do package deve usar Conta.fechar()
oo-8 programa anterior
próxima