1. Classes internas

Você aprendeu recentemente que existem variáveis ​​estáticas e métodos estáticos. Acontece que também existem classes estáticas. Mas abordaremos esse tema à distância.

Em Java, você tem total permissão para declarar classes dentro de classes. E até classes dentro de classes que estão dentro de classes dentro de classes. Tudo parece muito simples:

class OuterClass
{
   variables of the class
   methods of the class

   class NestedClass
   {
      variables of the class
      methods of the class
   }
}

Nós apenas declaramos uma classe dentro de outra. Tão simples como isso.

Exemplo:

public class Solution
{
   static ArrayList<Point> points = new ArrayList<Point>();

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}

As classes aninhadas podem ser estáticas ou não estáticas. As classes aninhadas estáticas são simplesmente chamadas de classes aninhadas estáticas . Classes aninhadas não estáticas são chamadas de classes internas ( classes internas ).



2. Classes estáticas

Classes aninhadas estáticas podem ser usadas fora de sua classe externa. Se essa classe tiver o modificador de acesso público, ela poderá ser usada em qualquer lugar do programa. Essas classes são quase indistinguíveis de qualquer classe comum. Mas há algumas diferenças.

Nome da classe

Se você quiser se referir a uma classe aninhada estática de algum lugar diferente de sua classe externa, precisará especificar o nome da classe, que consiste no nome da classe externa e no nome da classe aninhada. Aqui está a aparência geral deste nome:

OuterClass.InnerClass

Exemplos:

classe externa classe aninhada Nome completo da classe aninhada
com.codegym.Solution
Point
com.codegym.Solution.Point
java.util.Map
Entry
java.util.Map.Entry
java.util.Files
DirectoryStream
java.util.Files.DirectoryStream
java.nio.WindowsPath
Closeable
java.nio.WindowsPath.Closeable

Se uma classe aninhada tiver sua própria classe aninhada, seus nomes serão simplesmente unidos usando um ponto.

Um exemplo típico de uma classe aninhada no JDK é a Entryclasse dentro da Mapclasse. Se você deseja obter o conjunto de pares chave-valor armazenados em um HashMapobjeto, use o entrySet()método, que retorna um .Set<Map.Entry>

Observe que é um exemplo de uma classe externa e uma classe aninhada.Map.Entry

Criando um objeto

É muito fácil criar um objeto de uma classe aninhada estática. Isto é o que parece:

OuterClass.NestedClass name = new OuterClass.NestedClass();

É tudo igual às classes comuns, mas o nome consiste em duas partes.

Chamando métodos estáticos

Se uma classe estática tiver métodos estáticos, você poderá acessá-los da mesma forma que os métodos estáticos de classes comuns (mas o nome da classe consistirá em duas partes).

OuterClass.NestedClass.staticMethod();

Acessando variáveis ​​estáticas

Acessar as variáveis ​​estáticas públicas de uma classe aninhada também é fácil:

OuterParent.NestedClass.nameOfStaticVariable


3. Características das classes estáticas

As classes aninhadas estáticas têm menos motivos para serem chamadas de estáticas. Eles se comportam como classes regulares . Não há restrições para acessá-los de métodos não estáticos.

Se você estiver trabalhando com uma classe aninhada estática dentro de sua classe externa, não notará nenhuma diferença em relação à classe mais comum (não aninhada e nem estática).

Exemplo:

Classe Point aninhada estática Classe de ponto comum.
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }

   static class Point
   {
      int x;
      int y;
   }
}
public class Solution
{
   static ArrayList<Point> points;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;
      points = new ArrayList<Point>();
      points.add(point);
   }
}

class Point
{
   int x;
   int y;
}

Se você pegar alguma classe aninhada estática e movê-la para fora de sua classe externa, a única coisa que mudará é que a nova classe não poderá mais acessar as private staticvariáveis ​​e métodos de sua antiga classe externa.

Exemplo:

Classe Point aninhada estática Classe de ponto comum.
public class Solution
{
   private static ArrayList<Point> points;

   static class Point
   {
      int x;
      int y;

      public static void main(String[] args)
      {
         Point point = new Point();
         point.x = 100;
         point.y = 200;

         // This will work
         points = new ArrayList<Point>();
         points.add(point);
      }
   }
}
public class Solution
{
   private static ArrayList<Point> points;
}

class Point
{
   int x;
   int y;

   public static void main(String[] args)
   {
      Point point = new Point();
      point.x = 100;
      point.y = 200;

      // This will generate an error
      points = new ArrayList<Point>();
      points.add(point);
   }
}

O mainmétodo na Pointclasse comum não pode acessar a private static pointsvariável da Solutionclasse!

Essa é a principal diferença entre uma classe aninhada estática e uma classe comum. Os métodos de uma classe aninhada estática podem acessar todas as variáveis ​​e métodos estáticos de sua classe externa, mesmo que sejam declarados private.

E se você pensar sobre isso, por que isso deveria ser surpreendente? O privatemodificador diz explicitamente que as variáveis ​​e métodos marcados por esse modificador só podem ser acessados ​​de dentro de sua classe. Uma classe aninhada estática está dentro de sua classe externa? Sim, então não há problema! Acesse-os o quanto quiser.