1. 程式人生 > >內部類瞭解麼?簡單介紹下[中高]

內部類瞭解麼?簡單介紹下[中高]

一定義:
放在一個類的內部類我們就叫內部類。

二作用
1.內部類可以很好的實現隱藏
一般的非內部類,是不允許有 private 與 protected 許可權的,但內部類可以
2.內部類擁有外部類的所有元素的訪問許可權
3. 可以實現多重繼承(重點說下這個)
三 分類
1.靜態內部類:作為類的靜態成員,存在於某個類的內部。 (java.util.Collections,ConcurrentHashMap)
2.成員內部類:作為類的成員,存在於某個類的內部。
3.區域性內部類:存在於某個方法的內部。
4.匿名內部類:存在於某個類的內部,但是無類名的類。

參考程式碼: inner、Outter

/**
 * 靜態內部類雖然是外部類的成員,但是在未建立外部類的物件的情況下,可以直接建立靜態內部類的物件。
 * 靜態內部類可以引用外部類的靜態成員變數和靜態方法,但不能引用外部類的普通成員。
 */
public class Outter {
	static String staticVar = "staitc var靜態變數";
	String instinceVar = "普通成員變數";
	static {
		System.out.println("靜態程式碼塊執行:" + staticVar);
		System.out.println("===========================");
	}

	static void test() {
		System.out.println("外部類的靜態方法執行");
	}

	static class Inner {
		static {
			// 內部類的靜態程式碼塊在外部類初始化的時候,不會被初始化
			System.out.println("靜態內部類的靜態程式碼塊");
		}
		public void test2() {
			System.out.println("staticVar的值為:" + staticVar);// 直接引用外部類的靜態成員變數
			test();// 直接引用外部類的靜態方法
			// System.out.println(instinceVar); // 試圖引用外部類的非靜態成員變數,不能通過編譯
			System.out.println("靜態內部類的方法執行");
		}
	}

	public static void main(String[] args) {
		new Outter();
		Inner in = new Inner();// 靜態內部類的物件可以直接建立,無需先建立外部類的物件
		in.test2();
	}
}
/**
 * 成員內部類可以呼叫外部類的所有成員,但只有在建立了外部類的物件後,才能呼叫外部的成員。
 * 它與一個例項繫結在了一起,不可以定義靜態的屬性和方法
 *
 */
public class Outter1 {
	static int a = 1;
	int b = 0;

	public static void test1() {
		System.out.println("外部類的靜態方法");
	}

	public void test2() {
		System.out.println("外部類的非靜態方法");
	}

	class Inner {
		// static String aa; // 不可以定義靜態的屬性和方法
		public void test() {
			System.out.println("在成員內部類的方法中");
			test1();// 呼叫外部類的靜態方法
			test2();// 呼叫外部類的非靜態方法
			System.out.println("訪問外部類的靜態成員變數和非靜態成員變數:" + (a + b));// 訪問外部類的靜態成員變數和非靜態成員變數
		}
	}

	public static void main(String[] args) {
		// Inner in = new Inner(); // 成員內部類的物件不能直接建立,編譯會報錯
		Outter1 out = new Outter1(); // 先建立外部類的物件
		Inner in = out.new Inner(); // 注意:!成員內部類的物件必須通過外部類的物件建立
		in.test(); // 呼叫內部類的方法
	}
}
/**
 * 區域性內部類只能在方法內部中使用,一旦方法執行完畢,區域性內部類就會從記憶體中刪除。
  必須注意:如果區域性內部類中要使用他所在方法中的區域性變數,那麼就需要將這個區域性變數定義為final的。
 *
 */
public class Outter2 {
	
	int a = 10;
	
	public void test() {
		final int c = 5;
		System.out.println("執行外部類的方法");
		class Inner {
			int b = 20;
			void test1() {
				System.out.println("執行區域性內部類的方法,b:" + b);
				/**
				 * 注意:如果區域性內部類中要使用他所在方法中的區域性變數,
				 * 那麼就需要將這個區域性變數定義為final的。
				 */
				System.out.println("呼叫方法的區域性變數final,c:" + c);
			}
		}
		Inner inner = new Inner();
		inner.test1();
	}

	public static void main(String[] args) {
		Outter2 outter = new Outter2();
		outter.test();
	}
}
/**
 *   匿名內部類的定義與物件的建立合併在一起,匿名內部類一般通過如下形式定義,並且在定義的同時進行物件的例項化。
     new 類或者介面的名字(){
        //匿名內部類的主體,大括號中是匿名內部類的主體,這個主體就是類或者介面的實現,
         * 如果是類,那麼匿名內部類是該類的子類,
         * 如果是介面,匿名內部類需要完成介面的實現。
     }
 *
 */
public class Outter3 {
	public static void main(String[] args) {
		Person person = new Person();
		person.show(new Message() {
			public void show() {
				System.out.println("在匿名內部類中");
			}
		});

		// 比較經典的建立執行緒的一種方式
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("new Thread");// 輸出:new Thread 2
			}
		});
		t2.start();

	}
}

class Person {
	public void show(Message message) {
		message.show();
	}
}

class Message {
	public void show() {
		System.out.println("在Message類中");
	}
}

// 測試通過內部類實現多繼承等
class Example1 {
	public String name() {
		return "Example1 name()";
	}
}

class Example2 {
	public int age() {
		return 1;
	}
}

class Example3 {
	public int age() {
		return 1;
	}
}

class InnerExtendExample {
	 private String id = "id";
	 private static String name = "name";
	 //一般的非內部類,是不允許有 private 與protected許可權的,
	 // 但內部類可以,所以我們能通過內部類來隱藏我們的資訊。
	 private class test1 extends Example1 {
		public String name() {
			System.out.println("呼叫外部類的成員變數,id:" + id);
			System.out.println("呼叫外部類的靜態變數,name:" + name);
			return super.name();
		}
	}

	private class test2 extends Example2 {
		public int age() {
			return super.age();
		}
	}

	public String name() {
		return new test1().name();
	}

	public int age() {
		return new test2().age();
	}

	public static void main(String args[]) {
		InnerExtendExample ie = new InnerExtendExample();
		System.out.println("獲得父類Example1的方法,姓名:" + ie.name() );
		System.out.println("獲得父類Example2的方法,年齡:" + ie.age());
	}
	
}