Java例項說明 巢狀類包括內部類(即非靜態巢狀類)和靜態巢狀類 兩者的區別
內部類例項程式碼:
public class OuterMyTest {
class InnerMyTest{
}
public static void main(String[] args) {
InnerMyTest innerMyTest = new InnerMyTest();
}
}
編譯報錯:No enclosing instance of type OuterMyTest is accessible. Must qualify the allocation with an enclosing instance of type OuterMyTest (e.g. x.new A() where x is an instance of OuterMyTest).
說明:內部類例項化需要先例項化外部類 x.new A()
程式碼改進:
public class OuterMyTest { // 定義外部類
String s = "來訪問外部類的屬性吧!"; // 定義外部類的私有屬性
class InnerMyTest{ // 定義內部類
public void getInnerMyTest(){ // 定義內部類的方法
System.out.println(s); // 直接訪問外部類的私有屬性
}
}
public void fun(){ // 定義外部類的方法
new InnerMyTest().getInnerMyTest(); // 通過內部類的例項化物件呼叫方法
}
public static void main(String[] args) {
OuterMyTest outerMyTest = new OuterMyTest();
// 外部類例項化物件
InnerMyTest innerMyTest = outerMyTest.new InnerMyTest(); // 例項化內部類物件
innerMyTest.getInnerMyTest();
// 呼叫內部類的方法
outerMyTest.fun();
// 呼叫外部類的方法
}
}
執行結果:
來訪問外部類的屬性吧!
說明:
OuterMyTest outerMyTest = new OuterMyTest();
InnerMyTest innerMyTest = outerMyTest.new InnerMyTest();
我們在執行程式碼InnerMyTest innerMyTest = outerMyTest.new InnerMyTest();的時候,其實做了兩件事:
一件事是建立一個內部類的例項innerMyTest
第二件事是讓innerMyTest 繫結outerMyTest 作為其外圍類的例項。這樣innerMyTest 就可以訪問outerMyTest 內的所有成員屬性以及方法了。
靜態巢狀類例項程式碼:
public class OuterMyTest {
String s = "來訪問外部類的屬性吧!";
static class InnerMyTest{
public void getInnerMyTest(){
System.out.println(s);
}
}
public void fun(){
new InnerMyTest().getInnerMyTest();
}
public static void main(String[] args) {
OuterMyTest outerMyTest = new OuterMyTest();
InnerMyTest innerMyTest = outerMyTest.new InnerMyTest();
innerMyTest.getInnerMyTest();
outerMyTest.fun();
}
}
編譯報錯: Illegal enclosing instance specification for type OuterMyTest.InnerMyTest
給靜態巢狀類OuterMyTest .InnerMyTest 指定了非法的外圍類的例項。
程式碼改進:
public class OuterMyTest {
static String s = "來訪問外部類的屬性吧!";
static class InnerMyTest{
public void getInnerMyTest(){
System.out.println(s); // s要設定為靜態變數,否則編譯報錯:Cannot make a static reference to the non-static field s
}
}
public void fun(){
new InnerMyTest().getInnerMyTest();
}
public static void main(String[] args) {
OuterMyTest.InnerMyTest innerMyTest = new OuterMyTest.InnerMyTest();
innerMyTest.getInnerMyTest();
}
}
說明:
由於靜態巢狀類的本質就是一個靜態類,所以其例項物件的初始化不需要也不能像內部類那樣需要繫結一個外圍類物件。
由於靜態巢狀類沒有像內部類那樣繫結外部類物件,所以也就不存在靜態巢狀類不能訪問其外圍類的成員這種說法。