2018.10.11學習筆記
阿新 • • 發佈:2018-11-10
10.11學習筆記
今天學習了《Java程式設計思想》的第十章—內部類的前半部分。下面對今天學習收穫與疑惑作一個總結。
①內部類與外部類的聯絡:
當生成一個非靜態內部類的物件時,此物件必定會祕密的捕獲一個指向那個外圍類物件的引用,非靜態內部類的物件正是使用這個引用來訪問外部類的所有成員。因此,在建立一個非靜態內部類的物件時,必須要使用外部類物件的引用,有兩種方法獲取外部類物件的引用:外部類名字.this 和 new一個外部類物件,所以外部類名字.this = 外部類物件的引用。建立內部類時,就要使用這個外部類的物件引用.new 一個內部類物件。
②靜態內部類與非靜態內部類:
非靜態內部類:
初始化:非靜態內部類相當於外部類的一個方法,因此,非靜態內部類是在外部類載入完成之後自動載入的
呼叫外部類元素:非靜態內部類可以訪問外部類所有的成員,外部類也可以訪問內部類的所有成員變數(包括private方法,不過要建立一個內部類物件)。
自己成員、方法:非靜態內部類不允許宣告static成員變數和方法,因為java虛擬機器要求:所有的靜態變數必須在所有的非靜態變數載入完成之前載入記憶體之中。對於非靜態內部類,外部類載入完所有的靜態成員,然後載入內部類,最後才載入內部類中的靜態成員,顯然不滿足java虛擬機器的要求。
靜態內部類:
初始化:靜態內部類不需要對外部類物件的引用,靜態類和方法時屬於類本身,並不屬於該類的物件。外部類不會自動載入靜態內部類,只有呼叫到靜態內部類的成員變數或者方法時
呼叫外部元素:靜態內部類只能訪問外部類static方法和資料域。
自己的成員、方法:沒有限制,可以宣告靜態的,也可以宣告非靜態的。
無論是靜態內部類還是非靜態內部類,都會被編譯成內部類的個數 + 1 個class檔案。
/* attention:Outer經編譯後產生兩個class檔案(外部類名字$內部類名字($內部類名字).class) */ public class Outer { int a = 0; private static int b; class Inner{ //非靜態內部類可以訪問外部類的所有域 public int getA(){ return a; } public int getB(){ return b; } } public Inner getInner(){ return new Inner(); } //靜態內部類 static class staticInner{ //靜態內部類只能訪問外部類的static域 /** public int getA(){ return a; //無法訪問非static域 }*/ public int getB(){ return b; } } public static void main(String args[]){ Outer outer = new Outer(); Outer.Inner inner = outer.getInner(); //Outer.Inner inner1 = new Inner() 編譯器報錯 Outer.Inner inner1 = outer.new Inner();//使用外部類的物件.new 可以建立一個內部類物件 Outer.staticInner staticInner = new staticInner();//靜態內部類的建立不需要引用外部類的物件 } }
③內部類與向上轉型(現在還不理解其左右,只知道可以封裝一個類的實現):
通過將內部類向上轉型為一個介面的時候,可以完全隱藏實現的細節。
public interface First {
void description();
}
public class Second {
private class Inner implements First {
@Override
public void description(){
System.out.println("fuQian");
}
}
public First getFirst(){ //通過Second類返回一個內部類的物件
return new Inner();
}
}
public class Third extends Second {
public static void main(String args[]){
Second second = new Second();
second.getFirst().description(); //通過向上轉型為介面,可以訪問到內部類,所以完全隱藏了內部類的實現細節
//second.new Inner Inner類宣告為private,沒有任何人可以訪問他
}
}
通過內部類將Inner設定為private(普通的類只能宣告為public或者預設的包內訪問),因此所有人都不能訪問它,除非呼叫getFirst()方法返回一個Inner物件,從而完全隱藏了實現的細節。
④在方法和作用域內使用內部類:
public interface A {
public void test();
}
public class B{
public A getA(){
class Inner implements A{
@Override
public void test(){
System.out.println("膚淺");
}
}
return new Inner();
}
public static void main(String args[]){
B b = new B();
b.getA().test();
}
}
在getA()方法內建立了一個內部類並實現了A介面。
剩下的內部類內容,明天再學習吧。