內部類可以直接訪問外部類的成員
外部類想要訪問外部類的成員,先需要實例化內部對象也就是(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、在類外不可直接生成局部內部類,要想使用局部內部類時需要生成對象,對象調用方法,在方法中才能調用其局部內部類。