Classes Internas

1,520 views

Published on

Published in: Technology, Health & Medicine
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,520
On SlideShare
0
From Embeds
0
Number of Embeds
73
Actions
Shares
0
Downloads
22
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Classes Internas

  1. 1. Classes Internas Raphael Marques
  2. 2. Classes Internas • Tem gerado relações de amor e ódio desde sua introdução na versão 1.1 • Permite criar uma classe dentro de outra • Uma classe é um MEMBRO de outra classe (como campos e métodos) • Na prova geralmente são utilizadas em exemplos sobre outros tópicos
  3. 3. Classes Internas • Podem acessar todos os membros da classe externa, mesmo os private • Isso não quebra o encapsulamento • Classe interna regular: – Não é static – Não é local a um método – Não é anônima
  4. 4. Classes Internas class MyOuter { class MyInner {} } %javac MyOuter.java MyOuter.class MyOuter$MyInner.class %java MyOuter$MyInner
  5. 5. Classes Internas class MyOuter { class MyInner {} } %javac MyOuter.java MyOuter.class MyOuter$MyInner.class %java MyOuter$MyInner → ERRO
  6. 6. Classes Internas • %java MyOuter$MyInner → ERRO • Uma classe interna regular não pode ter nenhuma declaração static • Lembrando: uma classe interna regular não é static
  7. 7. Classes Internas class MyOuter{ private int x = 7; class MyInner{ public void seeOuter(){ System.out.println(“x: ”+x); } } }
  8. 8. Classes Internas • Para instanciar uma classe interna, é preciso uma instância da classe externa
  9. 9. Classes Internas class MyOuter{ private int x = 7; public void makeInner(){ MyInner in = new MyInner(); in.seeOuter(); } class MyInner{ public void seeOuter(){ System.out.println(“x: ”+x); } } }
  10. 10. Classes Internas • MyInner in = new MyInner(); • Só é possível porque não existe nenhuma outra classe chamada MyInner acessível • E como acessar a classe interna se ela precisa de uma instancia da classe externa?
  11. 11. Classes Internas public static void main(String[] args){ MyOuter outer = new MyOuter(); MyOuter.MyInner inner = mo.new MyInner(); inner.seeOuter(); } public static void main(String[] args){ MyOuter.MyInner inner = new MyOuter().new MyInner(); inner.seeOuter(); }
  12. 12. Classes Internas • Regras para utilização: – Use MyInner dentro da classe externa – Use MyOuter.MyInner fora da classe externa – Use MyInner fora da classe externa se você já tem uma instância da classe externa
  13. 13. Classes Internas public static void main(String[] args){ Outer outer = new Outer(); outer.new Inner(); outer.new Outer.Inner(); }
  14. 14. Classes Internas public static void main(String[] args){ Outer outer = new Outer(); outer.new Inner(); → LEGAL outer.new Outer.Inner(); → ILEGAL }
  15. 15. Classes Internas class MyOuter{ class MyInner{} void makeInner(){ MyInner a = new MyInner(); MyInner b = this.new MyInner(); } }
  16. 16. Classes Internas • E o this? • O this refere-se ao objeto da classe interna • Outer.this refere-se ao objeto da classe externa
  17. 17. Classes Internas public class Outer{ private int x = 7; public class Inner{ private int x = 5; public void doSomething(){ ...println(this.getClass()); ...println(Outer.this.getClass()); ...println(x); ...println(this.x); ...println(Outer.this.x); } } } ... new Outer().new Inner(). doSomething();
  18. 18. Classes Internas public class Outer{ private int x = 7; public class Inner{ private int x = 5; public void doSomething(){ ...println(this.getClass()); → class Outer$Inner ...println(Outer.this.getClass()); → class Outer ...println(x); → 5 ...println(this.x); → 5 ...println(Outer.this.x); → 7 } } } ... new Outer().new Inner(). doSomething();
  19. 19. Classes Internas • Modificadores aplicáveis a classes internas: – final – abstract – public – private – protected – strictfp – static • a classe interna vira classe aninhada • nested class
  20. 20. Classes Internas Locais a Métodos public void m(){ class Inner{ public void doSomething(){ System.out.println(quot;x:quot;+x); } } new Inner().doSomething(); } Gera: Outer.class e Outer$1Inner.class
  21. 21. Classes Internas Locais a Métodos public static void m(){ class Inner{ public void doSomething(){ System.out.println(quot;x:quot;+x); } } new Inner().doSomething(); } Gera: Outer.class e Outer$1Inner.class
  22. 22. Classes Internas Locais a Métodos public static void m(){ class Inner{ public void doSomething(){ System.out.println(quot;x:quot;+x); → ILEGAL } } new Inner().doSomething(); } Gera: Outer.class e Outer$1Inner.class
  23. 23. Classes Internas Locais a Métodos public class Outer{ public void m1(){ class Inner{} } public void m2(){ class Inner{} } } Gera: Outer.class, Outer$1Inner.class e Outer$1Inner.class
  24. 24. Classes Internas Locais a Métodos public void m(){ class Inner{} Inner inner = new Inner(); → LEGAL } public void m(){ Inner inner = new Inner(); → ILEGAL class Inner{} }
  25. 25. Classes Internas Locais a Métodos • Uma classe interna local não pode usar as variáveis locais do método em que a classe interna está. public class Outer{ void doSomething(){ int x = 0; class Inner{ public void seeOuter(){ System.out.println(x); → ILEGAL } } } }
  26. 26. Classes Internas Locais a Métodos • Porque? – A variável local ao método só existe durante a execução do método – Depois que o método termina a variável vira história – Mas a referência ao objeto da classe interna pode se manter na memória • Solução: – Marcar a variável local como final – É uma exigência do compilador
  27. 27. Classes Internas Locais a Métodos • Só podem receber os modificadores: – final – abstract
  28. 28. Classes Internas Anônimas class Popcorn { public void pop() { System.out.println(quot;popcornquot;); } } class Food { Popcorn p = new Popcorn() { public void pop() { System.out.println(quot;anonymous popcornquot;); } }; }
  29. 29. Classes Internas Anônimas Popcorn p = new Popcorn() { ... } • O campo p da classe Food não faz referência à um objeto da classe Popcorn, mas sim a um objeto da subclasse anônima de Popcorn. • Pode ser utilizado para estender superclasses ou implementar UMA interface • O construtor usado deve existir na superclasse • É possível declarar construtores em classes anônimas?
  30. 30. Classes Internas Anônimas Popcorn p = new Popcorn(); – Objeto da classe Popcorn Popcorn p = new Popcorn() { public void pop() {...} }; – Objeto da subclasse anônima de Popcorn – Sobrescrevendo o método pop()
  31. 31. Classes Internas Anônimas Popcorn p = new Popcorn(); – Objeto da classe Popcorn Popcorn p = new Popcorn() { public void pop() {...} }; ← ← ← ← ← ← ← ← ← ← ← ← ← – Objeto da subclasse anônima de Popcorn – Sobrescrevendo o método pop()
  32. 32. Classes Internas Anônimas Popcorn p = new Popcorn() { public void pop() {...} public void something() {...} }; O segundo método não estará acessível na referência p
  33. 33. Classes Internas Anônimas • Cuidado! Runnable r = new Runnable(); → ILEGAL Runnable r = new Runnable(){ public void run(){ } }; → LEGAL
  34. 34. Classes Internas Anônimas como Parâmetro System.out.println( new Popcorn(){ public String toString(){ return “new poporn”; } } ); →“new popcorn”
  35. 35. Classes Estáticas Aninhadas • São classes internas estáticas – Não são classes internas pela definição • A classe interna pode ser acessada sem precisar de uma instancia da classe externa
  36. 36. Classes Estáticas Aninhadas public class Outer{ public static class Nest {} public static void main(String[] args){ Nest n = new Nest(); } } ... public static void main(String[] args){ Outer.Nest n = new Outer.Nest(); }
  37. 37. Classes Internas • Cuidado com a sintaxe estranha • Saiba as características de classes internas, locais a métodos, e classes aninhadas • Não esqueça do ; quando criar uma classe anônima atribuindo a uma referência

×