1. 程式人生 > >Java的知識點14——內部類的概念、內部類的分類

Java的知識點14——內部類的概念、內部類的分類

內部類的概念

 一般情況,我們把類定義成獨立的單元。有些情況下,我們把一個類放在另一個類的內部定義,稱為內部類(innerclasses)。

內部類可以使用public、default、protected 、private以及static修飾

外部頂級類(我們以前接觸的類)只能使用public和default修飾

注:內部類只是一個編譯時概念,一旦我們編譯成功,就會成為完全不同的兩個類。對於一個名為Outer的外部類和其內部定義的名為Inner的內部類。編譯完成後會出現Outer.class和Outer$Inner.class兩個類的位元組碼檔案。所以內部類是相對獨立的一種存在,其成員變數/方法名可以和外部類的相同。

內部類介紹

package cn.dym05;

class Outer{
	private int age=10;
	public void show() {
		System.out.println(age);
	}
	public class Inner{
		//內部類中可以宣告與外部類同名的屬性與方法
		private int age=20;
		public void show() {
			System.out.println(age);
		}
	}
}

public class Test01 {
	public static void main(String[] args) {
		
	}
}

內部類的作用:

      1. 內部類提供了更好的封裝只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問

      2. 內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類的成員但外部類不能訪問內部類的內部屬性

      3. 介面只是解決了多重繼承的部分問題,而內部類使得多重繼承的解決方案變得更加完整

內部類的使用場合:

      1. 由於內部類提供了更好的封裝特性,並且可以很方便的訪問外部類的屬性。所以,在只為外部類提供服務的情況下可以優先考慮使用內部類。

      2.  使用內部類間接實現多繼承:每個內部類都能獨立地繼承一個類或者實現某些介面,所以無論外部類是否已經繼承了某個類或者實現了某些介面,對於內部類沒有任何影響。

內部類的分類

 在Java中內部類主要分為成員內部類(非靜態內部類、靜態內部類)、匿名內部類區域性內部類

成員內部類(可以使用private、default、protected、public任意進行修飾。 類檔案:外部類$內部類.class)

非靜態內部類(外部類裡使用非靜態內部類和平時使用其他類沒什麼不同)

      i. 非靜態內部類必須寄存在一個外部類物件裡。因此,如果有一個非靜態內部類物件那麼一定存在對應的外部類物件。非靜態內部類物件單獨屬於外部類的某個物件。

      ii. 非靜態內部類可以直接訪問外部類的成員,但是外部類不能直接訪問非靜態內部類成員。

      iii. 非靜態內部類不能有靜態方法、靜態屬性和靜態初始化塊

      iv. 外部類的靜態方法、靜態程式碼塊不能訪問非靜態內部類,包括不能使用非靜態內部類定義變數、建立例項。

成員變數訪問要點:

        1. 內部類裡方法的區域性變數:變數名。

        2. 內部類屬性this.變數名

        3. 外部類屬性外部類名.this.變數名

內部類的訪問

package cn.dym05;

class Outer{
	private int age=10;
	
	class Inner{
		int age=20;
		public void show() {
			int age=30;
			System.out.println("內部類方法裡的區域性變數age:"+age); //30
			System.out.println("內部類的成員變數age:"+this.age);//20
			System.out.println("外部類的成員變數age:"+Outer.this.age); //10	
		}
	}
}

public class Test02 {
	public static void main(String [] args) {
		//先建立外部類例項,然後使用該外部類例項建立內部類例項
		Outer.Inner inner=new Outer().new Inner();
		inner.show();
		Outer outer=new Outer();
		Outer.Inner inn=outer.new Inner();
		inn.show();
	}
}

//先建立外部類例項,然後使用該外部類例項建立內部類例項 

靜態內部類

 使用要點:

       1. 當一個靜態內部類物件存在,並不一定存在對應的外部類物件。 因此,靜態內部類的例項方法不能直接訪問外部類的例項方法。

       2. 靜態內部類看做外部類的一個靜態成員。 因此,外部類的方法中可以通過:“靜態內部類.名字”的方式訪問靜態內部類的靜態成員,通過 new 靜態內部類()訪問靜態內部類的例項。

靜態內部類的訪問

靜態內部類相當於外部類的一個靜態成員,通過 new 外部類名.內部類名() 來建立內部類物件

package cn.dym05;

class Outer{
	private int age=10;
	
	static class Inner{
		int age=20;
		public void show() {
			int age=30;
			System.out.println("內部類方法裡的區域性變數age:"+age); //30
			System.out.println("內部類的成員變數age:"+this.age);//20
			//System.out.println("外部類的成員變數age:"+Outer.this.age); //不能訪問	
		}
	}
}

public class Test02 {
	public static void main(String [] args) {
		//通過 new 外部類名.內部類名() 來建立內部類物件
		Outer.Inner inner=new Outer.Inner();
		inner.show();
		
	}
}

匿名內部類

      匿名內部類適合那種只需要使用一次的類。比如:鍵盤監聽操作等等

注:1. 匿名內部類沒有訪問修飾符

       2. 匿名內部類沒有構造方法。因為它連名字都沒有那又何來構造方法呢。

區域性內部類

還有一種內部類,它是定義在方法內部的,作用域只限於本方法,稱為區域性內部類

方法中的內部類

package cn.dym05;

public class Test04 {
	public void show() {
		//作用域僅限於該方法
		class Inner{
			public void fun() {
				System.out.println("helloworld");
			}
		}
		new Inner().fun();
	}
	public static void main(String[] args) {
		new Test04().show();
	}
}