1. 程式人生 > >Java學習筆記之內部類

Java學習筆記之內部類

//內部類: 將一個類定義在另一個類的裡面,對裡面那個類就稱為內部類.
class Outer
{
	private int num = 3;
	class Inner //它想訪問Outer中的num, 如果在外面就需要建立一個物件,然後通過公開的介面訪問,但是現在Outer內部, 就可以直接訪問了.這樣方便
	{
		void show()
		{
			System.out.println("show run..." + num);
		}
	}
	//如果現在想訪問Inner就需要這樣
	public void method()
	{
		Inner in = new Inner();
		in.show();
	}
	//內部類由於在內部, 相當於定義在了成員的位置上, 所以可以用成員修飾符, 如:
	//private class Test{}
	static class Inner
	{
		static void function()
		{
			System.out.println("function run......"+num);
		}
	}
}
/*
內部類訪問特點:
1. 內部類可以直接訪問外部類中的成員.
2. 外部類要訪問內部類, 必須建立內部類的物件.


一般用於類的設計.


分析事物時, 發現該事物描述中還有事物,而且這個事物還在訪問被描述事物的內容.
這時就把還有的事物定義成內部類來描述.


*/
class InnerClassDemo
{
	public static void main(String[] args)
	{
		Outer out  = new Outer();
		out.method();
		//直接訪問外部類中的內部類中的成員.
		Outer.Inner in = new Oouter().new Inner();
		in.show();
		//如果內部類是靜態, 那就相當於一個外部類了.
		Outer.Inner in = new Outer.Inner();
		in.show();
		//如果內部類是靜態的,成員是靜態的.
		Outer.Inner.function();


		//如果內部類中定義了靜態成員,該內部類也必須是靜態的.


	}
}


/***********************************************************************************/
//細節
class Outer
{
	int num = 3;
	class Inner
	{
		int num = 4;
		void show()
		{
			int num = 5;
			System.out.println(num);//5
			System.out.println(this.num);//4
			System.out.println(Outer.this.num);//3
		}
	}
	void method()
	{
		new Inner().show();
	}
}


class InnerClassDemo2
{
	public static void main(String[] args)
	{
		new Outer().method();
	}
}
/*
為什麼內部類能直接訪問外部類中成員呢?
那是因為內部類持有了外部類的引用-----外部類名.this
*/


/**********************************************************************/
//內部類可以存放在區域性位置上
class Outer
{
	int num = 3;
	Object method()
	{
		final int x = 9;
		class Inner
		{
			void show()
			{
				System.out.println("show..."+num);
			}
		}
		Object in = new Inner();
		return in;//0x0045
	}
}
class InnerClassDemo3
{
	public static void main(String[] args)
	{
		Outer out = new Outer();
		Object obj = out.method();//0x0045
	}
}
/*
內部類在區域性位置上只能訪問區域性中被final修飾的區域性變數.
*/


/*********************************************************************/
/*
匿名內部類, 就是內部類的簡寫格式.
必須有前提:
	內部類必須繼承或者實現一個外部類或者介面.


匿名內部類: 其實就是一個匿名子類物件.


格式: new 父類or介面(){子類內容}
*/


abstract class Demo
{
	abstract void show();
}


class Outer
{
	int num = 4;
	class Inner extends Demo //這是正常情況
	{
		void show()
		{
			System.out.println("show...."+num);
		}
	}
	public void method()
	{
		new Demo()//這個就叫匿名內部類
		{
			void show()
			{
				System.out.println("show...."+num);
			}
		}
	}
}


/**********************************************************************/
//匿名內部類的應用
interface Inter
{
	void show1();
	void show2();
}


class Outer
{
	public void method()
	{
		new Inter()
		{
			public void show1()
			{}
			public void show2()
			{}
		}.show1();  //呼叫了show1的方法, 相當於  new Inner().show1();
		
		//或者用下面的方法
		Inter in = new Inter()
		{
			public void show1()
			{}
			public void show2()
			{}
		}
		in.show1();
		in.show2();
	}
}
/*
通常的使用場景之一:
當函式引數是介面型別時,而且介面中的方法不超過三個.
可以用匿名內部類作為實際引數進行傳遞.
*/
class InnerClassDemo5
{
	public static void main(String[] args)
	{
		show(new InterImpl());
	}
	public static void show(Inter in)
	{
		in.show1();
		in.show2();
	}
}
class InterImpl implements Inter
{
	
}


/************************************************************/
//物件的初始化過程
class Fu
{
	int num = 9;
	{
		System.out.println("Fu");
	}


	Fu()
	{
		super();
		//顯示初始化
		//構造程式碼塊初始化
		show();
	}
	void show()
	{
		System.out.println("fu show..."+num); //被覆蓋,執行子類
	}
}
class Zi extends Fu
{
	int num = 8;
	{
		System.out.println("Zi");
	}
	Zi()
	{
		super();
		//顯示初始化
		//構造程式碼塊初始化
		show();
	}
	void show()
	{
		System.out.println("zi show..."+num);
	}
}


class Inner
{
	public static void main(String[] args)
	{
		new Zi();
	}
}
/*
結果為:
Fu
zi show...0
Zi
zi show...8
*/