Slides 05 - Modificadores de acesso e atributos de classe · Abril 2016 OO & Java - Modif. de...

Post on 01-Dec-2018

226 views 0 download

Transcript of Slides 05 - Modificadores de acesso e atributos de classe · Abril 2016 OO & Java - Modif. de...

Desenvolvimento OO com Java

Modificadores de acesso e atributos de classe

Vítor E. Silva Souza

(vitor.souza@ufes.br)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/