Classes Internas

  • 1,274 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
1,274
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
21
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Classes Internas Raphael Marques
  • 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. 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. Classes Internas class MyOuter { class MyInner {} } %javac MyOuter.java MyOuter.class MyOuter$MyInner.class %java MyOuter$MyInner
  • 5. Classes Internas class MyOuter { class MyInner {} } %javac MyOuter.java MyOuter.class MyOuter$MyInner.class %java MyOuter$MyInner → ERRO
  • 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. Classes Internas class MyOuter{ private int x = 7; class MyInner{ public void seeOuter(){ System.out.println(“x: ”+x); } } }
  • 8. Classes Internas • Para instanciar uma classe interna, é preciso uma instância da classe externa
  • 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. 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. 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. 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. Classes Internas public static void main(String[] args){ Outer outer = new Outer(); outer.new Inner(); outer.new Outer.Inner(); }
  • 14. Classes Internas public static void main(String[] args){ Outer outer = new Outer(); outer.new Inner(); → LEGAL outer.new Outer.Inner(); → ILEGAL }
  • 15. Classes Internas class MyOuter{ class MyInner{} void makeInner(){ MyInner a = new MyInner(); MyInner b = this.new MyInner(); } }
  • 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. 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. 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. Classes Internas • Modificadores aplicáveis a classes internas: – final – abstract – public – private – protected – strictfp – static • a classe interna vira classe aninhada • nested class
  • 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. 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. 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. 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. 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. 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. 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. Classes Internas Locais a Métodos • Só podem receber os modificadores: – final – abstract
  • 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. 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. 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. 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. 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. Classes Internas Anônimas • Cuidado! Runnable r = new Runnable(); → ILEGAL Runnable r = new Runnable(){ public void run(){ } }; → LEGAL
  • 34. Classes Internas Anônimas como Parâmetro System.out.println( new Popcorn(){ public String toString(){ return “new poporn”; } } ); →“new popcorn”
  • 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. 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. 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