Java - Các lớp bên trong

Trong chương này, chúng ta sẽ thảo luận về các lớp bên trong của Java.

Lớp học lồng nhau

Trong Java, giống như các phương thức, các biến của một lớp cũng có thể có một lớp khác làm thành viên của nó. Viết một lớp trong một lớp khác được phép trong Java. Lớp được viết bên trong được gọi lànested class, và lớp chứa lớp bên trong được gọi là outer class.

Syntax

Sau đây là cú pháp để viết một lớp lồng nhau. Đây, lớpOuter_Demo là lớp ngoài và lớp Inner_Demo là lớp lồng nhau.

class Outer_Demo {
   class Inner_Demo {
   }
}

Các lớp lồng nhau được chia thành hai loại:

  • Non-static nested classes - Đây là các thành viên không tĩnh của một lớp.

  • Static nested classes - Đây là các thành viên tĩnh của một lớp.

Lớp bên trong (Lớp lồng nhau không tĩnh)

Các lớp bên trong là một cơ chế bảo mật trong Java. Chúng tôi biết một lớp không thể được liên kết với công cụ sửa đổi quyền truy cậpprivate, nhưng nếu chúng ta có lớp là thành viên của lớp khác, thì lớp bên trong có thể được đặt ở chế độ riêng tư. Và điều này cũng được sử dụng để truy cập các thành viên riêng của một lớp.

Các lớp bên trong có ba loại tùy thuộc vào cách thức và vị trí bạn định nghĩa chúng. Họ là -

  • Lớp bên trong
  • Lớp bên trong phương thức cục bộ
  • Lớp bên trong ẩn danh

Lớp bên trong

Tạo một lớp bên trong khá đơn giản. Bạn chỉ cần viết một lớp trong một lớp. Không giống như một lớp, một lớp bên trong có thể là private và một khi bạn khai báo một lớp bên trong là private, nó không thể được truy cập từ một đối tượng bên ngoài lớp.

Sau đây là chương trình để tạo một lớp bên trong và truy cập nó. Trong ví dụ đã cho, chúng ta đặt lớp bên trong là riêng tư và truy cập lớp thông qua một phương thức.

Example

class Outer_Demo {
   int num;
   
   // inner class
   private class Inner_Demo {
      public void print() {
         System.out.println("This is an inner class");
      }
   }
   
   // Accessing he inner class from the method within
   void display_Inner() {
      Inner_Demo inner = new Inner_Demo();
      inner.print();
   }
}
   
public class My_class {

   public static void main(String args[]) {
      // Instantiating the outer class 
      Outer_Demo outer = new Outer_Demo();
      
      // Accessing the display_Inner() method.
      outer.display_Inner();
   }
}

Ở đây bạn có thể quan sát thấy Outer_Demo là lớp bên ngoài, Inner_Demo là lớp bên trong, display_Inner() là phương thức bên trong mà chúng ta đang khởi tạo lớp bên trong và phương thức này được gọi từ main phương pháp.

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is an inner class.

Tiếp cận các thành viên riêng

Như đã đề cập trước đó, các lớp bên trong cũng được sử dụng để truy cập các thành viên riêng của một lớp. Giả sử, một lớp đang có các thành viên riêng tư để truy cập chúng. Viết một lớp bên trong vào đó, trả về các thành viên private từ một phương thức bên trong lớp bên trong, chẳng hạn,getValue(), và cuối cùng từ một lớp khác (mà từ đó bạn muốn truy cập các thành viên riêng tư) gọi phương thức getValue () của lớp bên trong.

Để khởi tạo lớp bên trong, ban đầu bạn phải khởi tạo lớp bên ngoài. Sau đó, sử dụng đối tượng của lớp ngoài, sau đây là cách bạn có thể khởi tạo lớp bên trong.

Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();

Chương trình sau đây cho thấy cách truy cập các thành viên riêng của một lớp bằng cách sử dụng lớp bên trong.

Example

class Outer_Demo {
   // private variable of the outer class
   private int num = 175;  
   
   // inner class
   public class Inner_Demo {
      public int getNum() {
         System.out.println("This is the getnum method of the inner class");
         return num;
      }
   }
}

public class My_class2 {

   public static void main(String args[]) {
      // Instantiating the outer class
      Outer_Demo outer = new Outer_Demo();
      
      // Instantiating the inner class
      Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
      System.out.println(inner.getNum());
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is the getnum method of the inner class: 175

Lớp bên trong phương thức cục bộ

Trong Java, chúng ta có thể viết một lớp trong một phương thức và đây sẽ là một kiểu cục bộ. Giống như các biến cục bộ, phạm vi của lớp bên trong bị hạn chế trong phương thức.

Một lớp bên trong phương thức-cục bộ chỉ có thể được khởi tạo trong phương thức mà lớp bên trong được định nghĩa. Chương trình sau đây cho thấy cách sử dụng một lớp bên trong phương thức cục bộ.

Example

public class Outerclass {
   // instance method of the outer class 
   void my_Method() {
      int num = 23;

      // method-local inner class
      class MethodInner_Demo {
         public void print() {
            System.out.println("This is method inner class "+num);	   
         }   
      } // end of inner class
	   
      // Accessing the inner class
      MethodInner_Demo inner = new MethodInner_Demo();
      inner.print();
   }
   
   public static void main(String args[]) {
      Outerclass outer = new Outerclass();
      outer.my_Method();	   	   
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is method inner class 23

Lớp bên trong ẩn danh

Một lớp bên trong được khai báo không có tên lớp được gọi là anonymous inner class. Trong trường hợp các lớp bên trong ẩn danh, chúng tôi khai báo và khởi tạo chúng cùng một lúc. Nói chung, chúng được sử dụng bất cứ khi nào bạn cần ghi đè phương thức của một lớp hoặc một giao diện. Cú pháp của một lớp bên trong ẩn danh như sau:

Syntax

AnonymousInner an_inner = new AnonymousInner() {
   public void my_method() {
      ........
      ........
   }   
};

Chương trình sau đây chỉ ra cách ghi đè phương thức của một lớp bằng cách sử dụng lớp bên trong ẩn danh.

Example

abstract class AnonymousInner {
   public abstract void mymethod();
}

public class Outer_class {

   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner() {
         public void mymethod() {
            System.out.println("This is an example of anonymous inner class");
         }
      };
      inner.mymethod();	
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is an example of anonymous inner class

Theo cách tương tự, bạn có thể ghi đè các phương thức của lớp cụ thể cũng như giao diện bằng cách sử dụng lớp bên trong ẩn danh.

Lớp bên trong ẩn danh làm đối số

Nói chung, nếu một phương thức chấp nhận một đối tượng của một giao diện, một lớp trừu tượng hoặc một lớp cụ thể, thì chúng ta có thể triển khai giao diện, mở rộng lớp trừu tượng và truyền đối tượng cho phương thức. Nếu nó là một lớp, thì chúng ta có thể truyền trực tiếp nó vào phương thức.

Nhưng trong cả ba trường hợp, bạn có thể truyền một lớp bên trong ẩn danh cho phương thức. Đây là cú pháp truyền một lớp bên trong ẩn danh làm đối số của phương thức:

obj.my_Method(new My_Class() {
   public void Do() {
      .....
      .....
   }
});

Chương trình sau đây cho thấy cách chuyển một lớp bên trong ẩn danh làm đối số phương thức.

Example

// interface
interface Message {
   String greet();
}

public class My_class {
   // method which accepts the object of interface Message
   public void displayMessage(Message m) {
      System.out.println(m.greet() +
         ", This is an example of anonymous inner class as an argument");  
   }

   public static void main(String args[]) {
      // Instantiating the class
      My_class obj = new My_class();

      // Passing an anonymous inner class as an argument
      obj.displayMessage(new Message() {
         public String greet() {
            return "Hello";
         }
      });
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, nó sẽ cho bạn kết quả sau:

Output

Hello, This is an example of anonymous inner class as an argument

Lớp lồng nhau tĩnh

Một lớp bên trong tĩnh là một lớp lồng nhau là một thành viên tĩnh của lớp bên ngoài. Nó có thể được truy cập mà không cần khởi tạo lớp ngoài, sử dụng các thành viên tĩnh khác. Cũng giống như các thành viên tĩnh, một lớp lồng nhau tĩnh không có quyền truy cập vào các biến cá thể và phương thức của lớp bên ngoài. Cú pháp của lớp lồng nhau tĩnh như sau:

Syntax

class MyOuter {
   static class Nested_Demo {
   }
}

Việc khởi tạo một lớp lồng nhau tĩnh hơi khác một chút so với việc tạo một lớp bên trong. Chương trình sau đây cho thấy cách sử dụng một lớp lồng nhau tĩnh.

Example

public class Outer {
   static class Nested_Demo {
      public void my_method() {
         System.out.println("This is my nested class");
      }
   }
   
   public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();	 
      nested.my_method();
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is my nested class