1. 程式人生 > >Java基礎 -- 內部類

Java基礎 -- 內部類

ole object c tin public 需要 ott sequence 對象 是否

可以將一個類的定義放在另一個類的內部定義,這就是內部類。

內部類是一個非常有用的特性。因為它允許你把一些邏輯相關的類組織在一起,並控制位於內部的類的可視性。

一 創建內部類

創建內部類的方式:把類的定義置於外圍類的裏面:

public class Parcel1 {
	class Contents{
		private int i = 11;
		public int value() {return i;}
	}
	
	class  Destination{
		private String label;
		Destination(String whereTo){
			label = whereTo;
		}
		
		String readLable() {return label;}
	}
	
	public void ship(String dest) {
		Contents c = new Contents();
		Destination d = new Destination(dest);
		System.out.println(d.readLable());
	}
	
	public static void main(String[] args) {
		Parcell p = new Parcel1();
		p.ship("Zhengy");
	}

}

在我們在ship()方法裏面使用內部類的時候,與使用普通類沒有什麽區別,在這裏,實際的區別就是內部類的定義是嵌套在Parcel1中。

下面我們嘗試在類中定義一個方法,該方法返回一個指向內部類的醫用。

//內部類
public class Parcel2 {
	class Contents{
		private int i = 11;
		public int value() {return i;}
	}
	
	class  Destination{
		private String label;
		Destination(String whereTo){
			label = whereTo;
		}
		
		String readLable() {return label;}
	}
	
	
	public Destination to(String s) {
		return new Destination(s);
	}
	
	public Contents contents() {
		return new Contents();
	}
	
	
	public void ship(String dest) {
		Contents c = new Contents();
		Destination d = new Destination(dest);
		System.out.println(d.readLable());
	}
	
	public static void main(String[] args) {
		Parcel2 p = new Parcel2();
		p.ship("南京");
		
		Parcel2 q = new Parcel2();
		Parcel2.Destination d = q.to("北京");
		Parcel2.Contents c = q.contents();
	}

}

如果想在類外創建某個內部類的對象,必須像main()方法那樣,具體指明這個對象的類型:OuterClassName.InnerClassName。

二 內部類訪問外部類成員

當創建一個內部類的對象時,此對象與創建它的外圍對象之間就有了一種聯系,所以它能夠訪問其外圍對象的所有成員,而不需要任何特殊條件。下面的例子說明了這一點:

///鏈接到外部類

//類似叠代器
interface Selector{
	boolean end();    //判斷序列是否叠代結束
	Object current();  //獲取當前元素
	void next();       //下一個元素
}

//序列類(外圍類)
public class Sequence {
	//數組用於保存元素
	private Object[] items;
	
	//當前追加索引
	private int next = 0;
	public Sequence(int size) {items = new Object[size];}
	
	//向數組追加元素
	public void add(Object x) {
		if(next < items.length)
			items[next++] = x;
	}
	
	
	//內部類:叠代器(可以訪問外圍對象的所有成員),這裏用來叠代序列中所有元素
	private class SequenceSelector implements Selector{
		private int  i = 0;
		public boolean end() {return i == items.length;}
		public Object current() {return items[i];}
		public void next() {
			if(i < items.length)
				i++;
		}
	}
	
	//創建叠代器對象
	public Selector selector() {
		return new SequenceSelector();
	}
	
	public static void main(String[] args) {
		Sequence sequence = new Sequence(10);
		for(int i=0;i<10;i++) {
			sequence.add(Integer.toString(i));
		}
		
		Selector selector = sequence.selector();
		while(!selector.end()) {
			System.out.print(selector.current() + "  ");
			selector.next();
		}
		
	}
}

輸出結果如下:

0  1  2  3  4  5  6  7  8  9  

上面演示了一個:"叠代器"設計模式的例子。

三 使用.this和.new

在內部類中如果需要創建對外部類對象的引用,可以使用外部類的名字後面跟著.this。下面演示如何使用.this:

///使用.this
public class DotThis {
	void f() {
		System.out.println("DotThis.f()");
	}
	
	//內部類
	public class Inner{
		public DotThis outer() {
			return DotThis.this;
		}
	}
	
	public Inner inner() {
		return new Inner();
	}
	
	public static void main(String[] args) {
		DotThis dt = new DotThis();
		DotThis.Inner dti = dt.inner();
		dti.outer().f();
	}
}

輸出如下:

DotThis.f()

有時你可能想要告知某些其他對象,去創建其某個內部類的對象,要實現此目的。你必須在new 表達式中提供對其外部類對象的引用,這是需要使用.new語法,如下:

///.new

public class DotNew {
	public class Inner{
		public void f(){
			System.out.print("test");
		}
	}
	public static void main(String[] args) {
		DotNew dn = new DotNew();
		DotNew.Inner dni = dn.new Inner();	
		dni.f();
	}
}

想要直接創建內部類的對象,不可以直接引用外部類的名字DotNew,而是必須使用外部類的對象來創建該內部類對象,就像上面的程序中所看到的那樣。在擁有外部類對象之前是不可能創建內部類對象的,這是因為內部類對象會暗暗地連接到創建它的外部類對象上。

但是,如果創建的是嵌套類(靜態內部類),那麽它就不需要對外部類對象的引用。

四 內部類與向上轉型

Java基礎 -- 內部類