天天看點

内部類(基礎)

  • 内部類

内部類可以直接通路外部類的成員

外部類想要通路外部類的成員,先需要執行個體化内部對象也就是(new内部對象)

  • 成員内部類
Outer.Inner inner=new Outer().new Inner()
           

成員内部類持有外部類對象的引用

  • 我的了解:(外部類對象可以引用成員内部類)

    要想有成員内部類對象,先要有外部類對象

先建立一個Net類

public class Net {
	UI ui;
	public void setUi(UI ui){
		this.ui = ui;
	}
	public void loadData( ){
		String str="Hello wrold";
		ui.updateUI(str);
	}
}
           

然後再建立UI類

public class UI {
	public void updateUI(String str){
		System.out.println("正在更新"+str);
	}
	class Net{
		public void loadData(){
		}
	}

}
           

UI類裡面有Net内部類

再建立一個測試類Test

public class Test {
	public static void main(String[] args) {
		UI ui=new UI();
		Net net=new Net();
		net.setUi(ui);
		net.loadData();
	}
}
           

輸出結果為:正在更新Hello wrold

成員内部類可能出現記憶體洩漏的問題,記憶體越用越少,有些對象沒有釋放完畢。(如果你想釋放外部類對象,但是成員内部類持有外部對象的引用。是以回收不了。)

  • 靜态内部類

    靜态内部類不需要有外部類對象,靜态内部類不持有外部類的引用,靜态内部類不能通路外部的非靜态成員,但是可以通過new()外部類 .成員的方法通路

建立靜态内部類

public class HelloWorld {
   private int dynamic_score = 77;
public static class SInner {
   int score = 91;
public void show() {
System.out.println("通路外部類中的非靜态變量dynamic_score:" +  new HelloWorld().dynamic_score);
System.out.println("通路内部類中的score:" + score);
}
}
           

測試靜态内部類

public static void main(String[] args) {
		// 直接建立内部類的對象
        SInner si = new SInner();   
        // 調用show方法
		si.show();
}
}
           

輸出結果:

通路外部類中的非靜态變量dynamic_score:77

通路内部類中的score:91

  • 匿名内部類

    匿名内部類最長用:

Net net=new Net(){loadDate(){}};

BufferedReader br=new BufferedReader(new FileReader(""));
           

注意事項:

1、匿名内部類中是不能定義構造函數的。

2、匿名内部類中不能存在任何的靜态成員變量和靜态方法。

3、匿名内部類不能是抽象的,它必須要實作繼承的類或者實作的接口的所有抽象方法。

4、沒有抽象方法的抽象類。

這裡定義了一個人吃的抽象方法
要想在抽象類中使用匿名内部類,必須實作一個繼承或者一個接口
abstract class Person {
    public abstract void eat();
}
 
class Child extends Person {
    public void eat() {
        System.out.println("eat something");
    }
}
public class Demo {
    public static void main(String[] args) {
        Person p = new Child();
        p.eat();
    }
}
           

輸出結果為:

eat something

  • 局部内部類

    寫在方法中的,一般來說,需要傳回對象,之後想什麼時候調用就什麼時候調用。

    在局部内部類通路方法中的變量的時候,變量需要是final的,(常量)如果不定義成final的,變量就會随着方法的結束從棧記憶體消失、導緻局部内部類不能通路局部變量。

展現局部内部類的代碼
class Out {
    private int age = 12;
    public void Print(final int x) {
        class In {
            public void inPrint() {
                System.out.println(x);
                System.out.println(age);
            }
        }
        new In().inPrint();
    }
}
           
final int x 
由上面代碼可知: 
局部内部類通路方法中的變量的時候,變量需要是final修飾的 
           
測試類
public class Demo {
    public static void main(String[] args) {
        Out out = new Out();
        out.Print(3);
    }
}
           

運作結果為:

3

12

在上面的代碼中,我們将内部類移到了外部類的方法中

内部類移到了外部類
public void Print(final int x) {
        class In {
        
在外部類的方法中再生成一個内部類對象去調用内部類方法
main方法中的:
out.Print(3);


           

注意事項:

1、此類不能使用public、private修飾。

2、其作用域被限定在聲明此類的方法中。

3、和其他内部類相比,它具有可以通路方法參數的優點。

4、被局部内部類使用的方法參數必須是final的。

5、局部類隻能通路(使用)這個塊中(局部類外)final屬性。這裡的塊包括了上面說的塊、構造器、方法。

6、在類外不可直接生成局部内部類,要想使用局部内部類時需要生成對象,對象調用方法,在方法中才能調用其局部内部類。

繼續閱讀