Classes Internas e Anônimas
Prof. Ricardo Linden
Classes Internas e Anônimas
1
Classes Internas
 Classes Internas são classes dentro de classes.
 Declaramos
classes exatamente como fazíamos
antes, mas agora ela está dentro do corpo de outra
classe
 Consequentemente dentro do arquivo .java desta
outra classe).
 As suas regras de acesso são um pouquinho
diferentes.
 O uso mais comum das classes internas é para lidar
com eventos, como veremos mais a frente.
Classes Internas e Anônimas
2
Como declarar?
 Uma classe aninhada (tipo de classe internas) é
declarada dentro de uma classe existente
 Exemplo:
public class MyRegularClass
{
…….
class myInnerClass
{ ….
}
}
Classes Internas e Anônimas
3
Classes Internas
 Os objetos das classes internas são associados com objetos das
classes envoltórias
 Para criar um objeto de uma classe interna é necessário criar
primeiro um objeto da classe externa.
 Exemplo
BankAccount account = new BankAccount();
BankAccount.money amount = account.new Money(“41.99”);
System.out.println(amount.getAmount());
Classes Internas e Anônimas
4
Regras de Acesso
 Uma classe aninhada tem acesso total aos campos e
métodos da classe que a envolve, incluindo aqueles
de acesso privado.
 De acordo com a Sun, isto não quebra o conceito de
do acesso privado, já que a classe aninhada também
“pertence” à classe que a envolve.
Classes Internas e Anônimas
5
Modificadores de Acesso
 Classes internas pode ter modificadores:
– public
– protected
– private
– Ou ter acesso package-level (sem modifiadores)
Classes Internas e Anônimas
6
Static  Não-Static
 Uma classe aninhada pode ser declarada como static





ou não.
Se ela não for static, é chamada de classe interna.
Se for static, é chamada de classe estática aninhada.
Uma classe estática aninhada está associada à classe
que a envolve e não pode referenciar nenhuma das
variáveis de instância.
Entretanto, elas podem acessar todos os membros
(variáveis e métodos) estáticos da classe envoltória.
É como se fosse um método estático.
Classes Internas e Anônimas
7
Classes Aninhadas Estáticas
 Exemplo:
public abstract class Elipse2D {
…
public static class Float extends Elipse2D {
…
}
}
 A referência a elas é feita usando o nome da classe
envoltória. Exemplo:
new Elipse2D.Float (10., 20., 30., 40.)
Classes Internas e Anônimas
8
Classes Aninhadas Estáticas
 Uma classe aninha estática não tem nenhuma
relação com os objetos da classe envoltória
– Instâncias das variáveis não podem ser
referenciadas.
– Métodos não estáticos não podem ser invocados
Classes Internas e Anônimas
9
Convenções de Chamada
 Para chamar um método de uma classe estática
aninhada na classe envoltória:
– InnerClassName.staticMethodName
 Para referenciar uma variáve stática de uma classe
estática aninhada:
– InnerClassName.staticVariableName
Classes Internas e Anônimas
10
Classes Internas
 Uma
instância de uma classe interna existe
efetivamente dentro de uma instância da classe que
a envolve.
Instância da OuterClass
Instância da InnerClass
Classes Internas e Anônimas
11
Classes Internas
 Se você declarar new myInnerClass() em algum
ponto no código, um novo objeto será criado com
acesso a todas as variáveis de instância ao objeto
que o envolve.
 Ele será declarado com acesso a todas as variáveis
internas da classe que o envolve.
Classes Internas e Anônimas
12
Exemplo Simples
public class FixedStack {
Object array[]; int top = 0;
FixedStack(int limit) {array = new Object(limit);}
public void push(Object item) { array[top++] = item; }
public boolean isEmpty() { return top == 0; }
class Enumerator implements java.util.Enumeration {
int count = top;
public boolean hasNoreElements() { return count > 0; }
public Object nextElement() {
if (count == 0)
throw new NoSuchElementException(“FixedStack”);
return array[--count];
}
}
public java.util.Enumeration elements() {
return new Enumeration(); }
}
Classes Internas e Anônimas
13
Comentários sobre exemplo
 Neste caso, a interface java.util.Enumeration
é indispensável para o funcionamento da classe
interna.
 A instância que contém um Enumerator é da classe
FixedStack.
– Para se referir a ela, use FixedStack.this
 Em uma classe estática aninhada, é proibido se
referir à instância FixedStack.this
Classes Internas e Anônimas
14
Exemplo
public class TestInstanceInnerClass {
private JButton button1, button2;
class Listener implements ActionListener {
public void actionPerformed (
ActionEvent evt){
Object src = evt.getSource();
if (src == button1)
System.out.println ("One");
else if (src == button2)
System.out.println ("Two");
else if (src == button3)
System.out.println ("Three");
}
}
Classes Internas e Anônimas
15
Exemplo (continuação)
public TestInstanceInnerClass() {
JFrame frame;
button1 = new JButton ("One");
button2 = new JButton ("Two");
frame = new JFrame ("Test Instance Class");
Container cp = frame.getContentPane();
cp.add ("North", button1);
cp.add ("Center", button2);
Listener lstnr = new Listener();
button1.addActionListener (lstnr);
button2.addActionListener (lstnr);
frame.setSize(175, 150);
frame.setVisible (true);
}
public static void main (String[] args) {
new TestInstanceInnerClass();
}
}
Classes Internas e Anônimas
16
Classes Internas Locais
 São definidas dentro de um método ou outro bloco
(como um if ou um for)
 Só podem ser referenciadas dentro daquele bloco.
 Podem referenciar:
– variáveis de instância da classe que as envolve
– variáveis locais final do bloco que as envolve.
Classes Internas e Anônimas
17
Exemplo
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestLocalInnerClass {
public static void main (String[] args) {
JFrame frame;
final JButton button1, button2;
button1 = new JButton ("One");
button2 = new JButton ("Two");
frame = new JFrame ("Test Local Class");
Container cp = frame.getContentPane();
cp.add ("North", button1);
cp.add ("Center", button2);
frame.setSize(175, 150);
Classes Internas e Anônimas
18
Exemplo (continuação)
class Listener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == button1)
System.out.println (”Um");
else if (src == button2)
System.out.println ("Two");
}
}
Listener lstnr = new Listener();
button1.addActionListener (lstnr);
button2.addActionListener (lstnr);
frame.setVisible (true);
}
}
Classes Internas e Anônimas
19
Observações...
 É possível ter classes internas às classes internas.
 Exemplo: Classe A tem classe interna pública B que
tem uma classe interna pública B C:
A.aObject = new A( );
A.B bObject = aObject.new B( );
A.B.C cObject = bObject.new C( )
Classes Internas e Anônimas
20
Regras de herança
 Seja OuterClass que contém uma classe interna InnerClass.
Logo:
– Se DerivedClass é uma subclasse de OuterClass, então
DerivedClass também tem InnerClass como classe interna
– Não é possível sobrepor a definição de InnerClass em
DerivedClass.
– InnerClass pode extender uma classe.
– OuterClass pode externder uma classe diferente de
InnerClass
Classes Internas e Anônimas
21
Classes Anônimas
 Em algum momento podemos não nos importar com
o nome das variáveis.
 Se não quisermos dar nome às nossas classes,
estaremos criando classes anônimas.
 Classes anônimas são classes que são declaradas
“on-the-fly”, isto é, onde são necessárias, dentro de
um bloco de código.
Classes Internas e Anônimas
22
Classes Anônimas
 Nós sabemos que não vamos precisar de outra
instância dela após, logo não temos necessidade de
dar-lhe um nome que permita o acesso posterior.
 Estas classes não pode ter construtores
– não têm nome para colocar depois do new!
Classes Internas e Anônimas
23
Exemplo
MeuBotao.addActionListener (new ActionListener(){
public void actionPerformed (ActionEvent evt){
:
}
});
 Nós sabemos que o ActionListener deste botão é
muito específico e não será usado por mais ninguém.
 Logo, podemos declará-lo imediatamente.
 Não se preocupem com os conceitos de programação
gráfica. Nós vamos discuti-los com detalhes depois.
 Note que nós não definimos um construtor, só o
método que nos interessava naquele momento.
Classes Internas e Anônimas
24
Quando usar classes anônimas
 Crie classes anônimas apenas quando suas classes forem muito
pequenas (um ou dois métodos).
 Mais que isto e seu programa será ilegível.
 Eventos de botões, que são muito específicos, são bons
candidatos ao uso delas.
 Mantenha-as curtas: já que você tem acesso a todos os
métodos da classe envoltória, mantenha o grosso do código
dentro dela.
Classes Internas e Anônimas
25
Resultados da Compilação
 Quando você compilar uma classe interna, você verá
no seu diretório um arquivo com o nome
OuterClass$InnerClass.class
 Quando você compilar uma classe anônima, você
verá no seu diretório um arquivo chamado
OuterClass$n.class, onde n é um número inteiro
crescente.
Classes Internas e Anônimas
26
Questões de Implementação
 Implementada
através de tradução para os mecanismos
habituais do Java
– A instância da classe envoltória é referenciada por this$0
– A variável local x da classe envoltória é referenciada por
val$x
– O compilador se encarrega de copiar os códigos de this$ e
todos val$ no momento da criação do objeto.
 Referenciando:
– instância do objeto que contém classe: classe_env.this
 Não pode conter variáveis estáticas
 Quebram o conceito dos modificadores private e protected
Classes Internas e Anônimas
27
Download

Classes Internas e Anônimas