1. 程式人生 > 其它 >java基礎第二十四課---java內部類

java基礎第二十四課---java內部類

技術標籤:java基礎java

內部類是一個定義在另一個類中的類。那為什麼要使用內部類呢?其主要原因有以下三點

1.內部類方法可以訪問該類定義所在的作用域中的資料,包括私有資料
2.內部類可以對統一包中的其他資料隱藏起來,增強面向物件的封裝性
3.當想定義一個回撥函式且不想編寫大量程式碼時,使用匿名內部類比較便捷

藉助於內部類可以實現類似於多繼承的作用
public class Person {
	//人在出生的時候選擇性別
	private String[] sex = {"男性","女性"};

	class Xiaoming{
		private
String xiaoming_sex; private String showSex() { // TODO Auto-generated method stub xiaoming_sex = sex[1]; return xiaoming_sex; } } //在外部類當中定義一個方法展示小明的性別 private void show_XiaoMing_sex() { // TODO Auto-generated method stub Xiaoming xiaoming = new Xiaoming(); System.out.println(xiaoming.
showSex()); } public static void main(String[] args) { Person person = new Person(); person.show_XiaoMing_sex(); } }

為了能夠執行程式,內部類的物件總有一個隱式引用,他指向了建立他的外部類物件
在這裡插入圖片描述
內部類物件擁有一個對外圍外部類物件的引用
請注意一下,outer不是java關鍵字,我們只是用它說明內部類中的機制

內部類的幾種表現形式

一、成員式內部類

定義:成員式內部類如同外部類的一個普通方法
成員式內部類有以下特性:

1.持有父類引用,故可以訪問父類任何訪問許可權的變數、方法

2.非靜態內部類中不能宣告static成員

上邊的程式碼就是成員式內部類
如何訪問成員式內部類:

外部類名.內部類名 變數名 = new 外部類名().new 內部類名();
Person.Xiaoming xiaoming = new Person().new Xiaoming();

二、區域性內部類

1.什麼是區域性內部類
定義:區域性內部類就是定義在程式碼塊、方法體內、作用域({})內的類。

public class Person {
	//人在出生的時候選擇性別
	private static String[] sex = {"男性","女性"};
	
	public void print() {
		class People {
			private String name = "xiaoming";
			public void print() {
				System.out.println("hello world");
			}
		}
		People people = new People();
		people.print();
	}
}

測試:

public class Test {
	public static void main(String[] args) {
		
		Person person = new Person();
		person.print();
	}
}

區域性內部類有以下特性:

1.不能使用public、private、protected、static等這些修飾符
2.區域性內部類只能在當前方方法中使用,作用域範圍僅限於當前方法中
3.區域性內部類和成員內部類一樣,不能擁有靜態成員,但可以訪問外部成員的所有變數
4.區域性內部類訪問的區域性變數必須使用fianl修飾,在jdk8中自動隱士的加上了final,但是依然是常量,值不能被改變(不知道為什麼)

為什麼不推薦使用區域性內部類?

如果當前方法不是main方法,那麼當前方法呼叫完畢之後,當前方法的棧幀就會被銷燬,方法內部的區域性變數的空間也會被銷燬。

三、匿名內部類

定義:匿名內部類是區域性內部類的一種特殊形式,是一個沒有名稱的內部類。

注意:匿名內部類必須繼承一個父類或者一個介面

1.匿名內部類的由來

首先新建一個抽象類

public abstract class Person {
	 void sleep() {}
}

繼承這個抽象類並實現它的方法

public class Student  extends Person{
	
	private void sleep() {
		// TODO Auto-generated method stub
		System.out.println("學生在吃");
	}
	
}

最後呼叫

public class Demo3 {
	public static void main(String[] args) {
		Person person = new Student();
		person.sleep();
	}
}

可以看到我們在這裡使用了多型的思想,將student類向上轉型到person類當中,這裡我們只是用了一次student類,把我們有沒有什麼辦法跳過這個student類來實現person當中的方法呢?

我們進行相關的改動後:

public class Demo3 {
	public static void main(String[] args) {
		new Person() {
			void sleep() {
				System.out.println("學生正在睡覺。。。。");
			};
		}.sleep();
	}
}

可以看到繼承了person類,並在()中實現了響應的抽象方法。
最後這是我們重用的匿名內部類的方式:

public class Person{
	public static void main(String[] args) {
		new Thread() {
			@Override
			public void run() {
				for(int i=0;i<10;i++) {//3.將要執行的程式碼,寫在run方法中
					System.out.println("aaaaaaa");
				}

			}
		}.start();
	}
}

最常用的就是利用匿名內部類的方式來開闢一個新的執行緒.

四、靜態內部類

定義:有時候,使用內部類只是為了把一個類隱藏在另一個類的內部,並不需要內部類引用外圍類物件。為此,我們可以將內部類宣告為static,以便取消產生的引用。

特點:

1.在建立外部類例項的時候不必建立外部類例項。
OuterClass.InnerClass in = new OuterClass.InnerClass();
2.靜態內部類可以直接訪問訪問外部類的靜態成員
3.在靜態內部類可以定義靜態和非靜態的成員
4.外部類可以通過完整的類名直接訪問靜態內部類的靜態成員。

public class OuterClass {
	String name = "Outer.name";
	static String name2 = "Outer.name2";
	static class InnerClass{
		private void printNmae() {
			// TODO Auto-generated method stub
			System.out.println(name2);
			System.out.println(new OuterClass().name);
		}
	}
}

有道雲筆記更精彩哦~
文件:第二十三課—java 內部類.note