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
CommonsAtribuição-CompartilhaIgual 4.0Internacional;• Vocêtemodireitode:
– Compartilhar:copiareredistribuiromaterialemqualquersuporteouformato
– Adaptar:remixar,transformar,ecriarapartirdomaterialparaqualquerfim,mesmoquecomercial.
• Deacordocomostermosseguintes:– Atribuição:vocêdevedarocréditoapropriado,proverumlinkpara
alicençaeindicarsemudançasforamfeitas.Vocêdevefazê-loemqualquercircunstânciarazoável,masdemaneiraalgumaquesugiraaolicencianteaapoiarvocêouoseuuso;
– CompartilhaIgual:sevocêremixar,transformar,oucriarapartirdomaterial,temdedistribuirassuascontribuiçõessobamesmalicençaqueooriginal.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 2
Mais informações podem ser encontradas em:http://creativecommons.org/licenses/by-sa/4.0/
Conteúdodocurso
• OqueéJava;• Variáveisprimitivasecontroledefluxo;
• Orientaçãoaobjetosbásica;
• Umpoucodevetores;• Modificadoresdeacessoeatributosdeclasse;
• Herança,reescritaepolimorfismo;
• Classesabstratas;• Interfaces;• Exceçõesecontroledeerros;
• UtilitáriosdaAPIJava.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 3
EstesslidesforambaseadosnaapostiladocursoFJ-11:JavaeOrientaçãoaObjetosdaCaelum ena apostila ProgramaçãoOrientada aObjetos em Javadoprof.FlávioMiguelVarejão.
Questão deresponsabilidade (denovo!)• Imagineumsistema...
– Dezenas deformulários;– CPFssão validados – função validar(cpf) deve serchamada em cada formulário;
– Todos osdesenvolvedoressão responsáveis!
• Sem problemas!Define-seaclasse Pessoacomoatributo cpf eométodo validar()!– Eaí odesenvolvedor foi lá e…
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 4
Pessoa p = new Pessoa();p.cpf = "321.654.987-00"; // Cadê a validação?
Regrasdenegócio• Paraumacontacorrente:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 5
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.
Implementandoaregradenegócio
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 6
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!
}}
Implementandoaregradenegócio
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 7
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?
Implementandoaregradenegócio
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 8
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;
// Agora sim!if (c.sacar(5000)) System.out.println("Consegui");else System.out.println("Não deu...");
c.saldo = -3000.0; // Só que não...
Conta
TesteConta
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áriadoatributo (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
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 11
class Conta {private int numero;private String dono;private double saldo;private double limite;
public boolean sacar(double qtd) {// ...
}
// ...}
Modificador de acesso / visibilidade!
Modificadoresdeacesso• Determinamavisibilidade deumdeterminadomembrodaclassecomrelação aoutrasclasses;
• Háquatro níveisdeacesso:– Público (public);– Privado/privativo (private);– Protegido (protected);– Amigo ouprivativoaopacote(friendly oupackage-private).
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 12
Regra de bolso do encapsulamento: atributossão privativos, métodos são públicos.
Regra de bolso das regras: toda regra tem suas exceções…
Palavras-chave• Três palavras-chaveespecificamoacesso:
– public
– private
– protected
• Oníveldeacessopackage-private édeterminadopelaausência deespecificador;
• Devemserusadasantes donomedomembro quequeremespecificar;
• Nãopodemserusadasemconjunto.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 13
Modificadoresdeacesso
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 14
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
Testando oencapsulamento
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 15
class Conta {// ...private double saldo;
public boolean sacar(double qtd) {// ...
}}
Conta c = new Conta();c.depositar(1000.0);c.saldo = -3000.0;
// Não compila!// error: saldo has private access in Conta// c.saldo = -3000.0;// ^
Conta
TesteConta
Separandointerfaceeimplementação• EmOOéfundamental oocultamento deinformação:
– Estruturainterna ficainacessível;– Interface doobjetoépública.
• Oqueéumapilha?– Umalista?– Umvetor?– Umaestrutura quemepermiteempilhar edesempilhar itens?
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 16
Ocultamentodeinformações
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 17
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;
}}
Mudandoaimplementação
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 18
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.)
OexemplodoCPF
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 19
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
}
// ...}
E se um dia eu não precisar maisvalidar CPF para pessoas com idade
acima de 60 anos?
Maseseeu precisar acessar umatributo?• Bastausarummétodo paraisso!
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 20
class Conta {int numero;String dono;double saldo;double limite;
public double verSaldo() {return saldo;
}
public void alterarLimite(double limite) {this.limite = limite;
}
// ...}
POJOs (oBom eVelhoObjeto Java)• Atributosdevemserprivativos;• Seprecisaremserlidos oualterados,provermétodosget/set(parabooleanos,pode-seusaroprefixois):
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 21
public class Cliente {// ...private String nome;
public String getNome() {return nome;
}
public void setNome(String nome) {this.nome = nome;
}}
IDEs geram esses métodosautomaticamente.
Planeje bem ainterfacedaclasse• É importante observar que:
– Ométodo getAtr() não temque necessariamenteretornar apenas oatributo atr;
– Não crie automaticamente métodos get/setparatodos os atributos!Paraalguns não faz sentido…
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 22
// 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/
Inicialização• Neologismocriadoparaindicartarefas quedevemserefetuadasaoiniciarmos algo;
• Quandocriamosobjetos,podemosquererinicializá-locomalgunsvalores;
• Poderíamoscriarummétodo paraisso:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 23
class Aleatorio {private int numero;
public void inicializar() {Random rand = new Random();numero = rand.nextInt(20);
}}
Construtores• Problema dométodoinicializar(): podemosesquecer dechamá-lo!
• Porisso,Javaprovêomecanismodeconstrutores:– São chamadosautomaticamente peloJavaquandoumobjetonovoécriado;
– Construtoresnão tem valorderetornoepossuemomesmo nomedaclasse.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 24
new → construtor
Construtores• Quandoumnovo objetoécriado:
1. éalocadamemória paraoobjeto;2. oconstrutor échamado.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 25
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();}
}
Construtorespodemterargumentos• Sedefinidosargumentos,devemserpassadosnacriação doobjetocomnew:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 26
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);
}}
Podehavermúltiplosconstrutores• Nossasclassespodemterquantos construtoresquisermos (comargumentosdiferentes):
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 27
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);
}}
Construtordefault• Quandonão especificamosconstrutores,Javaprovêumconstrutordefault paranossaclasse:– Todaclasseprecisa deumconstrutor;– Semparâmetros esemimplementação.
• Quandoespecificamos construtores,oconstrutordefault não éprovidoautomaticamente:– Sevocêescreveu umconstrutor,Javaassumequevocêsabe oqueestáfazendoenãoprovêum;
– Chamar oconstrutorsemoparâmetrogeraerro seelenãofordefinidoexplicitamente.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 28
Isso é bom! Mas por que?(Apostila Caelum, sec. 6.5)
Construtoreschamandoconstrutores• Seriainteressante nãohaverduplicação decódigo:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 29
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);
}}
Construtoreschamandoconstrutores• Usamosnovamente apalavra-chavethis,comoutrosignificado:chamaroutroconstrutor:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 30
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);
}}
Construtoreschamandoconstrutores• Achamadathis():
– Deveespecificarosargumentos doconstrutoraserchamado;
– Deveseraprimeira linhadoconstrutorqueautiliza;– Nãopodeserusadaforadeconstrutores.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 31
Depois que o objeto foi construído, não é mais possível chamar o
construtor para ele.
Opadrão JavaBean
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 32
ATRIBUTOSDECLASSEDesenvolvimentoOOcomJava– Modific.deacessoeatributosdeclasse
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 33
Atributos independentes deobjetos• Vimosatéagoraqueatributos pertencemaosobjetos:
– Nãosefaznadasemantescriar umobjeto(new)!• Noentanto,hásituações quevocêquerusá-lossem terquecriarobjetos:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 34
public class TesteConta {public static void main(String[] args) {
int qtdContas = 0;Conta c1 = new Conta();qtdContas++;
Conta c2 = new Conta();qtdContas++;// ...
}} A responsabilidade está
com a classe certa?
Atributos independentes deobjetos• Seacertamos aresponsabilidade,voltamos adependerdeumobjeto parausar oatributo:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 35
class Conta {// ...public int qtdContas = 0;
public Conta() {qtdContas++; // Outras inicializações...
}}
Conta c1 = new Conta();Conta c2 = new Conta();
// Quantas contas foram criadas?System.out.println(c2.qtdContas);
TesteConta
Atributosstatic• Usandoapalavra-chavestatic vocêdefineumatributodeclasse(“estático”):– Pertenceàclasse comoumtodo;– Pode-seacessá-losmesmosemtercriado umobjeto;– Objetospodem acessá-loscomosefosseummembrodeobjeto,sóquecompartilhado.
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 36
class Conta {// ...public static int qtdContas = 0;
public Conta() {qtdContas++; // Outras inicializações...
}}
Acesso aatributos static• Não precisamos mais deumobjeto pra acessar:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 37
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?
Acesso aatributos static• Seacertamos avisibilidade doatributo,precisamosentão deummétodo paraacessá-lo:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 38
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!?!
Métodos static• Métodos também podem ser static:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 39
class Conta {// ...private static int qtdContas = 0;
public Conta() { qtdContas++; /* ... */ }
public static int getQtdContas() {return qtdContas;
}}
Conta c1 = new Conta();Conta c2 = new Conta();
// Quantas contas foram criadas?System.out.println(Conta.getQtdContas());
TesteConta
Armazenamentoemmemória
Março2016 OO&Java- Orientaçãoaobjetosbásica 40
Classe Conta
sacar()depositar()
saldo = 1_000_000_000
saldo = 1_000
meuSonhominhaConta
qtdContas = 2
Contexto static• Métodos staticnão podem acessar membros não-static:
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 41
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...
Contexto static
Abril2016 OO&Java- Modif.deacessoeatributosdeclasse 42
// 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();
}}
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/
Top Related