15-09-2009 PARTE III: Java e OO - detalhes Membros de classe e de instância De classe Static Membros de classe e instâncias Pacotes Visibilidade Classes aninhadas Método De instância não static não necessita de objeto para necessita de objeto para ser chamado. ser chamado. Atributo existe um só cópia para todos os objetos da classe. há uma cópia para cada objeto instanciado. 1 2 Exercício Exemplo 1: método public class A { public static int x = 7; public int y = 3; public static int somar(int v) { return x + v; } public int multiplicar() { return x * y; } } 1.public class ImprimirStrings { 2. String str = “atributo-nao-estatico”; 3. public void imprimir() { 4. String a = new String(“aaa”); 5. String b = new String(“bbb”); 6. System.out.println(a.concat(b)); 7. } 8. public static void main(String[] args) { 9. imprimir(); 10. } 11.} a. Quais são os atributos e métodos de classe? b. Quais são os atributos e métodos de instância? Fonte http://java.sun.com/docs/books/tutorial/java/javaOO/QandE/creating-questions.html ERRO! non-static method imprimir() cannot be referenced from static context 3 Exemplo 1 corrigido 4 Exemplo 1 corrigido – versão 2 1.public class ImprimirStrings { 2. String str = “atributo-nao-estatico”; 1.public class ImprimirStrings { 2. String str = “atributo-nao-estatico”; 3. public void imprimir() { 4. String a = new String(“aaa”); 5. String b = new String(“bbb”); 6. System.out.println(a.concat(b)); 7. } 3. public static void imprimir() { 4. String a = new String(“aaa”); 5. String b = new String(“bbb”); 6. System.out.println(a.concat(b)); 7. } 8. public static void main(String[] args) { 9. ImprimirStrings is = new ImprimirStrings(); 10. is.imprimir() 11. } 12.} 8. public static void main(String[] args) { 9. imprimir(); 10. } 11.} 5 6 1 15-09-2009 Exemplo 2: atributo Exemplo 2 corrigido 1.public class ImprimirStrings { 2. String str = “atributo-nao-estatico”; 1.public class ImprimirStrings { 2. String str = “atributo-nao-estatico”; 3. public void imprimir() { 4. String a = new String(“aaa”); 5. String b = new String(“bbb”); 6. System.out.println(a.concat(b)); 7. System.out.println(str); 8. } 3. public static void imprimir() { 4. String a = new String(“aaa”); 5. String b = new String(“bbb”); 6. System.out.println(a.concat(b)); 7. System.out.println(str); 8. } 9. public static void main(String[] args) { 10. ImprimirStrings obj = new ImprimirStrings(); 11. obj.imprimir(); 12. } 13.} 9. public static void main(String[] args) { 10. imprimir(); 11. } 12.} ERRO! non-static variable str cannot be referenced from static context 7 Exemplo 3: métodos e atributos de utilidade 8 Exercícios Da apostila: 1.public class Circle { 2. public static double calculaArea(double raio) { 3. return Math.PI * ( raio * raio ); 4. } 5. } 09 (num autos feitos) 10 (num instâncias de sinaleiros) JAVARepositorio/JRevisaoOO/JExercSinaleiroInstanciasSol 6.// Dentro de um método qualquer... 7.// utilizamos o nome da classe na chamada 8. double circleArea = Circle.calculaArea(5); 9.} Não abusar do uso de métodos static se não criamos programas sem objetos 9 10 PARTE III: Java e OO - detalhes Pacotes em Java Membros de classe e instâncias Pacotes Visibilidade Classes aninhadas Declaração em Java: Deve ser a 1ª declaração do arq. Sintaxe: package <nome>; Exemplos: package poligono; package primitiva; Importar pacotes import primitiva.*; Somente as classes utilizadas no programa são carregadas pela JVM 11 import primitiva.Ponto; 12 2 15-09-2009 Pacotes: packages Pacotes: representação UML Nome do pacote É uma coleção de classes Melhorar organização do código Reduzir conflito de nomes Relação Convenção Sun edu.utfpr.<nome do pacote> edu.utfpr.dainf.<nome do pacote> com.uol.<nome do pacote> 13 14 Pacotes em Java: conflito de nomes Pacotes: organização do código Dois pacotes com classes ponto Diretório dos fontes package primitiva class Ponto ... <proj>/src/ poligono • Regular.java • Hexagono.java • Pentagono.java package base class Ponto ... primitiva • Linha.java • Ponto.java Para distingui-las: Diretório .class <proj>/build/classes/ poligono • Regular.class • Hexagono.class • Pentagono.class primitiva • Linha.class • Ponto.class > cd <proj>/src primitiva.Ponto base.Ponto > javac poligono/*.java primitiva/*.java -d ../build/classes 15 opção d: compilador cria diretórios com base na declaração package; o 16 diretório ../build/classes deve existir!!! Visibilidade classes, métodos e atributos PARTE III: Java e OO - detalhes Membros de classe e instâncias Pacotes Visibilidade Classes aninhadas Níveis de controle de acesso - Privado # Protegido + Público ~ De Pacote (default) 17 18 3 15-09-2009 Visibilidade privada Elemento - Visibilidade atributos privados Pessoa Aplica-se Classe top-level NÃO Classe aninhada SIM Método SIM Atributo SIM -nome: String classes derivadas não podem acessar membros privados da classe base Membros private de uma classe base não são herdados pelas classes derivadas :Aluno -nome: String curso=“informatica” -anoNasc: int 19 Aluno O objeto aluno pode ver os atributos nome e anoNasc, e o método calcIdade de Pessoa? -curso: String Nome has private access in Pessoa O objeto José pode acessar o atributo privado de João? } 20 # Visibilidade protegida class Main { public static void main(String args[]) { Aluno a = new Aluno(); a.curso = “informatica”; a.nome = “Jairo”; a.anoNasc = 1975; int i = a.calcIdade(); … -calcIdade: int Nome=“João” void copiarNome(Pessoa outra) { nome = outra.nome; } Visibilidade método privado Pessoa joão:Pessoa Nome=“José” class Pessoa { private String nome; public Pessoa(String nome) { this.nome = nome; } Membros privados somente podem ser acessados na mesma classe. Assim, Membros = métodos/atributos josé:Pessoa Elemento Aplica-se Classe top-level NÃO Classe aninhada SIM Método SIM Atributo SIM Membros protegidos podem ser acessados por classes do mesmo pacote Membros protegidos são herdados; assim classes derivadas podem acessá-los (mesmo se estiverem em pacotes diferentes). Cannot find method 21 Visibilidade protegida (exemplo) Pessoa :Aluno #nome: String curso=“informatica” #anoNasc: int Visibilidade default O objeto aluno pode ver os atributos nome e anoNasc, e o método calcIdade de Pessoa? class Main { public static void main(String args[]) { Aluno a = new Aluno(); a.curso = “informatica”; a.nome = “Jairo”; a.anoNasc = 1975; int i = a.calcIdade(); … #calcIdade: int Aluno #curso: String OK 22 OK 23 Elemento Classe top-level ~ Aplica-se SIM Classe aninhada SIM Método SIM Atributo SIM É o valor assumido, quando nada é especificado Membros sem modificadores podem ser acessados por classes do mesmo pacote Membros default são herdados; assim classes derivadas podem acessá-los (somente se estiverem no mesmo pacote diferente do protegido). 24 4 15-09-2009 + Visibilidade pública Elemento VISIBILIDADE: quadro resumo Aplica-se Classe SIM Classe aninhada SIM Método SIM Atributo SIM Privado Protegido private protected Classe* Aninhada Método Atributo Todas as classes podem visualizar atributos, métodos e classes públicas, independente do pacote onde estejam. Obs: somente uma classe pública é permitida por arquivo fonte .java NÃO SIM SIM SIM NÃO SIM SIM SIM Pacote default Público public SIM SIM SIM SIM SIM SIM SIM SIM * classes não aninhadas 25 26 Exercícios PARTE III: Java e OO - detalhes Apostila Membros de classe e instâncias Pacotes Visibilidade Classes aninhadas 11 JRevisaoOO\JExercSinaleiroConstrutoraPrivate 12 JRevisaoOO\JExercPacotes 13 JRevisaoOO\JCadastroUsuario 27 28 Exemplo Classes aninhadas public class JLinha { private static int totLinha=0; private int idLinha; protected Ponto pt1; protected Ponto pt2; Uma classe é definida como membro de outra classe public JLinha(int x1, int y1, int x2, int y2) { idLinha = ++totLinha; pt1 = new Ponto(x1, y1); pt2 = new Ponto(x2, y2); } public JLinha() { idLinha = ++totLinha; } CLASSE EXTERNA public class Ponto { protected int x; protected int y; CLASSE ANINHADA protected Ponto(int x, int y) { this.x = x; this.y = y; } protected String pontoStr() { return "(" + x + ", " + y + ")"; } protected String pontoStrComId(){ return "Linha " + idLinha + " " + pontoStr(); } } 29 } Tem acesso aos membros da classe JLinha 30 5 15-09-2009 Instanciação: forma 1 Instanciação de classes aninhadas Há duas formas como mostram os slides a seguir: 1. a construtora de Jlinha instancia os pontos 2. instancia-se Jlinha para depois instanciar os pontos public class JMain { public static void main(String args[]) { // Forma 1: a construtora de linha instancia // os dois pontos JLinha l1 = new JLinha(5, 15, 7, 17); System.out.println(l1.pt1.pontoStr() + " " + l1.pt2.pontoStr()); } } Observar que o acesso aos pontos se faz pela linha 31 Instanciação: forma 2 JRevisaoOO\JLinhaClasseAninhada 32 Objetos de classes internas public class JMain { public static void main(String args[]) { // Forma 2: instancia-se linha e depois os pontos JLinha l2 = new JLinha(); JLinha.Ponto p1 = l2.new Ponto(10, 10); JLinha.Ponto p2 = l2.new Ponto(20, 20); l2.pt1 = p1; l2.pt2 = p2; System.out.println(l2.pt1.pontoStrComId() + " " + l2.pt2.pontoStrComId()); } } !!! Importante !!! Pontos só podem existir se houver uma linha Linha = objeto externo Ponto 1 obj. interno Ponto 2 obj. interno Observar que a classe Ponto só existe no contexto da JLinha JRevisaoOO\JLinhaClasseAninhada 33 Exercícios 34 Representanção em UML Baixe o código das classes aninhadas disponível em Agregação por composição http://www.dainf.ct.utfpr.edu.br/~tacla/JAVARepositorio/JRevisaoOO/JLinhaClasseAninhada/ JLinha Ponto -totLinha:int=0 Observe a existência do JLinha$Ponto.class +JLinha(x:int, y:int, x2:int, y2:int) +linhaToString():String 1 2 #x: int #y: int #Ponto(x:int, y:int) #pontoToString():String Desaninhe a classe Ponto de JLinha preservando os mesmos comportamentos 35 Os dois exemplos Ponto aninhado e não aninhado são representados de forma similar em UML. 36 6 15-09-2009 Classe Aninhada Estática Exercícios: interface e aninhamento Fazer exercício 14 da apostila (transcrito abaixo) Utilize uma classe interna que implemente a interface Iterator e permita navegar num vetor de 10 inteiros aleatórios armazenados em um atributo de instância da classe externa. O método next() do Iterator deve retornar somente os valores ímpares armazenados no vetor. Por exemplo, se no vetor existirem os seguintes números: [100, 39, 88, 13, 4, 4, 2, 5, 94, 32], a sequência de invocações de next() produz: next() -> 39 next() -> 13 next() -> 5 next() -> throw NoSuchElementExecption O métod hasNext() verifica se há um ímpar em alguma posição além das já pesquisadas. A implementação do método remove() é opcional e, caso não seja feita, deve retornar uma instância de UnsupportedOperationException (com throw) Solução em \JRevisaoOO\JAninhadaIteratorSol 37 1.public class JRadar { 2. private int velocidadeMaxima; 3. 4. public JRadar(int v) { 5. velocidadeMaxima = v; 6. } 7. public Boolean multar(int v) { 8. // multar return true qdo a velocidade detectada pelo 9. // radar excede em 10% a velocidade maxima; 10. if (v > (velocidadeMaxima * 1.1)) 11. return true; 12. else 13. return false; 14. } 15. public static class TesteJRadar{ 16. public static void main(String args[]) { 17. JRadar r[] = {new JRadar(40), new JRadar(60), new JRadar(110)}; 18. int v[] = {44, 67, 110}; 19. Boolean res[]={false, true, false}; 20. for (int i=0; i < r.length; i++) { 21. if (r[i].multar(v[i]) == res[i]) 22. System.out.println("OK"); 23. else 24. System.out.println("ERRO: radar " + i); 25. } 26. } 27. } 28.} 38 RepositorioJAVA\JRevisaoOO\JExemClasseAninhadaEstaticaRadar Exercícios Classe aninhada estática Observe os .class gerados por javac Fazer exercício 15 da apostila (transcrito abaixo) JRadar.class JRadar$TesteJRadar.class Utilize uma classe aninhada estática para testar uma classe externa que calcula o dígito verificador de um código composto por três dígitos da seguinte forma: 829 => 8*4 + 2*3 + 9*2 = 56 => 56 % 10 = 6 (dígito verificador). O teste deve ser feito para dois códigos cujos dígitos verificadores são conhecidos. Para executar na linha de comando java JRadar$TesteJRadar Solução JRevisaoOO\JExerClasseAninhadaEstaticaDVSol 39 40 Por que utilizar classes aninhadas? Tipos de classe aninhada Quando a classe interna for utilizada somente pela externa 1. class Externa { 2. ... 3. class Interna { 4. ... 5. } 6. 7. class static AninhadaEstatica { 8. ... 9. } 10. } Aumenta encapsulamento Se as classes aninhadas forem pequenas Aumenta legibilidade código mais próximo da onde é utilizado 41 42 7 15-09-2009 Interna x Aninhada static Classes internas anônimas Interna (não static) Aninhada Static SIM NÃO Classe interna tem acesso a SIM atributos de instância e métodos da classe externa? NÃO Um objeto da classe interna tem implicitamente uma referência ao objeto da sua classe externa? NÃO (não há objeto) Necessário instanciar objeto da classe externa? SIM 1.Button b = new Button("Ok"); 2.b.addActionListener( 3. new ActionListener() { 4. public void actionPerformed(ActionEvent e) { 5. tratarOK(); 6. } 7. } 8.); As linhas [3, 7] instanciam um objeto da classe ActionListener e sobrescrevem o método actionPerformed. Este objeto é passado como argumento do método addActionListener na linha 2. ActionListener é uma classe interface. 43 44 Classes internas anônimas (e.g. 2) 1. public static void main(String args[]) { 2. java.awt.EventQueue.invokeLater( 3. new Runnable() { 4. public void run() { 5. new IUEditor().setVisible(true); 6. } 7. } 8. ); 9. } Somente podemos instanciar classes anônimas que estendem outra classe ou que implementem outra classe (não as duas coisas ao mesmo tempo e nem mais de uma classe de interface). Por exemplo, a classe Runnable é de interface e, neste exemplo, é instanciada. 45 8