Middle
Quais são os tipos de classes aninhadas?
sobes.tech IA
Resposta da IA
As classes aninhadas (Nested Classes) em Java dividem-se em dois tipos principais:
-
Classes aninhadas estáticas (Static Nested Classes)
- Marcadas com o modificador
static. - Comportam-se como membros estáticos normais da classe contêiner.
- Podem aceder aos membros estáticos da classe externa (mesmo que privados).
- Não têm acesso direto aos membros não estáticos da classe externa.
- São criadas sem uma instância da classe externa:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();.
- Marcadas com o modificador
-
Classes internas (Inner Classes)
As classes internas não são marcadas com
statice estão relacionadas com uma instância da classe externa. Elas subdividem-se em:-
Classes membro (Member Inner Classes)
- Declaradas ao nível de um membro da classe contêiner, mas fora de seus métodos.
- Têm acesso a todos os membros da classe externa, incluindo privados.
- Requerem uma instância da classe externa para criar sua própria instância:
OuterClass outerObject = new OuterClass(); OuterClass.MemberInnerClass innerObject = outerObject.new MemberInnerClass();.
-
Classes locais (Local Classes)
- Criadas dentro de métodos, construtores ou blocos de inicialização.
- Seu âmbito está limitado ao bloco onde são declaradas.
- Não podem ser declaradas com modificadores de acesso (
public,private,protected). - Podem aceder a variáveis locais finais ou efetivamente finais do bloco externo.
- Não podem ser usadas fora do bloco onde são definidas.
-
Classes anónimas (Anonymous Classes)
- São, na essência, classes locais sem nome.
- São declaradas e instanciadas ao mesmo tempo.
- São usadas para implementar uma classe abstrata ou uma interface "de improviso".
- Tal como as classes locais, têm acesso a variáveis locais finais ou efetivamente finais do bloco externo.
-
Exemplo de estrutura:
class OuterClass {
private int outerField;
private static int staticOuterField;
// Classe aninhada estática
static class StaticNestedClass {
void accessOuter() {
// Pode aceder aos membros estáticos da classe externa
int value = staticOuterField;
// Não pode aceder aos membros não estáticos
// int value2 = outerField; // Erro de compilação
}
}
// Classe membro (classe interna)
class MemberInnerClass {
void accessOuter() {
// Pode aceder a todos os membros da classe externa
int value1 = outerField;
int value2 = staticOuterField;
}
}
void methodWithLocalAndAnonymous() {
final int localVar = 10; // final ou efetivamente final
// Classe local
class LocalClass {
void accessOuter() {
// Pode aceder aos membros da classe externa e variáveis locais finais/efetivamente finais
int value1 = outerField;
int value2 = staticOuterField;
int localValue = localVar;
}
}
LocalClass localObj = new LocalClass();
localObj.accessOuter();
// Classe anónima (que implementa Runnable)
Runnable anonymousRunnable = new Runnable() {
@Override
public void run() {
// Pode aceder aos membros da classe externa e variáveis locais finais/efetivamente finais
int value1 = outerField;
int value2 = staticOuterField;
int localValue = localVar;
System.out.println("Executando com variável local: " + localValue);
}
};
anonymousRunnable.run();
}
}