Classes Internas

3,359 views

Published on

Slides sobre classes internas de Java

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

No Downloads
Views
Total views
3,359
On SlideShare
0
From Embeds
0
Number of Embeds
754
Actions
Shares
0
Downloads
57
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Classes Internas

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

×