Modificadores de acesso e atributos de classe - Informática

Propaganda
Desenvolvimento OO com Java
Modificadores de acesso
e atributos de classe
Vítor E. Silva Souza
([email protected])
http://www.inf.ufes.br/~vitorsouza
Departamento de Informática
Centro Tecnológico
Universidade Federal do Espírito Santo
Licençaparausoedistribuição
• EsteobraestálicenciadacomumalicençaCreative
Commons Atribuição-CompartilhaIgual 4.0Internacional;
• Vocêtemodireitode:
– Compartilhar:copiareredistribuiromaterialem
qualquersuporteouformato
– Adaptar:remixar,transformar,ecriarapartirdo
materialparaqualquerfim,mesmoquecomercial.
• Deacordocomostermosseguintes:
– Atribuição:vocêdevedarocréditoapropriado,proverumlinkpara
alicençaeindicarsemudançasforamfeitas.Vocêdevefazê-loem
qualquercircunstânciarazoável,masdemaneiraalgumaquesugira
aolicencianteaapoiarvocêouoseuuso;
– CompartilhaIgual:sevocêremixar,transformar,oucriarapartirdo
material,temdedistribuirassuascontribuiçõessobamesma
licençaqueooriginal.
Mais informações podem ser encontradas em:
http://creativecommons.org/licenses/by-sa/4.0/
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
2
Conteúdodocurso
• OqueéJava;
• Variáveisprimitivase
controledefluxo;
• Orientaçãoaobjetos
básica;
• Umpoucodevetores;
• Modificadoresdeacesso
eatributosdeclasse;
• Herança,reescritae
polimorfismo;
• Classesabstratas;
• Interfaces;
• Exceçõesecontrolede
erros;
• UtilitáriosdaAPIJava.
EstesslidesforambaseadosnaapostiladocursoFJ-11:Javae
OrientaçãoaObjetosdaCaelum ena apostila Programação
Orientada aObjetos em Javadoprof.Flávio MiguelVarejão.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
3
Questão deresponsabilidade (denovo!)
• Imagineumsistema...
– Dezenas deformulários;
– CPFssão validados – função validar(cpf) deve ser
chamada em cada formulário;
– Todos osdesenvolvedoressão responsáveis!
• Sem problemas!Define-seaclasse Pessoacomo
atributo cpf eométodo validar()!
– Eaí odesenvolvedor foi lá e…
Pessoa p = new Pessoa();
p.cpf = "321.654.987-00"; // Cadê a validação?
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
4
Regrasdenegócio
• Paraumacontacorrente:
class Conta {
int numero;
String dono;
double saldo;
double limite;
// ...
}
RN1: quando negativo, o
valor absoluto do saldo não
pode ser superior ao do
limite.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
5
Implementandoaregradenegócio
class Conta {
// Restante da classe...
void sacar(double qtd) {
double novoSaldo = this.saldo - qtd;
this.saldo = novoSaldo;
}
}
public class TesteConta {
public static void main(String[] args) {
Conta c = new Conta();
c.saldo = 1000.0;
c.limite = 1000.0;
c.sacar(5000);
// Vai gerar inconsistência!
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
6
Implementandoaregradenegócio
public class TesteConta {
public static void main(String[] args) {
Conta c = new Conta();
c.saldo = 1000.0;
c.limite = 1000.0;
// Vamos verificar antes de sacar...
double valorASacar = 5000.0;
if (valorASacar < c.saldo + c.limite)
c.sacar(valorASacar);
}
}
A responsabilidade está
com a classe certa?
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
7
Implementandoaregradenegócio
boolean sacar(double qtd) {
double novoSaldo = this.saldo - qtd;
if (novoSaldo >= -limite) {
this.saldo = novoSaldo;
return true;
}
else return false;
}
Conta c = new Conta();
c.saldo = 1000.0;
c.limite = 1000.0;
Conta
TesteConta
// Agora sim!
if (c.sacar(5000)) System.out.println("Consegui");
else System.out.println("Não deu...");
c.saldo = -3000.0;
Abril2016
// Só que não...
OO&Java- Modif.deacessoeatributosdeclasse
8
Faltaencapsulamento...
• Permitiroacessodiretoaos atributos:
– Exige disciplina dosclientes daclasse Conta;
– Pode levar ainconsistências;
• Solução:impedir oacesso externo ao atributo:
– Atributo privativo;
– Externo =qualquer outra clase,exceto aproprietária
doatributo (ex.:Conta paraoatributo saldo).
• Vantagens:
– Objetos trocam mensagens combaseem contratos;
– Modificações na implementação não afetam clientes
(ex.:adicionar CPMFnos saques deconta-corrente).
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
9
Encapsulamento
• Usamosobjetossemsaberseufuncionamento interno;
• Assimtambém deveseremnossossistemasOO:
– Maiormanutenibilidade;
– Maiorreusabilidade.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
10
Implementando oencapsulamento
class Conta {
private int numero;
private String dono;
private double saldo;
private double limite;
public boolean sacar(double qtd) {
// ...
}
// ...
}
Modificador
de acesso /
visibilidade!
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
11
Modificadoresdeacesso
• Determinamavisibilidade deumdeterminadomembro
daclassecomrelação aoutrasclasses;
• Háquatro níveisdeacesso:
– Público (public);
– Privado/privativo (private);
– Protegido (protected);
– Amigo ouprivativoaopacote(friendly oupackageprivate).
Regra de bolso do encapsulamento: atributos
são privativos, métodos são públicos.
Regra de bolso das regras: toda regra tem
suas exceções…
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
12
Palavras-chave
• Três palavras-chaveespecificamoacesso:
– public
– private
– protected
• Oníveldeacessopackage-private édeterminadopela
ausência deespecificador;
• Devemserusadasantes donomedomembro que
queremespecificar;
• Nãopodemserusadasemconjunto.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
13
Modificadoresdeacesso
Acesso
Público
Protegido
Amigo
Privado
A própria classe
Sim
Sim
Sim
Sim
Classe no mesmo
pacote
Sim
Sim
Sim
Não
Subclasse em
pacote diferente
Sim
Sim
Não
Não
Não-subclasse em
pacote diferente
Sim
Não
Não
Não
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
14
Testando oencapsulamento
class Conta {
// ...
private double saldo;
Conta
public boolean sacar(double qtd) {
// ...
}
}
Conta c = new Conta();
c.depositar(1000.0);
c.saldo = -3000.0;
TesteConta
// Não compila!
// error: saldo has private access in Conta
// c.saldo = -3000.0;
// ^
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
15
Separandointerfaceeimplementação
• EmOOéfundamental oocultamento deinformação:
– Estruturainterna ficainacessível;
– Interface doobjetoépública.
• Oqueéumapilha?
– Umalista?
– Umvetor?
– Umaestrutura quemepermiteempilhar e
desempilhar itens?
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
16
Ocultamentodeinformações
import java.util.*;
class Pilha {
private Vector elems;
public Pilha() {
elems = new Vector(10, 10);
}
public void empilha(Object obj) {
elems.add(obj);
}
public Object desempilha() {
Object obj = elems.get(elems.size() - 1);
elems.remove(elems.size() - 1);
return obj;
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
17
Mudandoaimplementação
import java.util.*;
class Pilha {
private LinkedList elems;
public Pilha() {
elems = new LinkedList();
}
public void empilha(Object obj) {
elems.addFirst(obj);
}
public Object desempilha() {
return elems.removeFirst();
}
}
Programe para interfaces, não para implementações!
(Design Patterns, de Eric Gamma et al.)
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
18
OexemplodoCPF
class Cliente {
private String nome;
private String endereco;
private String cpf;
private int idade;
public void mudaCPF(String cpf) {
validaCPF(cpf);
this.cpf = cpf;
}
private void validaCPF(String cpf) {
// série de regras aqui, falha caso não seja válido
}
// ...
}
Abril2016
E se um dia eu não precisar mais
validar CPF para pessoas com idade
acima de 60 anos?
OO&Java- Modif.deacessoeatributosdeclasse
19
Maseseeu precisar acessar umatributo?
• Bastausarummétodo paraisso!
class Conta {
int numero;
String dono;
double saldo;
double limite;
public double verSaldo() {
return saldo;
}
public void alterarLimite(double limite) {
this.limite = limite;
}
// ...
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
20
POJOs (oBom eVelhoObjeto Java)
• Atributosdevemserprivativos;
• Seprecisaremserlidos oualterados,provermétodos
get/set(parabooleanos,pode-seusaroprefixois):
public class Cliente {
// ...
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
IDEs geram esses métodos
}
automaticamente.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
21
Planeje bem ainterfacedaclasse
• É importante observar que:
– Ométodo getAtr() não temque necessariamente
retornar apenas oatributo atr;
– Não crie automaticamente métodos get/setpara
todos os atributos!Paraalguns não faz sentido…
// O limite faz parte do saldo (só que cobra juros)!
public double getSaldo() {
return saldo + limite;
}
// Não há método para mudar o saldo. Tem que sacar()
// public void setSaldo(double saldo)
Sugestão de leitura:
http://blog.caelum.com.br/nao-aprender-oo-getters-e-setters/
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
22
Inicialização
• Neologismocriadoparaindicartarefas quedevemser
efetuadasaoiniciarmos algo;
• Quandocriamosobjetos,podemosquererinicializá-lo
comalgunsvalores;
• Poderíamoscriarummétodo paraisso:
class Aleatorio {
private int numero;
public void inicializar() {
Random rand = new Random();
numero = rand.nextInt(20);
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
23
Construtores
• Problema dométodoinicializar(): podemos
esquecer dechamá-lo!
• Porisso,Javaprovêomecanismodeconstrutores:
– São chamadosautomaticamente peloJavaquando
umobjetonovoécriado;
– Construtoresnão tem valorderetornoepossuemo
mesmo nomedaclasse.
new → construtor
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
24
Construtores
• Quandoumnovo objetoécriado:
1. éalocadamemória paraoobjeto;
2. oconstrutor échamado.
class Aleatorio {
private int numero;
public Aleatorio() {
Random rand = new Random();
numero = rand.nextInt(20);
}
}
public class Teste {
public static void main(String[] args) {
Aleatorio aleat = new Aleatorio();
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
25
Construtorespodemterargumentos
• Sedefinidosargumentos,devemserpassadosna
criação doobjetocomnew:
class Aleatorio {
private int numero;
public Aleatorio(int max) {
Random rand = new Random();
numero = rand.nextInt(max);
}
}
public class Teste {
public static void main(String[] args) {
Aleatorio aleat1 = new Aleatorio(20);
Aleatorio aleat2 = new Aleatorio(50);
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
26
Podehavermúltiplosconstrutores
• Nossasclassespodemterquantos construtores
quisermos (comargumentosdiferentes):
class Aleatorio {
private int numero;
public Aleatorio() {
Random rand = new Random();
numero = rand.nextInt(20);
}
public Aleatorio(int max) {
Random rand = new Random();
numero = rand.nextInt(max);
}
}
public class Teste {
public static void main(String[] args) {
Aleatorio aleat1 = new Aleatorio();
Aleatorio aleat2 = new Aleatorio(50);
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
27
Construtordefault
• Quandonão especificamosconstrutores,Javaprovêum
construtordefault paranossaclasse:
– Todaclasseprecisa deumconstrutor;
– Semparâmetros esemimplementação.
• Quandoespecificamos construtores,oconstrutor
default não éprovidoautomaticamente:
– Sevocêescreveu umconstrutor,Javaassumeque
vocêsabe oqueestáfazendoenãoprovêum;
– Chamar oconstrutorsemoparâmetrogeraerro se
elenãofordefinidoexplicitamente.
Isso é bom! Mas por que?
(Apostila Caelum, sec. 6.5)
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
28
Construtoreschamandoconstrutores
• Seriainteressante nãohaverduplicação decódigo:
class Aleatorio {
private int numero;
public Aleatorio() {
Random rand = new Random();
numero = rand.nextInt(20);
}
public Aleatorio(int max) {
Random rand = new Random();
numero = rand.nextInt(max);
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
29
Construtoreschamandoconstrutores
• Usamosnovamente apalavra-chavethis,comoutro
significado:chamaroutroconstrutor:
class Aleatorio {
private int numero;
public Aleatorio() {
// Chama o outro construtor com argumento 20.
this(20);
}
public Aleatorio(int max) {
Random rand = new Random();
numero = rand.nextInt(max);
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
30
Construtoreschamandoconstrutores
• Achamadathis():
– Deveespecificarosargumentos doconstrutoraser
chamado;
– Deveseraprimeira linhadoconstrutorqueautiliza;
– Nãopodeserusadaforadeconstrutores.
Depois que o objeto foi construído,
não é mais possível chamar o
construtor para ele.
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
31
Opadrão JavaBean
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
32
DesenvolvimentoOOcomJava– Modific.deacessoeatributosdeclasse
ATRIBUTOSDECLASSE
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
33
Atributos independentes deobjetos
• Vimosatéagoraqueatributos pertencemaosobjetos:
– Nãosefaznadasemantescriar umobjeto(new)!
• Noentanto,hásituações quevocêquerusá-lossem ter
quecriarobjetos:
public class TesteConta {
public static void main(String[] args) {
int qtdContas = 0;
Conta c1 = new Conta();
qtdContas++;
Conta c2 = new Conta();
qtdContas++;
// ...
}
}
Abril2016
A responsabilidade está
com a classe certa?
OO&Java- Modif.deacessoeatributosdeclasse
34
Atributos independentes deobjetos
• Seacertamos aresponsabilidade,voltamos adepender
deumobjeto parausar oatributo:
class Conta {
// ...
public int qtdContas = 0;
public Conta() {
qtdContas++;
}
// Outras inicializações...
}
Conta c1 = new Conta();
Conta c2 = new Conta();
TesteConta
// Quantas contas foram criadas?
System.out.println(c2.qtdContas);
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
35
Atributosstatic
• Usandoapalavra-chavestatic vocêdefineum
atributodeclasse(“estático”):
– Pertenceàclasse comoumtodo;
– Pode-seacessá-losmesmosemtercriado umobjeto;
– Objetospodem acessá-loscomosefosseum
membrodeobjeto,sóquecompartilhado.
class Conta {
// ...
public static int qtdContas = 0;
public Conta() {
qtdContas++;
}
// Outras inicializações...
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
36
Acesso aatributos static
• Não precisamos mais deumobjeto pra acessar:
public class TesteConta {
public static void main(String[] args) {
Conta c1 = new Conta();
Conta c2 = new Conta();
System.out.println(Conta.qtdContas);
// ...
}
}
O atributo é da classe.
A visibilidade está certa?
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
37
Acesso aatributos static
• Seacertamos avisibilidade doatributo,precisamos
então deummétodo paraacessá-lo:
class Conta {
// ...
private static int qtdContas = 0;
public Conta() {
qtdContas++;
}
// Outras inicializações...
public int getQtdContas() {
return qtdContas;
}
}
Mas não sendo static, vou precisar de um
objeto pra acessar o atributo de novo!?!
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
38
Métodos static
• Métodos também podem ser static:
class Conta {
// ...
private static int qtdContas = 0;
public Conta() { qtdContas++; /* ... */ }
public static int getQtdContas() {
return qtdContas;
}
}
Conta c1 = new Conta();
Conta c2 = new Conta();
TesteConta
// Quantas contas foram criadas?
System.out.println(Conta.getQtdContas());
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
39
Armazenamentoemmemória
Classe Conta
qtdContas = 2
sacar()
depositar()
saldo =
1_000_000_000
meuSonho
minhaConta
Março2016
saldo = 1_000
OO&Java- Orientaçãoaobjetosbásica
40
Contexto static
• Métodos staticnão podem acessar membros não-static:
public class Teste {
private int atributo;
private int atributoStatic;
public void metodo() { }
public static void metodoStatic() { }
public static void main(String[] args) {
// ...
System.out.println(atributoStatic);
System.out.println(Teste.atributoStatic);
metodoStatic();
Teste.metodoStatic();
// Continua...
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
41
Contexto static
//
//
//
//
//
Não pode:
System.out.println(atributo);
System.out.println(Teste.atributo);
metodo();
Teste.metodo();
// Preciso de um objeto:
Teste t = new Teste();
System.out.println(t.atributo);
t.metodo();
}
}
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
42
Cuidadocomostatic
• Membrosestáticos são como variáveis/funções globais;
• Sãomais procedurais doque orientados aobjetos;
• Noentanto,em alguns casos são necessários…
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
43
Exercitar é fundamental
• ApostilaFJ-11daCaelum:
– Seção 6.8,página 81(classFuncionario);
– Seção 6.9,página 83(desafios).
Abril2016
OO&Java- Modif.deacessoeatributosdeclasse
44
http://nemo.inf.ufes.br/
Download