1. 程式人生 > >內部類的定義與使用

內部類的定義與使用

基本概念:就是在一個類內部進行其他類結構巢狀操作。

內部類的優點

  1. 內部類與外部類可以方便地訪問彼此的私有域(包含私有方法、私有屬性)。
    eg:
class Outer{
    private String msg = "Hello World";
    //內部類
    //--------------------------------
    class Inner{
        public void print(){
            System.out.println(msg);
        }
    }
    //--------------------------------
    public void fun(){
        Inner in = new Inner();
        in.print();
    }
}
public class InnerClass{
    public static void main(String[] args){
        Outer out = new Outer();
        out.fun();
    }
}
  1. 內部類是另外一種封裝(保護性),對外部其他類隱藏。
  2. 外部類可以實現Java單繼承的侷限。
    eg:
class A{
    private String name = "A的私有域";
    public String getName(){
        return name;
    }
}
class B{
    private int age = 20;
    public int getAge(){
        return age;
    }
}
class Outter{
    private class InnerClassA extends A{
        public String name(){
            return super.getName();
        }
    }
    private class InnerClassB extends B{
        public int age(){
            return super.getAge();
        }
    }
    public int age(){
        return new InnerClassB().age();
    }
    public String name(){
        return new InnerClassA().name();
    }
}
public class InnerToExtends{
    public static void main(String[] args){
        Outter out = new Outter();
        System.out.println(out.name());
        System.out.println(out.age());
    }
}

缺點:
結構複雜

內部類與外部類的關係

  1. 對於非靜態內部類,內部類的建立需要依賴外部類物件,在沒有外部類例項之前無法建立非靜態內部類。
  2. 內部類是一個相對獨立的個體,與外部類沒有is-a(繼承)關係。
  3. 內部類可以直接訪問外部類的元素(包含私有域)
    eg:
class Outer{
    private String msg = "Hello World";
    //內部類
    //--------------------------------
    class Inner{
        public void print(){
            System.out.println(msg);
        }
    }
    //--------------------------------
  1. 外部類不可以直接訪問內部類元素,需要通過內部類的間接引用訪問。
    eg:
class Outer{
    private String msg = "Hello World";
    //內部類
    //--------------------------------
    class Inner{
        public void print(){
            System.out.println(msg);
        }
    }
    //--------------------------------
    public void fun(){
        Inner in = new Inner();
        in.print();
    }
}
public class InnerClass{
    public static void main(String[] args){
        Outer out = new Outer();
        out.fun();
    }
}

建立內部類語法(在外部類外部

  1. 建立非靜態內部類
    外部類.內部類 內部類引用 = new 外部類().new 內部類();

Outter.Inner in = new Outter().new Inner();

  1. 建立靜態內部類
    外部類.內部類 內部類引用 = new 外部類.內部類();

Outter.Inner in = Outter.Inner();

內部類的分類

  1. 成員內部類(成員方法)
    a. 成員內部類內部不能存在任何static變數或方法,可以訪問外部靜態域。

因為static一定不依賴物件,但方法依賴於物件,這兩者很明顯有矛盾,所以成員內部類(成員方法)中不能存在static。

b. 成員內部類是依附外部類的,所以只有先建立了外部類才能建立內部類。

  1. 靜態內部類
    a. 靜態內部類的建立不需要依賴外部類,可以直接建立。
    b. 靜態內部類不可以使用任何外部類的非static域(包含屬性與方法),但可以存在自己的成員變數。
  2. 方法內部類
    a. 方法內部類不允許使用訪問許可權修飾符public、private、protected均不允許。
    b. 方法內部類對外部完全隱藏,除了建立這個類的方法可以訪問它以外,其他地方均不能訪問。
    c. 方法內部類如果想要使用方法形參,該形參必須使用final宣告(JDK8將形參變為隱式final宣告)。
    eg:
class Outter{
    private int num;
    public void display(int test){
        class Inner{
            private void fun(){
                num++;
                test++;//這是錯誤的,test是被final修飾的,不能被改變
                System.out.println(num);
                System.out.println(test);
            }
        }
        new Inner().fun();
    }
}
public class Test{
    public static void main(String[] args){
        Outter out = new Outter();
        out.display(20);
    }
}
  1. 匿名內部類(Lamdba表示式前身)
    匿名內部類就是一個沒有名字的方法內部類。
    特點與方法內部類完全相同,除此之外,還有兩個自己的特點:
    a. 匿名內部類必須繼承一個抽象類或者實現一個介面。
    b. 匿名內部類沒有構造方法,因為它沒有類名。