1. Lớp học bên trong

Gần đây bạn đã biết rằng có các biến tĩnh và phương thức tĩnh. Hóa ra cũng có các lớp tĩnh. Nhưng chúng ta sẽ tiếp cận chủ đề này từ xa.

Trong Java, bạn hoàn toàn được phép khai báo các lớp bên trong các lớp. Và thậm chí các lớp trong các lớp nằm trong các lớp trong các lớp. Tất cả trông rất đơn giản:

class OuterClass
{
   variables of the class
   methods of the class

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

Chúng tôi chỉ khai báo một lớp bên trong một lớp khác. Đơn giản vậy thôi.

Ví dụ:

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;
   }
}

Các lớp lồng nhau có thể tĩnh hoặc không tĩnh. Các lớp lồng tĩnh được gọi đơn giản là các lớp lồng tĩnh . Các lớp lồng nhau không tĩnh được gọi là các lớp bên trong ( inner class ).



2. Các lớp tĩnh

Các lớp lồng tĩnh có thể được sử dụng bên ngoài lớp bên ngoài của chúng. Nếu một lớp như vậy có công cụ sửa đổi truy cập công khai, thì nó có thể được sử dụng ở bất kỳ đâu trong chương trình. Những lớp học như vậy gần như không thể phân biệt được với bất kỳ lớp học thông thường nào. Nhưng có một vài sự khác biệt.

Tên lớp

Nếu bạn muốn tham chiếu đến một lớp lồng tĩnh từ một nơi nào đó khác với lớp bên ngoài của nó, bạn cần chỉ định tên lớp, bao gồm tên của lớp bên ngoài và tên của lớp lồng nhau. Đây là sự xuất hiện chung của tên này:

OuterClass.InnerClass

Ví dụ:

lớp ngoài lớp lồng nhau Tên đầy đủ của lớp lồng nhau
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

Nếu một lớp lồng nhau có lớp lồng riêng của nó, thì tên của chúng chỉ được nối với nhau bằng dấu chấm.

Một ví dụ điển hình của lớp lồng nhau trong JDK là Entrylớp bên trong Maplớp. Nếu bạn muốn lấy tập hợp các cặp khóa-giá trị được lưu trữ trong một HashMapđối tượng, thì hãy sử dụng entrySet()phương thức trả về một .Set<Map.Entry>

Lưu ý rằng đó là một ví dụ về lớp bên ngoài và lớp lồng nhau.Map.Entry

Tạo một đối tượng

Rất dễ dàng để tạo một đối tượng của một lớp lồng nhau tĩnh. Cái này nó thì trông như thế nào:

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

Tất cả đều giống như với các lớp thông thường, nhưng tên bao gồm hai phần.

Gọi các phương thức tĩnh

Nếu một lớp tĩnh có các phương thức tĩnh, bạn có thể truy cập chúng giống như các phương thức tĩnh của các lớp thông thường (nhưng tên lớp sẽ bao gồm hai phần).

OuterClass.NestedClass.staticMethod();

Truy cập các biến tĩnh

Việc truy cập các biến tĩnh công khai của một lớp lồng nhau cũng dễ dàng:

OuterParent.NestedClass.nameOfStaticVariable


3. Đặc điểm của lớp tĩnh

Các lớp lồng nhau tĩnh có ít lý do nhất để được gọi là tĩnh. Họ cư xử giống như các lớp học thông thường . Không có giới hạn nào trong việc truy cập chúng từ các phương thức không tĩnh.

Nếu bạn đang làm việc với một lớp lồng tĩnh bên trong lớp bên ngoài của nó, bạn sẽ không nhận thấy bất kỳ sự khác biệt nào so với lớp thông thường nhất (không lồng nhau và không tĩnh).

Ví dụ:

Lớp điểm lồng nhau tĩnh Lớp Điểm thường.
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;
}

Nếu bạn lấy một lớp lồng tĩnh nào đó và di chuyển nó ra khỏi lớp bên ngoài của nó, thì điều duy nhất sẽ thay đổi là lớp mới sẽ không thể truy cập các private staticbiến và phương thức của lớp bên ngoài cũ của nó nữa.

Ví dụ:

Lớp điểm lồng nhau tĩnh Lớp Điểm thường.
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);
   }
}

Phương mainthức trong Pointlớp thông thường không thể truy cập vào private static pointsbiến của Solutionlớp!

Đây là điểm khác biệt chính giữa lớp lồng tĩnh và lớp thông thường. Các phương thức của một lớp lồng tĩnh có thể truy cập tất cả các biến và phương thức tĩnh của lớp bên ngoài của chúng, ngay cả khi chúng được khai báo private.

Và nếu bạn nghĩ về nó, tại sao điều đó lại đáng ngạc nhiên? Công privatecụ sửa đổi nói rõ ràng rằng các biến và phương thức được đánh dấu bởi công cụ sửa đổi này chỉ có thể được truy cập từ bên trong lớp của chúng. Là một lớp lồng tĩnh bên trong lớp bên ngoài của nó? Vâng, vì vậy không có vấn đề! Truy cập chúng nhiều như bạn muốn.