1. 程式人生 > >Java中內部類的定義及使用

Java中內部類的定義及使用

一、定義

1.在一個類的內部進行其他類結構的巢狀的操作。

例:

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 Test4{
    public static void main(String[] args){
        Outer out = new Outer();//外部類物件
        out.fun();//外部類方法
    }
}

二、分類

  1.成員內部類(成員方法)
          a.成員內部類不能存在任何static變數或方法,可以訪問外部類的靜態域
          b.成員內部類是依附外部類的,只有先建立了外部類才能建立內部類
  2.靜態內部類(靜態方法)
          a.靜態內部類的建立不需要依賴外部類,可以直接建立
          b.靜態內部類不可以使用任何外部類的static域(包含屬性與方法),但可以存在自己       
             的成員變數
  3.方法內部類
    要求:a. 區域性內部類不允許使用訪問許可權修飾符 public、 private、 protected 均不允許 
         b. 區域性內部類對外部完全隱藏,除了建立這個類的方法可以訪問它其他的地方是
            不允許訪問的。
         c. 區域性內部類要想使用方法形參,該形參必須用final宣告(JDK8將形參變為隱式
            final宣告).
  4.匿名內部類(landba表示式前身)
     沒有名字的方法內部類,它符合方法內部類的所有約束.除此之外,還有兩個自己的特點:
         a. 匿名內部類必須繼承一個抽象類或者實現一個介面
         b.匿名內部類是沒有構造方法的,因為它沒有類名。

三、建立內部類語法(在外部類外部)

1.建立非靜態內部類
       外部類.內部類    內部類引用 = new  外部類().new    內部類();
       Outter.Inner in = new Outter().new Inner();
2.建立靜態內部類:
       外部類.內部類    內部類引用 = new  外部類.內部類();
       Outter.Inner  in = new Outter.Inner();

四、內部類的優點和缺點

1. 內部類與外部類可以方便的訪問彼此的私有域(包括私有方法,私有屬性)
2. 內部類是另外另外一種封裝(保護性),對外部的其他類隱藏(心臟包在人身體內部)。
3. 內部類可以實現 java 單繼承的侷限
   內部類的缺點:結構複雜

五、內部類與外部類的關係

1.對於非靜態內部類,內部類的建立需要依賴外部類物件,在沒有外部類例項之前無法建立非靜態內部類
2.內部類是一個相對獨立的個體,與外部類沒有is - a關係
3.內部類可以直接房訪問外部類的元素(包含私有域),但是外部類不可以直接訪問內部類元素,需要通過內部類的引用間接訪問

原始碼

1. 靜態內部類
class Outer{
    private static String msg = "Hello World!";
    //定義一個內部類
    //*******************************************************
    static class Inner{
        public void print(){
            System.out.println(msg);  //呼叫msg
        }
    }
    //*******************************************************
    //外部類方法
    public void fun(){
        Inner in = new Inner(); //靜態內部類物件
        in.print();   //呼叫靜態內部類方法
    }
}
public class Test4{
    public static void main(String[] args){
        Outer out = new Outer();//外部類物件
        out.fun();//外部類方法
    }
}    
2.方法內部類
  class Outer{
    private int num;
    //外部類方法
    public void fun(final int test){
         //定義一個方法內部類
         //*******************************************************
        class Inner{
            public void print(){
                num++;
                System.out.println(num);  
                System.out.println(test);
            }
        //*******************************************************
        }
    Inner in = new Inner();//在方法內部定義方法內部類物件
    in.print();  //
    }
}
public class Test4{
    public static void main(String[] args){
        Outer out = new Outer();//外部類物件
        out.fun(20);//外部類方法
    }
}    
3.匿名內部類
interface MyInterface{
    void test();
}
class Outer{
    public void fun(final int temp){
        new MyInterface(){
            public void test(){
                System.out.println("匿名內部類!"+temp);
            }
        }.test();
    }
}
public class Test4{
    public static void main(String[] args){
        Outer out = new Outer();//外部類物件
        out.fun(20);//外部類方法
    }
}   
4.用內部類來實現"多繼承"
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 String name() {
        return new InnerClassA().name();
    }
    public int age() {
        return new InnerClassB().age();
    }
}
public class Test4 {
    public static void main(String[] args) {
        Outter outter = new Outter();
        System.out.println(outter.name());
        System.out.println(outter.age());
    }
}