Day26:內部類的詳解

工地佬 發表於 2022-11-29

內部類

1.1內部類概述

內部類:就是在一個類中定義另外一個類。

例如我們在A類中定義一個B類,那麼B類就是A類的內部類,A則是B的外部類。

好比我們的手機是一個類,而手機內部的零件又屬於一個類。

內部類的定義格式:

/*格式:
public class 類名{
    修飾符 class 類名{
        
    }
}
*/
//範例:
public class Outer{//外部類
    public class Inner{//內部類
        
    }
}

內部類的特點:

  • 內部類可以直接訪問外部類的所有成員
  • 外部類訪問內部類的成員必須建立物件
public class Outer{
    private int a=10;
    public String name="工地佬";
    public void show(){
        System.out.println("外部類的方法");
    }
    
    //內部類
    public class Inner{//當內部類的修飾符為靜態時,則無法訪問外部類的非靜態成員,因為靜態成員與類共載入,而非靜態成員從屬於物件,時間上有所差異
        public void show(){
        System.out.println("內部類的方法");
        System.out.println("外部類的屬性"+a+name);//內部類可以訪問外部類的所有成員
        }  
    }
    
    //外部類訪問內部類的方法必須建立內部類的物件
    public void Method(){
        Inner i=new Inner();
        i.show();
    }
    
}

1.2 內部類的種類

根據內部類所在類的位置不同,將內部類劃分為以下兩種形式:

  • 成員內部類:為內部類的成員位置

  • 區域性內部類:為類的區域性位置,也就是方法內的類


1.2.1成員內部類

當外部程式訪問內部類時,如何將內部類物件例項化?

  • 當在外部訪問一個類中的成員內部類時:

我們要先建立外部類的物件,再透過外部類物件再建立內部類的物件;

格式:外部類名.內部類名 類名=外部類物件.內部類;

範例:Outer.Inner i=new Outer().new Inner();

//建立一個含有成員內部類的類
public class Outer{
    private int a=10;
    public class Inner{
        public void show(){
            System.out.println(a);
        }
    }
}
//測試類
public class Test{
    public static void main(String[] args){
        //建立內部類格式
        Outer.Inner i=new Outer().new Inner();
        i,show();
    }
}

我們建立內部類其實是不想讓外界直接訪問,所以我們的內部類的修飾符一般不會用public,而是用private

當我們將內部類私有化後,會在外部類留有一個方法來訪問內部類

public class Outer{
    private int a=10;
       /* public class Inner{
        public void show(){
            System.out.println(a);
        }我們的內部類一般不用public
    }
    */
    private class Inner{
        public void show(){
           System.out.println(a); 
        }
    }
    //在外部類中留下一個方法來訪問內部類
    public void method(){
        Inner i=new Inner();
        i.show();
    }
    
}
//測試類
public class Test{
    public static void main(String[] args){
        Outer o=new Outer();
        o.method();
    }
}

1.2.2 區域性內部類

  • 區域性內部類是在類中方法定義的類,外界是無法直接使用的,需要在方法中建立內部類的物件方可使用
  • 區域性內部類可以直接訪問方法內的區域性變數以及外部類的成員。
public class Outer{
    private int a=10;
    public void method(){
        int b=20;//方法中的區域性變數
        class Inner{
            public void show(){
            System.out.println(a);//可以訪問外部類的成員
            System.out.println(b);//可以訪問方法中的區域性變數
          }
        }
        Inner i=new Inner();//要訪問區域性內部類的成員,必須透過在外部類的方法中建立區域性內部類的物件進而呼叫
        i.show();
    }
}
public class Test{
    public static void main(String[] args){
        /*Outer o=new Outer();
        o.method;    直接呼叫方法並不會將方法中的類的方法執行,因為並沒有明確的指令去呼叫區域性內部類的方法
        */
        //在方法中建立區域性內部類後方可訪問
        Outer o=new Outer();
        o.method; // 10  20
    }
}

1.2.2.1 區域性內部類中的匿名內部類

前提:有一個類或者介面,這個類可以是普通類,也可以是抽象類。

格式:new 類名/介面名(){

重寫的方法};

案例:

new Inter(){
   public void show{
        Syestem.out.println("匿名內部類輸出了");
    }
);

匿名內部類也是在方法之中,其本質其實是一個繼承類的子類物件或者是介面的實現類物件,只是沒有名字而已。

public interface Inter{
    void show();
}
public class Outer{
    
    private int a=10;
    
    public void method{//外部類方法
        
        String name="工地佬";
        
        new Inter(){//匿名內部類,本質為實現類的物件
            public void show(){
                System.out.println("匿名內部類");
            }
        };
        //如何訪問匿名內部類的方法呢?
        //既然其是一個物件,那麼直接 物件.方法 呼叫即可
        new Inter(){
            public void show(){
                System.out.println("匿名內部類");
            }
        }.show();//匿名內部類直接.方法可以且只能呼叫其自身重寫的方法
        //因為該匿名內部類為一個實現類物件,我們可以用多型的方式去接收這個物件
        Inter i=new Inter(){
            public void show(){
                System.out.println("匿名內部類");
            }
        };
        //然後直接用i來呼叫方法
        i.show();
    }
}
public class Test{
    public static void main(String[] args){
        Outer o=new Outer();
        o.method();
    }
}