天天看點

内部類:非靜态内部類,靜态内部類,局部内部類,匿名内部類詳解

大部分時候,類被定義成一個獨立的成簇單元。在某些情況下,也會把一個類放在另一個類的内部定義,這個定義在其他内部的類被稱為内部類(有的地方也叫嵌套類),包含内部類的類也被稱為外部類(有的地方也叫宿主類);

内部類主要作用如下:

1. 内部類提供更好的封裝,可以把内部類隐藏在外部類之内,不允許同一包中的其他類通路該類。

2. 内部類成員可以直接通路外部類的私有資料,應為内部類被當成其外部類的成員,同一個類的成員之間可以互相通路。

3. 匿名内部類适合用于建立那些僅需要一次使用的類。

内部類大緻分為:非靜态内部類,靜态内部類,局部内部類和匿名内部類;

**

1.非靜态内部類

**

(1).可直接通路外部類的所有資料;

(2)通路内部類,必須建立對象

①外部類通路,直接建立對象

②其他類通路,外部類名.内部類名 對象名 = 外部類對象.内部類對象;

(3)當變量名與外部類重名時,用引用區分

(4)私有内部類,在外部類建立get()方法建立内部類對象

(5)非靜态内部類不能有靜态成員

例1: 調用内部類,通路外部類成員

public class Test {
    public static void main(String[] args) {
        //外部類名.内部類名  對象名 = 外部類對象.内部類對象
        A.B ab = new A().new B();     
        ab.print();
    }
}

class A{
    private int n =;     //外部類成員變量
    int m = ;
    private void method() {
        System.out.println("method");
    }
    class B {
        //static int a=10;        //非靜态内部類不能有靜态成員
        public void print() {     //内部類随意通路外部類成員
            System.out.println("輸出結果:");
            System.out.println(n);
            System.out.println(m);
            method();
        }
    }
}
輸出結果:


method
           

例2:私有内部類

class A{
    private class B {
        public void print() {
            System.out.println("輸出結果:");
            System.out.println("私有内部類");
        }
    }
    public void getB() {        //建立get()方法
        B b = new B();          //方法中生成内部類對象
        b.print();
    }
}
public class Test {
    public static void main(String[] args) {
        A a = new A();
        a.getB();
    }
}
輸出結果:
私有内部類
           

例3:變量名重名,引用區分

class A{
    int m = ;
    class B {
        int m = ;
        public void print() {
            int m = ;
            System.out.println("輸出結果:");
            System.out.println(m);          //局部變量
            System.out.println(this.m);     //内部類成員變量
            System.out.println(A.this.m);   //外部類成員變量
        }
    }
}
public class Test {
    public static void main(String[] args) {
        A.B ab = new A().new B();
        ab.print();
    }
}
輸出結果:



           

2.靜态内部類

(1)通路内部類
      ①外部類通路,直接(類名.)調用
      ②其他類通路,外部類名.内部類名  對象名 = 外部類名.内部類對象;
 (2)靜态内部類不可以直接通路外部類的非靜态資料
           
class A{
    int m = ;
    static class B {
        public void print() {
            System.out.println("輸出結果:");
            //System.out.println(m);       //無法通路
            System.out.println("靜态内部類");
        }
    }
}
public class Test {
    public static void main(String[] args) {
        A.B ab = new A.B();        //A.B ab = A.new B();
        ab.print();                //兩者等效,前者更符合書寫習慣;
    }
}
輸出結果:
靜态内部類
           

3.局部内部類

定義在方法體中,相當于局部變量
     局部内部類通路所在方法的變量必須用final修飾
     為什麼?
     答:當調用這個方法時,不修飾則随方法共存亡;如果用fianl修飾,會在類加載的時候進入常量池,即使方法貪占消失,常量池仍可使用。
           
class A{
    int m = ;
    public void method() {
        final int n = ;
        class B {
            public void print(){
                System.out.println("輸出結果:");
                System.out.println(n);
                System.out.println(m);
            }
        }
        B b = new B();
        b.print();
    }
}
public class Test {
    public static void main(String[] args) {
        A a = new A();                  
        a.method();                     
    }
}
輸出結果:


           

4.匿名内部類(局部内部類的一種)

前提:存在一個類或者接口
     本質:匿名内部類當做參數傳遞(本質把匿名内部類作為一個對象)
     作用:适合建立那種隻需要一次使用的類
           

例1:

interface C {
    public void print();
}
class A{
    public void method(){
        new C() {          //實作該接口,建立接口的子類對象
            public void print() {
                System.out.println("輸出結果:");
                System.out.println("匿名内部類1");
            }
        }.print();       //編譯看父類,運作看子類
    }
}   
public class Test {
    public static void main(String[] args) {
    A a = new A();
    a.method();
    }
}
輸出結果:
匿名内部類
           

**例2:

了解更清晰,多态,父類引用指向子類對象**

interface C {
    public void print();
}
class A{
    public C method(){
        C c = new C() {
            public void print() {
                System.out.println("輸出結果:");
                System.out.println("匿名内部類2");
            }
        };
        return c;
    }
}   
public class Test {
    public static void main(String[] args) {
    A a = new A();
    a.method().print();
    }
}
輸出結果:
匿名内部類