Java 教程

Java 控制語句

面向物件程式設計

Java 內建類

Java 檔案處理

Java 錯誤與異常

Java 多執行緒

Java 同步

Java 網路程式設計

Java 集合

Java 介面

Java 資料結構

Java 集合演算法

高階 Java

Java 雜項

Java API 與框架

Java 類參考

Java 有用資源

Java - 內部類



Java 內部類

Java 內部類是在另一個類內部定義的。內部類的概念與巢狀 Java 類一起使用,其中使用外部類和內部類。定義內部類的主要類稱為外部類,而外部類內部的所有其他類都稱為Java 內部類

巢狀類

在 Java 中,就像方法一樣,類的變數也可以擁有另一個類作為其成員。在 Java 中允許在一個類中編寫另一個類。在內部編寫的類稱為巢狀類,包含內部類的類稱為外部類

語法

以下是編寫巢狀類的語法。在這裡,類Outer_Demo是外部類,類Inner_Demo是巢狀類。

class Outer_Demo {
   class Inner_Demo {
   }
}

巢狀類分為兩種型別 -

  • 非靜態巢狀類 - 這些是類的非靜態成員。

  • 靜態巢狀類 - 這些是類的靜態成員。

Inner Classes

內部類(非靜態巢狀類)

內部類是 Java 中的一種安全機制。我們知道一個類不能與訪問修飾符private相關聯,但是如果我們將該類作為另一個類的成員,則可以將內部類設為私有。這還用於訪問類的私有成員。

Java 內部類的型別

內部類根據您定義它們的方式和位置分為三種類型。它們是 -

  • 內部類
  • 方法區域性內部類
  • 匿名內部類

建立內部類

建立內部類非常簡單。您只需要在一個類中編寫一個類即可。與類不同,內部類可以是私有的,並且一旦您將內部類宣告為私有的,就無法從類外部的物件訪問它。

以下是建立內部類並訪問它的程式。在給定的示例中,我們將內部類設為私有,並透過方法訪問該類。

示例:在 Java 中建立內部類

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

在這裡您可以觀察到Outer_Demo是外部類,Inner_Demo是內部類,display_Inner()是在其中例項化內部類的方法,並且此方法從main方法呼叫。

如果您編譯並執行上述程式,您將獲得以下結果 -

輸出

This is an inner class.

訪問私有成員

如前所述,內部類也用於訪問類的私有成員。假設一個類具有私有成員來訪問它們。在其中編寫一個內部類,從內部類中的一個方法(例如getValue())返回私有成員,最後從另一個類(您想從中訪問私有成員的類)呼叫內部類的 getValue() 方法。

要例項化內部類,首先必須例項化外部類。此後,使用外部類的物件,以下是例項化內部類的方式。

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

以下程式顯示瞭如何使用內部類訪問類的私有成員。

示例:使用內部類訪問私有成員

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

如果您編譯並執行上述程式,您將獲得以下結果 -

輸出

This is the getnum method of the inner class: 175

方法區域性內部類

在 Java 中,我們可以在方法內部編寫一個類,這將是區域性型別。像區域性變數一樣,內部類的作用域僅限於方法內部。

方法區域性內部類只能在其定義的方法內部例項化。以下程式顯示瞭如何使用方法區域性內部類。

示例:方法區域性內部類

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

如果您編譯並執行上述程式,您將獲得以下結果 -

輸出

This is method inner class 23

匿名內部類

未宣告類名的內部類稱為匿名內部類。對於匿名內部類,我們同時宣告和例項化它們。通常,當您需要覆蓋類或介面的方法時使用它們。匿名內部類的語法如下 -

語法:匿名內部類

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

以下程式顯示瞭如何使用匿名內部類覆蓋類的方法。

示例:匿名內部類

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

如果您編譯並執行上述程式,您將獲得以下結果 -

輸出

This is an example of anonymous inner class

以相同的方式,您可以使用匿名內部類覆蓋具體類和介面的方法。

匿名內部類作為引數

通常,如果一個方法接受介面、抽象類或具體類的物件,那麼我們可以實現介面、擴充套件抽象類並將物件傳遞給方法。如果是類,我們可以直接將其傳遞給方法。

但在所有三種情況下,您都可以將匿名內部類作為引數傳遞給方法。以下是將匿名內部類作為方法引數傳遞的語法 -

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

以下程式展示瞭如何將匿名內部類作為方法引數傳遞。

示例

// 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";
         }
      });
   }
}

如果您編譯並執行上述程式,則會得到以下結果:

輸出

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

靜態巢狀類

靜態內部類是作為外部類靜態成員的巢狀類。它可以使用其他靜態成員在不例項化外部類的情況下進行訪問。就像靜態成員一樣,靜態巢狀類無法訪問外部類的例項變數和方法。靜態巢狀類的語法如下:

語法

class MyOuter {
   static class Nested_Demo {
   }
}

例項化靜態巢狀類的方式與例項化內部類略有不同。以下程式展示瞭如何使用靜態巢狀類。

示例

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

如果您編譯並執行上述程式,您將獲得以下結果 -

輸出

This is my nested class
廣告