1. 程式人生 > 遊戲攻略 >《原神攻略》海的那頭是故鄉任務攻略

《原神攻略》海的那頭是故鄉任務攻略

內部類的基本概念

• 當一個類的定義出現在另外一個類的類體中時,那麼這個類叫做內部類 (Inner),而這個內部類所在的類叫做外部類(Outer)。

• 類中的內容:成員變數、成員方法、構造方法、靜態成員、構造塊和靜 態程式碼塊、內部類。

實際作用

當一個類存在的價值僅僅是為某一個類單獨服務時,那麼就可以將這個 類定義為所服務類中的內部類,這樣可以隱藏該類的實現細節並且可以 方便的訪問外部類的私有成員而不再需要提供公有的get和set方法。

內部類的分類

• 普通內部類 - 直接將一個類的定義放在另外一個類的類體中。 • 靜態內部類 - 使用static關鍵字修飾的內部類,隸屬於類層級。 • 區域性內部類 - 直接將一個類的定義放在方法體的內部時。
• 匿名內部類 - 就是指沒有名字的內部類。 普通內部類格式
訪問修飾符 class 外部類的類名 {   訪問修飾符 class 內部類的類名 {

    內部類的類體; }

}

code

public class NormalOuter {
    private int cnt = 1;

    // 定義普通內部類,隸屬於外部類的成員,並且是物件層級
    /*private*/public /*final*/ class NormalInner {
        private int ia = 2;
        private int cnt = 3;
        public NormalInner() {
            System.out.println(
"普通內部類的構造方法體執行到了!"); } public void show() { System.out.println("外部類中變數cnt的數值為:" + cnt); // 1 System.out.println("ia = " + ia); // 2 } public void show2(int cnt) { System.out.println("形參變數cnt = " + cnt); // 區域性優先原則 4 System.out.println("內部類中cnt = " + this
.cnt); // 3 System.out.println("外部類中cnt = " + NormalOuter.this.cnt); // 1 } }
public class NormalOuterTest {

    public static void main(String[] args) {

        // 1.宣告NormalOuter型別的引用指向該型別的物件
        NormalOuter no = new NormalOuter();
        // 2.宣告NormalOuter類中內部類的引用指向內部類的物件
        NormalOuter.NormalInner ni = no.new NormalInner();
        // 呼叫內部類中的show方法
        ni.show();

        System.out.println("---------------------------------------------");
        ni.show2(4);
    }
}
普通內部類的使用方式
  • 普通內部類和普通類一樣可以定義成員變數、成員方法以及構造方法等。

  • 普通內部類和普通類一樣可以使用final或者abstract關鍵字修飾。

  • 普通內部類還可以使用private或protected關鍵字進行修飾。

  • 普通內部類需要使用外部類物件來建立物件。

  • 如果內部類訪問外部類中與本類內部同名的成員變數或方法時,需要使 用this關鍵字。

靜態內部類格式 訪問修飾符 class 外部類的類名 {   訪問修飾符 static class 內部類的類名 {

    內部類的類體; }

}

code

/**
 * 實現靜態內部類的定義和使用
 */
public class StaticOuter {
    private int cnt = 1;        // 隸屬於物件層級
    private static int snt = 2; // 隸屬於類層級

    public /*static*/ void show() {
        System.out.println("外部類的show方法就是這裡!");
    }

    /**
     * 定義靜態內部類   有static關鍵字修飾隸屬於類層級
     */
    public static class StaticInner {
        private int ia = 3;
        private static int snt = 4;

        public StaticInner() {
            System.out.println("靜態內部類的構造方法哦!");
        }

        public void show() {
            System.out.println("ia = " + ia); // 3
            System.out.println("外部類中的snt = " + snt); // 2
            //System.out.println("外部類的cnt = " + cnt); // Error:靜態上下文中不能訪問非靜態的成員,因此此時可能還沒有建立物件
        }

        public void show2(int snt) {  // 就近原則
            System.out.println("snt = " + snt); // 5
            System.out.println("內部類中的成員snt = " + StaticInner.snt); // 4
            System.out.println("外部類中的成員snt = " + StaticOuter.snt); // 2
            //StaticOuter.show();
            new StaticOuter().show();
        }
    }
}
public class StaticOuterTest {

    public static void main(String[] args) {

        // 1.宣告StaticInner型別的引用指向該型別的物件
        StaticOuter.StaticInner si = new StaticOuter.StaticInner();
        // 2.呼叫show方法進行測試
        si.show();

        System.out.println("---------------------------------------------");
        si.show2(5);
    }
}

靜態內部類使用方式

• 靜態內部類不能直接訪問外部類的非靜態成員。

• 靜態內部類可以直接建立物件。

• 如果靜態內部類訪問外部類中與本類內同名的成員變數或方法時,需要 使用類名.的方式訪問。

區域性(方法)內部類格式

訪問修飾符 class 外部類的類名 {
  訪問修飾符 返回值型別 成員方法名(形參列表) {

    class 內部類的類名 {

      內部類的類體;}

  }

}

區域性內部類使用方式

  區域性內部類只能在該方法的內部可以使用。

  區域性內部類可以在方法體內部直接建立物件。

  區域性內部類不能使用訪問控制符和static關鍵字修飾符。

  區域性內部類可以使用外部方法的區域性變數,但是必須是final的。由區域性內部類和區域性變數的宣告週期不同所致

public class AreaOuter {
    private int cnt = 1;

    public void show() {

        // 定義一個區域性變數進行測試,從Java8開始預設理解為final關鍵字修飾的變數
        // 雖然可以省略final關鍵字,但建議還是加上
        final int ic = 4;

        // 定義區域性內部類,只在當前方法體的內部好使
        class AreaInner {
            private int ia = 2;

            public AreaInner() {
                System.out.println("區域性內部類的構造方法!");
            }

            public void test() {
                int ib = 3;
                System.out.println("ia = " + ia); // 2
                System.out.println("cnt = " + cnt); // 1
                System.out.println("ic = " + ic); // 4
            }
        }

        // 宣告區域性內部類的引用指向區域性內部類的物件
        AreaInner ai = new AreaInner();
        ai.test();
    }

}
public class AreaOuterTest {

    public static void main(String[] args) {

        // 1.宣告外部類型別的引用指向外部類的物件
        AreaOuter ao = new AreaOuter();
        // 2.通過show方法的呼叫實現區域性內容類的定義和使用
        ao.show();
    }
}

回撥模式概念

回撥模式是指——如果一個方法的引數是介面型別,則在呼叫該方法時, 需要建立並傳遞一個實現此介面型別的物件;而該方法在執行時會呼叫 到引數物件中所實現的方法(介面中定義的)。

匿名內部類格式

介面/父類型別 引用變數名 = new 介面/父類型別() { 方法的重寫 };

code

public interface AnonymousInterface {
    // 自定義抽象方法
    public abstract void show();
}
public class AnonymousInterfaceImpl implements AnonymousInterface {
    @Override
    public void show() {
        System.out.println("這裡是介面的實現類!");
    }
}
public class AnonymousInterfaceTest {

    // 假設已有下面的方法,請問如何呼叫下面的方法?
    // AnonymousInterface ai = new AnonymousInterfaceImpl();
    // 介面型別的引用指向實現型別的物件,形成了多型
    public static void test(AnonymousInterface ai) {
        // 編譯階段呼叫父類版本,執行呼叫實現類重寫的版本
        ai.show();
    }

    public static void main(String[] args) {

        //AnonymousInterfaceTest.test(new AnonymousInterface()); // Error:介面不能例項化
        AnonymousInterfaceTest.test(new AnonymousInterfaceImpl());

        System.out.println("---------------------------------------------------------------");
        // 使用匿名內部類的語法格式來得到介面型別的引用,格式為:介面/父類型別 引用變數名 = new 介面/父類型別() { 方法的重寫 };
        AnonymousInterface ait = new AnonymousInterface() {
            @Override
            public void show() {
                System.out.println("匿名內部類就是這麼玩的,雖然你很抽象!");
            }
        };

        // 從Java8開始提出新特性lamda表示式可以簡化上述程式碼,格式為:(引數列表) -> {方法體}
        AnonymousInterface ait2 = () -> System.out.println("lamda表示式原來是如此簡單!");
        AnonymousInterfaceTest.test(ait2);
    }
}