No livro da Keith Sierra, no capitulo 8 sobre Classes Internas ela diz o seguinte.
Porém, em um exemplo do livro, é apresentado o seguinte código.
class BigOuter{
static class Nest {void go() {System.out.println("hi1") ;}}
}
class Broom{
static class B2 {void goB2() {}}
public static void main(String[] args) {
BigOuter.Nest n = new BigOuter.Nest();
n.go;
B2 b2 = new B2();
b2.goB2();
}
}
A parte do código onde é feito new BigOuter.Nest() significa claramente uma instânciação da classe externa não?
Não. Ele está instanciado a classe Nest. Como está dentro de BigOuter, você precisa qualificar completamente o nome da classe Nest, que fica BigOuter.Nest, como vc faria na sintaxe de pacotes.
Mas uma dúvida ai, então quer dizer que posso instânciar chamar essa classe interna estática em qualquer lugar, desde que eu passe o caminho dela completo?
Classes internas podem ser (e são) um verdadeiro embaraço!
A linha 7 de seu código [B]NÃO[/B] cria uma classe externa da classe interna
Vejamos:
...
BigOuter.Nest n = new BigOuter.Nest();
n.go;
...
Lembre-se de que atributos estáticos são acessados via NomeClasse.Atributo
e uma classe interna é um atributo da classe da classe. Não é a toa que podemos aplicar sobre
ela os modificadores de acesso public, private, protected.
Logo a linha acima está criando um objeto da classe interna de BigOuter e não um objeto BigOuter!
Espero que tenha ajudado
Na verdade, o java ainda tem o comando import static.
Que é um import para esses casos:
[code]import static seupacote.BigOuter.Nest;
Nest n = new Nest(); //Funciona![/code]
Você pode usar o import static até mesmo para métodos:
[code]
import static java.util.Math;
…
int x = sin(PI);[/code]
Embora a Sun argumente que isso possa deixar o código mais confuso. E é efetivamente a oficialização de como se trabalhar com programação estruturada em Java (a classe se transforma num namespace simples).
Sim, deixando de lado o tema “certificação” e partindo para o tema “boas práticas”, recomendo o uso de classes internas apenas em contextos onde ela só fizer sentido dentro da classe externa, e mais em local nenhum.
É, por exemplo, o caso da classe No de um LinkedList:
public class LinkedList {
private static class Node {
}
}
Ou de listeners de botões (no caso, sem que sejam classes internas estáticas).
Não vejo praticamente nenhuma razão para uma classe interna ser pública, salvo à exceção dessa classe ser um enum. Se você esbarrar numa situação dessas, pense duas ou três vezes se não seria melhor que essa fosse uma classe normal, não interna.
Vou aproveitar e tirar mais uma duvidazinha sobre classe interna, porém, agora de método.
No livro existe uma questão (número 6 do Capitulo 8) que diz o seguinte:
A resposta B é indicada como correta, vejam só.
Esse DEVE ai me pegou, pq nos exemplos do livro (que são poucos) não tem nenhum com abstract. O único lugar que menciona abstract é onde diz que os únicos modificadores permitidos nesse tipo de classe são abstract e final (mas não os dois juntos).
A Ela deve ser marcada como final;
B Ela deve ser marcada como abstract;
C Ela deve ser marcada como public;
D Ela deve ser marcada como static;
E Ela pode acessar membros privados da classe encapsuladora;
Sendo E e B corretas.
Porém, acho que peguei uma nuance aqui na explicação da resposta.
Ela diz assim: “B está correta porque uma classe interna local de método PODE ser abstrata…”
Talvez a resposta B deve vir com um PODE ali em vez do DEVE.