Sim, em Java, uma classe pode ser definida dentro de outra classe. Essas classes são conhecidas como classes internas ou classes aninhadas.
Existem quatro tipos principais de classes internas em Java:
☕ Classe Interna Regular (Inner Class)
É uma classe definida dentro de outra classe. Ela pode ter acesso aos membros da classe externa, incluindo campos privados. As classes internas são frequentemente usadas quando a classe interna tem uma relação forte com a classe externa.
Neste exemplo, temos uma classe Carro
com uma classe interna Motor
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Carro { private String modelo; // Construtor da classe Carro public Carro(String modelo) { this.modelo = modelo; } // Classe interna Motor public class Motor { // Método para ligar o motor public void ligar() { System.out.println("O motor do carro " + modelo + " foi ligado."); } } public static void main(String[] args) { // Criação de uma instância da classe Carro com o modelo "Sedan" Carro carro = new Carro("Sedan"); // Criação de uma instância da classe interna Motor associada ao carro Carro.Motor motor = carro.new Motor(); // Chama o método ligar() da classe interna Motor para ligar o motor motor.ligar(); } } |
☕ Classe Anônima (Anonymous Class)
Classe anônima (Anonymous Class) é um conceito em Java que permite criar uma classe sem nome (ou seja, sem declarar explicitamente um nome de classe) e instanciá-la ao mesmo tempo, geralmente para fornecer uma implementação rápida e ad hoc de uma interface ou classe abstrata. Isso é útil quando você precisa criar uma classe que será usada apenas uma vez e não deseja criar uma classe separada para ela.
A designação “anônima” refere-se ao fato de que, ao escrever o código, você não precisa escolher um nome para essa classe, porque o compilador cuida disso internamente.
Neste exemplo, usamos uma classe anônima para criar uma implementação rápida de uma interface:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Definição de uma interface interface Mensagem { void exibirMensagem(); } public class ExemploClasseAnonima { public static void main(String[] args) { // Criação de uma classe anônima que implementa a interface Mensagem Mensagem mensagem = new Mensagem() { @Override public void exibirMensagem() { System.out.println("Isso é uma mensagem anônima."); } }; // Chamada do método da interface usando a instância da classe anônima mensagem.exibirMensagem(); } } |
☕ Classe Estática Aninhada (Static Nested Class)
É uma classe interna que é declarada como estática. Isso significa que ela não tem acesso direto aos membros não estáticos da classe externa. As classes estáticas aninhadas são frequentemente usadas para melhorar a organização do código.
Exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public class Exterior { // Classe estática aninhada (Static Nested Class) static class InternaEstatica { // Método da classe estática aninhada void mostrar() { System.out.println("Isso é uma classe estática aninhada."); } } public static void main(String[] args) { // Criação de uma instância da classe estática aninhada Exterior.InternaEstatica interna = new Exterior.InternaEstatica(); // Chama o método da classe estática aninhada interna.mostrar(); } } |
☕ Classe Interna Local (Local Inner Class)
É uma classe definida dentro de um método ou bloco de código. Ela só é visível dentro do escopo onde foi definida.
Neste exemplo, temos uma classe interna local definida dentro de um método:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class ClasseExterna { // Método externo da classe externa public void metodoExterno() { // Classe interna local definida dentro do método class ClasseLocal { // Método da classe interna local void mostrar() { System.out.println("Isso é uma classe interna local."); } } // Criação de uma instância da classe interna local ClasseLocal local = new ClasseLocal(); // Chamada do método da classe interna local local.mostrar(); } public static void main(String[] args) { // Criação de uma instância da classe externa ClasseExterna externa = new ClasseExterna(); // Chamada do método externo da classe externa, que também cria e utiliza a classe interna local externa.metodoExterno(); } } |
📅 Tabela Comparativa de Tipos de Classes Internas em Java
Tipo de Classe Interna | Visibilidade a membros da Classe Externa | Necessidade de Instância da Classe Externa | Aplicação Comum |
---|---|---|---|
Classe Interna Regular | Sim | Sim | Relações fortes entre a Classe Externa e a Classe Interna, como Listeners e Comportamentos específicos. |
Classe Anônima | Não | Não | Implementações ad hoc de interfaces e classes abstratas. |
Classe Estática Aninhada | Sim | Não | Melhorar a organização de código, quando a classe interna não precisa de acesso aos membros não estáticos da Classe Externa. |
Classe Interna Local | Sim | Sim | Encapsular funcionalidades específicas de um método ou bloco de código. |
*Atualizado em 30 de setembro de 2023