內部類

1、什麼是內部類

定義:將一個類定義在另一個類的裏面,對裏面那個類就稱爲內部類(內置類,嵌套類)。

2、內部類的訪問規則

(1)內部類可以直接訪問外部類中的成員,包括私有。之所以可以直接訪問外部類中的成員,是因爲內部類中持有了一個外部類的引用。
格式:外部類名.this
(2)外部類要訪問內部類,必須建立內部類對象。

3、內部類的訪問格式

(1)當內部類定義在外部類的成員位置上,而且非私有,可以在外部其他類中直接建立內部類對象。
格式:外部類名.內部類名 變量名 外部類對象.內部類對象;
     Outer.Inner in = new Outer().new Inner();
(2)當內部類定義在局部位置上,也可以直接訪問外部類中的成員。
  同時可以訪問所在局部中的局部變量,但必須是被 final 關鍵字修飾的。
(3)當內部類在成員位置上,就可以被成員修飾符所修飾。
比如:private:將內部類在外部類中進行封裝。
      static:內部類就具備靜態的特性。
內部類代碼示例:
class InnerClassDemo {
	public static void main(String[] args){
		Outer.Inner in = new Outer().new Inner();  //創建一個內部類對象
		in.show();                                 //調用內部類對象中的show()方法
	}
}

class Outer {
	int x = 3;
	
	class Inner {
		int x = 4;
		void show() {
			System.out.println("show:"+Outer.this.x);
		}
	}
	
}
結果:


以上示例也可以寫成這樣:
class InnerClassDemo {
	public static void main(String[] args){
		new Outer().function();  //new一個父類的匿名對象
	}
}

class Outer {
	int x = 3;
	
	class Inner {
		int x = 4;
		void show() {
			System.out.println("show:"+Outer.this.x);
		}
	}
	
	public void function() {
		new Inner().show();       //new一個子類的匿名對象
	}
}
運行結果一樣。

定義在函數中的內部類(局部位置的內部類):
class InnerClassDemo {
	public static void main(String[] args){
		new Outer().run(6);  //new一個匿名對象
	}
}

class Outer {
	int x = 3;
	
	public void run(final int a){
		final int y = 5;       //內部類若想訪問局部變量,此變量必須被 final修飾,a和y均被final修飾
		
		class Inner {
			int z = 4;
			void show() {
				System.out.println("show y:"+y+" show a:"+a);  //可直接訪問局部變量 a和y
			}
		}
		
		new Inner().show();       //new一個匿名對象
	}
}
運行結果:


4、靜態內部類

當內部類被static修飾後,只能直接訪問外部類中的static成員。出現訪問侷限。

在外部其他類中,如何直接訪問static內部類的非靜態成員呢?

new Outer.Inner().show();

在外部其他類中,如何直接訪問static內部類的靜態成員呢?

Outer.Inner.show();

注意:當內部類中定義了靜態成員,該內部類必須是static的。


直接訪問static內部類的非靜態成員:

class InnerClassDemo {
	public static void main(String[] args){
		new Outer.Inner().show();  //訪問內部類的非靜態成員.show()方法爲非靜態
	}
}

class Outer {
	static int x = 3;
		
	static class Inner {
		static int y = 4;
		void show() {
			System.out.println("show x:"+Outer.x+" show y:"+Inner.y);
		}
	}
}
結果:



直接訪問static內部類的靜態成員:

class InnerClassDemo {
	public static void main(String[] args){
		Outer.Inner.show();     //訪問內部類的靜態成員,全爲靜態;
	}
}

class Outer {
	static int x = 3;
		
	static class Inner {
		static int y = 4;
		static void show() {
			System.out.println("show x:"+Outer.x+" show y:"+Inner.y);
		}
	}
}
結果:



5、內部類定義原則

a) 當描述事物時,事物的內部還有事物,該事物用內部類來描述。

b) 因爲內部事物在使用外部事物的內容。

6、匿名對象

匿名對象:new的一個對象直接調用其方法,而不給此對象命名

如: new Outer().function();

爲,直接創建了一個Outer類型的對象,並直接調用此對象的function()方法。此過程中沒有給此對象命名。

7、匿名內部類

a) 匿名內部類就是內部類的簡寫格式。

b) 定義匿名內部類的前提:內部類必須是繼承一個類或實現一個接口。

c) 匿名內部類的格式:new 父類或接口(){定義子類的內容};

d) 其實匿名內部類就是一個匿名子類對象,而這個對象有點胖,可以理解爲帶內容的對象。

e) 匿名內部類中,定義的方法最好不要超過3個。


匿名內部類代碼示例:

class InnerClassDemo {
	public static void main(String[] args){
		new Outer().function();     //new一個匿名對象
	}
}

abstract class AbsDemo{
	abstract void show();
}

class Outer {
	int x = 3;

	public void function(){              
		new AbsDemo(){     //匿名內部類,是AbsDemo類的子類對象
			void show(){   //重寫父類AbsDemo中的抽象方法
				System.out.println("x = :"+x);
			}
			void abc(){    //子類中建立一個子類方法abc()
				System.out.println("abc");
			}
		}.show();   //直接調用子類對象的show()函數
	}
}
結果:



父類引用指向匿名內部類,匿名內部類其實是個子類(多態情形)

class InnerClassDemo {
	public static void main(String[] args){
		new Outer().function();     //new一個匿名對象
	}
}

abstract class AbsDemo{
	abstract void show();
}

class Outer {
	int x = 3;

	public void function(){              
		AbsDemo b = new AbsDemo(){     //多態,父類引用指向子類對象
			void show(){               //重寫父類AbsDemo中的抽象方法
				System.out.println("x = :"+x);
			}
			void abc(){                //子類中建立一個子類方法abc()
				System.out.println("abc");
			}
		};
		b.show(); 
		//b.abc();  多態錯誤,父類中沒有abc()方法,編譯時出錯
	}
}



發佈了39 篇原創文章 · 獲贊 7 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章