CodeGym /Java Blog /Toto sisi /Java內部類別
John Squirrels
等級 41
San Francisco

Java內部類別

在 Toto sisi 群組發布
在 Java 中,某些類別可以在其中包含其他類別。這樣的類別稱為巢狀類別。在其他類別中定義的類別通常分為兩類:靜態和非靜態。嵌套的非靜態類別稱為內部類別。聲明為靜態的巢狀類別稱為靜態巢狀類別。事實上,這裡並不複雜,儘管術語看起來有些模糊,有時甚至會讓專業軟體開發人員感到困惑。

巢狀類別和內部類別

因此,位於其他類別內部的所有類別都稱為巢狀類別。
class OuterClass {
    ...
    class NestedClass {
        ...
    }
}
非靜態的巢狀類別稱為內部類,靜態的稱為靜態巢狀類別Java 內部類別 - 1
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
因此,所有內部類別都是嵌套的,但並非所有嵌套都是內部的。這些是主要的定義。內部類別是Java中的一種安全機制。我們知道普通的類別不能與私有存取修飾符關聯。但是,如果我們的類別是另一個類別的成員,那麼可以將內部類別設為私有。此功能也用於存取私有類別成員。

內部類別範例

因此,讓我們嘗試創建一些類,並在其中創建另一個類。想像某種模組化遊戲機。本身有一個“盒子”,某些模組可以連接到它。例如,遊戲控制器、方向盤、VR 頭盔,通常沒有控制臺本身就無法運作。這裡我們有 GameConsole 類別。它有 2 個欄位和 1 個方法 — start()GameCosole和我們習慣的類別的差別在於它有一個內部的GameController類別。
public class GameConsole {
    private String model;
    private int weight;

    public void run() {
        System.out.println("Game console is on");
    }


    public class GameController {

        private String color;

        public void start() {
            System.out.println("start button is pressed");
        }

        public void x() {
            System.out.println("x button is pressed");
        }

        public void y() {
            System.out.println("y button is pressed");
        }
        public void a() {
            System.out.println("a button is pressed");
        }

        public void b() {
            System.out.println("b button is pressed");
        }
        public void mover() {
            System.out.println("mover button is pressed");
        }

    }

}
此時,您可能想知道:為什麼不將這些類別「分開」呢?沒有必要讓它們嵌套。確實有可能。相反,它是關於類別在使用方面的正確設計。建立內部類別是為了在程式中突出顯示與另一個實體密不可分的實體。控制器或 VR 安全帽等都是控制台的組件。是的,它們可以與控制台分開購買,但沒有它就無法使用。如果我們將所有這些類別設為單獨的公共類,我們的程式可能具有例如以下程式碼:
public class Main {

   public static void main(String[] args) {
       GameController controller = new GameController();
       controller.x();
   }
}
在這種情況下會發生什麼尚不清楚,因為如果沒有控制台,控制器本身就無法運作。我們創建了一個遊戲控制台物件。我們創建了它的子物件——遊戲控制器。現在我們可以玩了,只需按正確的鍵即可。我們需要的方法在正確的物件上呼叫。一切都簡單又方便。在這個例子中,提取遊戲控制器增強了封裝性(我們將控制台部分的細節隱藏在相應的類別中),並允許更詳細的抽象。但是,例如,如果我們創建一個程式來模擬可以單獨購買 VR 頭盔或控制器的商店,那麼這個範例就會失敗。最好單獨創建一個遊戲控制器。我們再舉一個例子。我們上面提到,我們可以將內部類別設為私有,但仍然可以從外部類別中呼叫它。下面是此類的一個範例。
class OuterClass {

   // inner class
   private class InnerClass {
       public void print() {
           System.out.println("We are in the inner class...");
       }
   }

   // method of outer class. We are create an inner class from the method of outer one
   void display() {
       InnerClass inner = new InnerClass();
       inner.print();
   }
}
這裡OuterClass是外部類,InnerClass是內部類,display()是我們在其中建立內部類別物件的方法。現在讓我們編寫一個帶有 main 方法的演示類,我們將在其中呼叫display()方法。
public class OuterDemoMain {

       public static void main(String args[]) {
           // create an object of the outer class
           OuterDemo outer = new OuterDemo();

           outer.display();
       }
}
如果您運行該程序,您將得到以下結果:
我們在內在班...

內部類別分類

內部類別本身或嵌套的非靜態類別分為三組。
  • 內部類照原樣。正如我們上面透過GameConsoleGameController範例所示範的那樣,只有一個非靜態類別位於另一個類別中。
  • 方法局部內部類別是方法內部的類別。
  • 匿名內部類別。
Java 內部類別 - 2

方法本地內部類別

在 Java 中,您可以在方法中編寫類,它是本機類型。與局部變數一樣,內部類別的範圍僅限於方法內。方法局部內部類別只能在定義該內部類別的方法內建立。讓我們來示範一下如何使用本地方法內部類別。
public class OuterDemo2 {

   //instance method of the outer class OuterDemo2
   void myMethod() {
       String str = "and it's a value from OuterDemo2 class' myMethod ";

       // method-local inner class
       class methodInnerDemo {
           public void print() {
               System.out.println("Here we've got a method inner class... " );
               System.out.println(str);

           }
       }

       // Access to the inner class
       methodInnerDemo inn = new methodInnerDemo();
       inn.print();
   }
}
現在我們將編寫一個帶有 main 方法的演示類,我們將在其中呼叫external()方法。
public class OuterDemoMain {


   public static void main(String args[]) {
       OuterDemo2 outer = new OuterDemo2();
       outer.myMethod();
   }
}
輸出是:
這裡我們有一個方法內部類別...它是來自 OuterDemo2 類別的 myMethod 的值

匿名內部類別

沒有類別名稱聲明的內部類別稱為匿名內部類別。當我們聲明一個匿名內部類別時,我們立即實例化它。通常,每當您需要重寫類別或介面方法時,就會使用此類。
abstract class OuterDemo3 {
   public abstract void method();

}
   class outerClass {

       public static void main(String args[]) {
           OuterDemo3 inner = new OuterDemo3() {
               public void method() {
                   System.out.println("Here we've got an example of an  anonymous inner class");
               }
           };
           inner.method();
       }
   }
輸出在這裡:
這裡我們有一個匿名內部類別的例子......

匿名內部類別作為參數

您也可以將匿名內部類別作為參數傳遞給該方法。這是一個例子。
interface OuterDemo4 {
       String hello();
   }

   class NewClass {
       // accepts the object of interface
       public void displayMessage(OuterDemo4 myMessage) {
           System.out.println(myMessage.hello());
           System.out.println("example of anonymous inner class as an argument");
       }

       public static void main(String args[]) {
           NewClass newClass = new NewClass();

           //here we pass an anonymous inner class as an argument
           newClass.displayMessage(new OuterDemo4() {
               public String hello() {
                   return "Hello!";
               }
           });
       }
}
輸出在這裡:
你好!匿名內部類別作為參數的範例
為了鞏固您所學到的知識,我們建議您觀看我們的 Java 課程中的影片課程
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION