Thinking in java 之:內部類

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

普通內部類:

public class InnerDemo {
	private Object[] item = { 2, 12, 3 };

	public void print() {
		System.out.println("aaaa");
	}

	public static void main(String[] args) {
		InnerDemo id = new InnerDemo();
		//如果想從外部類的非靜態方法之外的任意位置指明內部類類型OuterClassName.InnerClassName
		InnerDemo.SelectorImpl selectorImpl = id.selector();
		System.out.println(selectorImpl.end());
		selectorImpl.init();
	}
	class SelectorImpl implements Selector {
		private int i = 0;

		public void init() {
			InnerDemo id2 = new InnerDemo();
			id2.print();
		}
		public boolean end() {
			// 可以訪問外部內中的所有成員
			return i == item.length;
		}
	}

	public SelectorImpl selector() {
		return new SelectorImpl();
	}
}

interface Selector {
	boolean end();
}

結論如下:

1.如果想從外部類的非靜態方法之外的任意位置指明內部類類型OuterClassName.InnerClassName。

2.當生成一個內部類的對象時,此對象與製造它的外圍對象之間就有了一種聯繫,所以它能訪問其外圍對象的所有成員,而不需要任何特殊條件。此外,內部類還擁有其外圍類的所有元素的訪問權。

局部內部類:

public class LocalInner {
	public Destination destination(String s) {
		class PDestination implements Destination {
			private String label;

			private PDestination(String whereTo) {
				label = whereTo;
			}
		}
		return new PDestination(s);
	}

	public static void main(String[] args) {
		LocalInner li = new LocalInner();
		li.destination("Tokyo");// 這裏向上轉型,返回的是Destination的引用
	}
}

interface Destination {
	
}
匿名內部類:

public class Dog {


	public interface Pet {
		public void beFriendly();
		public void play();
	}

	public static void main(String[] args) {
		Pet dog = new Pet() {
			public void beFriendly() {
				System.out.println("hello");
			}

			public void play() {
				System.out.println("play");
			}
		};
		dog.beFriendly();
		dog.play();

	}
}
接口不能new,但是可以以匿名內部類的形式在{}中實現接口中的方法。

下面有兩種匿名內部類的寫法:

public class Test {
	 public static void main(String[] args) {
		// 這裏new Thread() {}是一個繼承Thread類的匿名內部類
		java.lang.Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				System.out.println("ssss");
			}
		});
		}
}
public class Test {
	public static void main(String[] args) {
		// 在虛擬機關閉的時候進行一些操作,會在addShutdownHook方法裏面調用start方法,
		// new Runnable() {}是一個實現Runnable接口的匿名內部類,然後作爲Thread構造器的參數傳入
		java.lang.Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("ssss");
			}
		}));
	}
}

靜態嵌套類:

public class Outer {
	private int y = 2;
	private static int x = 1;

	static class Nest {

		void print() {
			System.out.println(y); // 編譯報錯,只能訪問靜態變量
			System.out.println("Nest " + x);
		}
	}

	public static void main(String[] args) {
		Outer.Nest nest = new Outer.Nest();
		nest.print();
	}
}
與一般內部類不同,在靜態代碼中不能夠使用this操作,所以在靜態內部類中只可以訪問外部類的靜態變量和靜態方法,而不能訪問實例成員。使用靜態內部類的目的和使用內部類相同。如果一個內部類不依賴於其外部類的實例變量,或與實例變量無關,則選擇應用靜態內部類。

爲何要用內部類?

1. 內部類一般只爲其外部類使用;

2. 內部類提供了某種進入外部類的窗戶;

3. 也是最吸引人的原因,每個內部類都能獨立地繼承一個接口,而無論外部類是否已經繼承了某個接口。因此,內部類使多重繼承的解決方案變得更加完整。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章