SlideShare ist ein Scribd-Unternehmen logo
1 von 5
Downloaden Sie, um offline zu lesen
Tradução resumida do artigo
                      “Getting in Touch with your Inner Class”
                     http://www.javaranch.com/campfire/StoryInner.jsp

                 “Entrando em contato com a sua classe interna”
                                        Henrique Bueno
                                       www.hbueno.com

Ser um objeto não é tão divertido como você pensa.

É solitário...

Aqui fora...
Na heap...
Sozinho.

Para não mencionar o horror, a devastação emocional quando você sente sua última
referência ir embora e você ser atingido – você acabou de se tornar comida do coletor de lixo.

Mas você sabe o que ajuda? Ter uma classe interna. Uma classe interna pode aliviar a solidão...
quando alguém cria uma instância da classe interna. Tudo que eu realmente quero é alguém
para se relacionar comigo.




Alguém para compartilhar meus mais privados pensamentos (e variáveis e métodos). Alguém
que sabe tudo sobre mim. Um relacionamento íntimo compartilhado entre dois objetos – um
externo e um interno.

Eu sou muito protetor com minha classe interna. Se alguém quer instanciar minha classe
interna, ele precisa ir através de mim – um objeto da classe externa.

Minha classe interna não pode existir sozinha. Eu, como uma instância da classe externa, posso
viver sozinho (entretanto triste). Você não precisa fazer uma instância de uma classe interna
para ter uma instância da classe externa. Mas você nunca irá conseguir instanciar minha classe
interna sem um objeto da classe externa para ligá-los.

Minha classe interna precisa de mim.

Nós temos essa ligação especial.

Minha classe interna torna a vida suportável na área de memória vigiada pelo coletor de lixo.




                                       www.hbueno.com
Aqui vai um código sobre o que estou falando:




OK, mas nada ocorre até que sejam criadas instâncias das duas classes...




                                      www.hbueno.com
Você ainda pode instanciar ambas as classes ao mesmo tempo:

                   Inner i = new Outer().new Inner();

Eu sei que parece estranho, mas isso mostra que você precisa de um objeto externo, assim
você pode perguntá-lo para fazer um objeto interno. Neste exemplo, você nem mantem uma
referência para o objeto externo... Apenas o objeto interno “i”. O objeto interno “i” ainda
conhece seu objeto exerno... Seu “outer this”. (Por falar no assunto, não existe palavra
reservada “outer this” – isso é apenas um conceito para a forma que objetos internos se
comportam). O objeto interno acessa as variáveis do objeto externo como se fossem suas.

Eu odeio static!

Você provavelmente já ouviu falar sobre static inner classes. Bem, elas não merecem ser
chamadas de classes internas!

Uma static inner class (uma classe interna marcada como static) se parece com:




Eu não gosto delas porque elas não me dão aquela ligação especial objeto-objeto. Na
realidade, classes static inner nem deveriam ser chamadas de classes internas. Tecnicamente,
elas são “top-level nested classes”.

Uma static nested class pode ser instanciada, mas o objeto criado não compartilha nenhuma
relação especial com o objeto externo.

A classe static nested é ligada apenas a classe externa, não com a instância da classe externa.

                   Outer.Inner i = new Outer.Inner();

Por isso que você pode criar uma instância de uma classe static nested sem ter uma instância
da classe externa, da mesma forma que você pode chamar métodos estáticos de uma classe
sem instanciá-la. Uma classe top-level nested é um pouco mais do que outra forma de
controlar namespace.

Mas vamos voltar para classes internas; elas têm muito mais significado. Você sabia que eu
posso me ligar com uma instância de minha classe interna mesmo quando eu não sei o nome
da minha classe interna? Por conveniência, você pode obter uma instância de uma classe
interna e criar essa classe interna na mesma hora.

Funciona assim...

Imagine que você (o programador) está construindo sua bela interface gráfica e decide que
precisa saber quando o usuário clicou no seu botão GO. “Eu reconheço que preciso de um
objeto ActionListener”, você diz para si próprio. Então você digita:

                                       www.hbueno.com
goButton.addActionListener([object goes here]);

E então você percebe... “Eu não posso criar um objeto... Eu não tenho uma classe
ActionListener!”

Você nunca fez uma classe que implementa a interface ActionListener por conta própria.

Isso não é um problema.

Você pode criar uma nova classe que implementa a interface ActionListener, e fazer uma
instância dessa nova classe – tudo dentro do parâmetro do método addActionListener() do
objeto botão. O quanto isso é interessante?

Fica mais ou menos assim:




E funciona assim:

                            new ActionListener()

Diz ao compilador: “Crie uma instância de uma nova e não nomeada classe que implementa a
interface ActionListener...”

E após as chaves abertas em verde você define uma nova classe sem nome...




O método actionPerformed é o mesmo que você criaria se definisse uma nova classe para
implementar a interface ActionListener. Mas essa nova classe não tem nome. É por isso que
ela é chamada de classe interna anônima.

E perceba que você não disse “new MyActionClass()”. Você disso, “new ActionListener()”. Mas
você não está criando uma instância de ActionListener, você está criando uma instância de
uma nova classe anônima que implementa a interface ActionListener.



                                     www.hbueno.com
Mas espere! Você disse, “E se eu não quiser implementar uma interface... e se eu quiser criar
uma classe interna anônima que herde de outra classe:”

De novo, sem problemas!

Independente do que você disser depois do “new” como um “new AlgumaCoisa()”, se
AlgumaCoisa for uma interface, então a classe anônima implementa a interface (e precisará
definir todos os métodos da interface). Mas se AlgumaCoisa for uma classe, então sua classe
anônima automaticamente se tornará subclasse desta classe. Isso é perfeito para classes
“event adapter” como WindowAdapter.

Finalmente, não se esqueça de fechar o parâmetro (parênteses em vermelho) e colocar o
ponto e vírgula.

Perigo! Perigo!

Agora eu me sinto com a obrigação de avisar sobre uma coisa de classes internas anônimas, ou
qualquer outra classe interna que você defina dentro de um método. A classe interna não
poderá usar as variáveis locais do método onde ela está definida! Depois de tudo, no final do
método, as variáveis locais serão perdidas (registro do método é desempilhado). O objeto
interno que você criou da classe interna provavelmente ainda estará vivo na heap depois que
as variáveis locais do método saíram do escopo. Você pode, entretanto, usar variáveis locais
declaradas como final, mas nunca parâmetros do método e variáveis locais.

Outro aviso sobre classes internas é que elas não podem declarar membros estáticos, a menos
que elas sejam classes static nested.

Ah, não se sinta obrigado a parar com apenas uma classe interna... Não há nada na
especificação Java que diga que objetos externos devem ser monogâmicos.




O fim.




                                     www.hbueno.com

Weitere ähnliche Inhalte

Andere mochten auch

Win server 2008_r2_visao_geral
Win server 2008_r2_visao_geralWin server 2008_r2_visao_geral
Win server 2008_r2_visao_geralReginaldo Santos
 
Como crear un blogger
Como crear un bloggerComo crear un blogger
Como crear un bloggeredisonjulian
 
Apresentação1
Apresentação1Apresentação1
Apresentação1moozer762
 
Hetky ry Esitelmä robotisaation vaikutuksista
Hetky ry Esitelmä robotisaation vaikutuksistaHetky ry Esitelmä robotisaation vaikutuksista
Hetky ry Esitelmä robotisaation vaikutuksistaRoboticsFinland
 
Copleston frederick historia de la filosofia v - filosofos britanicos - hob...
Copleston frederick   historia de la filosofia v - filosofos britanicos - hob...Copleston frederick   historia de la filosofia v - filosofos britanicos - hob...
Copleston frederick historia de la filosofia v - filosofos britanicos - hob...sebimaximo
 

Andere mochten auch (6)

Win server 2008_r2_visao_geral
Win server 2008_r2_visao_geralWin server 2008_r2_visao_geral
Win server 2008_r2_visao_geral
 
Como crear un blogger
Como crear un bloggerComo crear un blogger
Como crear un blogger
 
Apresentação1
Apresentação1Apresentação1
Apresentação1
 
Hetky ry Esitelmä robotisaation vaikutuksista
Hetky ry Esitelmä robotisaation vaikutuksistaHetky ry Esitelmä robotisaation vaikutuksista
Hetky ry Esitelmä robotisaation vaikutuksista
 
A escola do deserto
A escola do desertoA escola do deserto
A escola do deserto
 
Copleston frederick historia de la filosofia v - filosofos britanicos - hob...
Copleston frederick   historia de la filosofia v - filosofos britanicos - hob...Copleston frederick   historia de la filosofia v - filosofos britanicos - hob...
Copleston frederick historia de la filosofia v - filosofos britanicos - hob...
 

Classes internas

  • 1. Tradução resumida do artigo “Getting in Touch with your Inner Class” http://www.javaranch.com/campfire/StoryInner.jsp “Entrando em contato com a sua classe interna” Henrique Bueno www.hbueno.com Ser um objeto não é tão divertido como você pensa. É solitário... Aqui fora... Na heap... Sozinho. Para não mencionar o horror, a devastação emocional quando você sente sua última referência ir embora e você ser atingido – você acabou de se tornar comida do coletor de lixo. Mas você sabe o que ajuda? Ter uma classe interna. Uma classe interna pode aliviar a solidão... quando alguém cria uma instância da classe interna. Tudo que eu realmente quero é alguém para se relacionar comigo. Alguém para compartilhar meus mais privados pensamentos (e variáveis e métodos). Alguém que sabe tudo sobre mim. Um relacionamento íntimo compartilhado entre dois objetos – um externo e um interno. Eu sou muito protetor com minha classe interna. Se alguém quer instanciar minha classe interna, ele precisa ir através de mim – um objeto da classe externa. Minha classe interna não pode existir sozinha. Eu, como uma instância da classe externa, posso viver sozinho (entretanto triste). Você não precisa fazer uma instância de uma classe interna para ter uma instância da classe externa. Mas você nunca irá conseguir instanciar minha classe interna sem um objeto da classe externa para ligá-los. Minha classe interna precisa de mim. Nós temos essa ligação especial. Minha classe interna torna a vida suportável na área de memória vigiada pelo coletor de lixo. www.hbueno.com
  • 2. Aqui vai um código sobre o que estou falando: OK, mas nada ocorre até que sejam criadas instâncias das duas classes... www.hbueno.com
  • 3. Você ainda pode instanciar ambas as classes ao mesmo tempo: Inner i = new Outer().new Inner(); Eu sei que parece estranho, mas isso mostra que você precisa de um objeto externo, assim você pode perguntá-lo para fazer um objeto interno. Neste exemplo, você nem mantem uma referência para o objeto externo... Apenas o objeto interno “i”. O objeto interno “i” ainda conhece seu objeto exerno... Seu “outer this”. (Por falar no assunto, não existe palavra reservada “outer this” – isso é apenas um conceito para a forma que objetos internos se comportam). O objeto interno acessa as variáveis do objeto externo como se fossem suas. Eu odeio static! Você provavelmente já ouviu falar sobre static inner classes. Bem, elas não merecem ser chamadas de classes internas! Uma static inner class (uma classe interna marcada como static) se parece com: Eu não gosto delas porque elas não me dão aquela ligação especial objeto-objeto. Na realidade, classes static inner nem deveriam ser chamadas de classes internas. Tecnicamente, elas são “top-level nested classes”. Uma static nested class pode ser instanciada, mas o objeto criado não compartilha nenhuma relação especial com o objeto externo. A classe static nested é ligada apenas a classe externa, não com a instância da classe externa. Outer.Inner i = new Outer.Inner(); Por isso que você pode criar uma instância de uma classe static nested sem ter uma instância da classe externa, da mesma forma que você pode chamar métodos estáticos de uma classe sem instanciá-la. Uma classe top-level nested é um pouco mais do que outra forma de controlar namespace. Mas vamos voltar para classes internas; elas têm muito mais significado. Você sabia que eu posso me ligar com uma instância de minha classe interna mesmo quando eu não sei o nome da minha classe interna? Por conveniência, você pode obter uma instância de uma classe interna e criar essa classe interna na mesma hora. Funciona assim... Imagine que você (o programador) está construindo sua bela interface gráfica e decide que precisa saber quando o usuário clicou no seu botão GO. “Eu reconheço que preciso de um objeto ActionListener”, você diz para si próprio. Então você digita: www.hbueno.com
  • 4. goButton.addActionListener([object goes here]); E então você percebe... “Eu não posso criar um objeto... Eu não tenho uma classe ActionListener!” Você nunca fez uma classe que implementa a interface ActionListener por conta própria. Isso não é um problema. Você pode criar uma nova classe que implementa a interface ActionListener, e fazer uma instância dessa nova classe – tudo dentro do parâmetro do método addActionListener() do objeto botão. O quanto isso é interessante? Fica mais ou menos assim: E funciona assim: new ActionListener() Diz ao compilador: “Crie uma instância de uma nova e não nomeada classe que implementa a interface ActionListener...” E após as chaves abertas em verde você define uma nova classe sem nome... O método actionPerformed é o mesmo que você criaria se definisse uma nova classe para implementar a interface ActionListener. Mas essa nova classe não tem nome. É por isso que ela é chamada de classe interna anônima. E perceba que você não disse “new MyActionClass()”. Você disso, “new ActionListener()”. Mas você não está criando uma instância de ActionListener, você está criando uma instância de uma nova classe anônima que implementa a interface ActionListener. www.hbueno.com
  • 5. Mas espere! Você disse, “E se eu não quiser implementar uma interface... e se eu quiser criar uma classe interna anônima que herde de outra classe:” De novo, sem problemas! Independente do que você disser depois do “new” como um “new AlgumaCoisa()”, se AlgumaCoisa for uma interface, então a classe anônima implementa a interface (e precisará definir todos os métodos da interface). Mas se AlgumaCoisa for uma classe, então sua classe anônima automaticamente se tornará subclasse desta classe. Isso é perfeito para classes “event adapter” como WindowAdapter. Finalmente, não se esqueça de fechar o parâmetro (parênteses em vermelho) e colocar o ponto e vírgula. Perigo! Perigo! Agora eu me sinto com a obrigação de avisar sobre uma coisa de classes internas anônimas, ou qualquer outra classe interna que você defina dentro de um método. A classe interna não poderá usar as variáveis locais do método onde ela está definida! Depois de tudo, no final do método, as variáveis locais serão perdidas (registro do método é desempilhado). O objeto interno que você criou da classe interna provavelmente ainda estará vivo na heap depois que as variáveis locais do método saíram do escopo. Você pode, entretanto, usar variáveis locais declaradas como final, mas nunca parâmetros do método e variáveis locais. Outro aviso sobre classes internas é que elas não podem declarar membros estáticos, a menos que elas sejam classes static nested. Ah, não se sinta obrigado a parar com apenas uma classe interna... Não há nada na especificação Java que diga que objetos externos devem ser monogâmicos. O fim. www.hbueno.com