1. 程式人生 > >第9天 面向物件

第9天 面向物件

第1章 面向物件 1.1 理解什麼是面向過程、面向物件 面向過程與面向物件都是我們程式設計中,編寫程式的一種思維方式。  面向過程的程式設計方式,是遇到一件事時,思考“我該怎麼做”,然後一步步實現的過程。 例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向過程的程式設計方式會思考“打掃衛生我該怎麼做,然後一件件的完成”,最後把公司衛生打掃乾淨了。  面向物件的程式設計方式,是遇到一件事時,思考“我該讓誰來做”,然後那個“誰”就是物件,他要怎麼做這件事是他自己的事,反正最後一群物件合力能把事就好就行了。 例如,公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向物件的程式設計方式會思考“我該讓誰來做,如小明擦玻璃、讓小麗掃地、讓小郭拖地、讓小強倒垃圾等”,這裡的“小明、小麗、小郭、小強”就是物件,他們要打掃衛生,怎麼打掃是他們自己的事,反正最後一群物件合力把公司衛生打掃乾淨了。 1.2 面向物件舉例  買電腦(組裝機) 先使用面向過程說明買電腦這件事:假如我們需要買組裝電腦,這時首先會在網上查詢具體每一個硬體的引數和報價。然後會去電腦城進行多家詢價,接著詢價結束後回家根據具體的結果分析出自己比較滿意的哪家報價,接著會到這家店裡進行組裝,組裝時還需要進行現場監督,組裝完成安裝相應的系統,然後電腦抱回家。 分析上述整個過程大體分一下幾步:上網查詢引數和報價、電腦城詢價、現場安裝和監督、抱電腦回家。在整個過程中我們參與了每一個細節,並且會感覺相當累。 使用面向物件說明買電腦這件事:假如我們需要買組裝機,這時應該找一個懂電腦硬體的人,讓他幫我們檢視引數和報價,並進行詢價和殺價,以及現場組裝監督。而我們自己並不需要親歷親為具體怎麼做,只要告訴這個人我們想要的具體需求即可。 分析上述整個過程,發現瞬間變的十分輕鬆,只要找到懂電腦硬體的這個人,我們的問題都可以解決。並且在這個過程中我們不用那麼辛苦。 1.3 面向物件思維方式的好處 通過生活中的真實場景使用面向物件分析完之後,我們開始分析面向過程和麵向物件的差異做出總結:  面向物件思維方式是一種更符合人們思考習慣的思想  面向過程思維方式中更多的體現的是執行者(自己做事情),面向物件中更多的體現是指揮者(指揮物件做事情)。  面向物件思維方式將複雜的問題簡單化。  世界萬物皆物件

第2章 類與物件 2.1 物件在需求中的使用 對面向物件有了瞭解之後,我們來說說在具體問題中如何使用面向物件去分析問題,和如何使用面向物件。 我們把大象裝冰箱為例進行分析。 在針對具體的需求,可以使用名詞提煉的辦法進行分析,尋找具體的物件。 需求:把大象裝冰箱裡 物件:大象、冰箱 分三步: 1、開啟冰箱門 2、將大象裝進去 3、關閉冰箱門 分析發現開啟、裝、關閉都是冰箱的功能。即冰箱物件具備如下功能: 冰箱開啟 冰箱儲存 冰箱關閉 用虛擬碼描述,上述需求中有兩個具體的事物 大象 和 冰箱 描述大象: class 大象 { } 描述冰箱 class冰箱 { void 開啟(){} void 儲存(大象){} void 關閉(){} } 當把具體的事物描述清楚之後,需要使用這些具體的事物,Java使用具體的事物,需要通過new關鍵字來建立這個事物的具體例項。
使用物件: 1、建立冰箱的物件

冰箱 bx = new 冰箱(); 

2、呼叫冰箱的功能

物件.功能();
bx.開啟();
bx.儲存(new 大象());
bx.關閉();

 總結: 1、先按照名詞提煉問題領域中的物件 2、對物件進行描述,其實就是在明確物件中應該具備的屬性和功能 3、通過new的方式就可以建立該事物的具體物件 4、通過該物件呼叫它以後的功能。 2.2 物件在程式碼中的體現 在分析現實生活中的事物時發現,這些事物都有其具體的特點和功能,這些特點和功能就組成了這個特殊的事物。 描述小汽車。 分析: 事物的特點(屬性): 顏色。 輪胎個數。 事物的(功能): 執行。

發現:事物其實就是由特點(屬性)和行為(功能)組成的。 可以簡單理解:屬性就是數值,其實就是變數;行為就是功能,就是方法。 小汽車 { 顏色; 輪胎個數; 執行() { } } 通過計算機語言Java來描述這個事物。  定義類的格式

public class 類名 {
	//可編寫0至n個屬性
    資料型別 變數名1;
    資料型別 變數名2;
	
	//可編寫0至n個方法
	修飾符 返回值型別 方法名(引數){
		執行語句;
}
}

 汽車類

public class Car {
	String color;
	int number;

	void run() {
		System.out.println(color + ":" + number);
	}
}

通過程式碼的描述,知道類的真正意義就是在描述事物。屬性和功能統稱為事物中的成員。 事物的成員分為兩種:成員屬性和成員功能。 成員屬性在程式碼中的體現就是成員變數 成員功能在程式碼中的體現就是成員方法 把寫好的程式碼測試一下。需要一個可以獨立執行類。  建立物件的格式:

類名 物件名 = new 類名();

 測試類

public class CarDemo {
	public static void main(String[] args) { 
		/*
		 *  測試:Car類中的run方法。
		 */
		// 1,建立Car的物件。給物件起個名字。
		Car c = new Car();// c是類型別的變數。c指向了一個具體的Car型別的物件。
		// 2,通過已有的物件呼叫該物件的功能。格式:物件.物件成員;
		// 3,可以該物件的屬性賦值。
		c.color = "red";
		c.number = 4;
		c.run();
	}
}

2.3 物件的記憶體圖解 經過上面對小汽車的描述,和Java程式碼測試,我們雖然可以將生活中的事物使用Java程式碼描述出來,但是這些程式碼在記憶體中是如何執行的,接下來我們需要研究下物件在記憶體的圖解。 接下來就是分析物件在記憶體中的分配情況。這裡需要畫圖一步一步演示,嚴格按照畫圖流程講解記憶體物件建立過程。

package cn.itcast.demo01;
/*
 * 類的方式,描述現實中的事物小汽車
 * 
 * 	小汽車	屬性和功能
 * 			屬性:顏色 輪胎個數  變數定義
 * 			功能:跑--方法
 * 
 * 	屬性和方法,都屬於類的成員
 * 	屬性,成員變數
 *  方法,成員方法
 */
public class Car {
	//定義Car類的屬性	
	//定義顏色屬性
	String color;
	//定義輪胎個數
	int count;	
	//定義跑的功能
	public void run(){
		System.out.println("小汽車在跑" + "..." + color + "..." + count);
	}
}
package cn.itcast.demo01;
/*
 * 測試,自定義的類Car
 * 創建出Car類的變數
 * 變數,呼叫屬性,成員變數
 * 變數,呼叫方法
 */

public class CarTest {

	public static void main(String[] args) {
		//創建出Car類的變數,創建出Car型別的物件,小汽車真的有了
		Car c = new Car();
		//物件.呼叫類中的屬性和方法
		c.color = "黑色";
		c.count = 5;	
		c.run();
	}

}

在這裡插入圖片描述 2.4 類和物件的區別 面向物件的程式設計思想力圖在程式中對事物的描述與該事物在現實中的形態保持一致。為了做到這一點,**面向物件的思想中提出兩個概念,即類和物件。其中,類是對某一類事物的抽象描述,而物件用於表示現實中該類事物的個體。**接下來通過一個圖例來抽象描述類與物件的關係,如下圖所示。 圖1-1	類與物件 在上圖中,可以將玩具模型看作是一個類,將一個個玩具看作物件,從玩具模型和玩具之間的關係便可以看出類與物件之間的關係。類用於描述多個物件的共同特徵,它是物件的模板。物件用於描述現實中的個體,它是類的例項。從上圖中可以明顯看出物件是根據類建立的,並且一個類可以對應多個物件,接下來分別講解什麼是類和物件。 經過前面幾個知識點的學習,基本上掌握了類是用於描述事物的,類中可以定義事物的屬性和行為。而物件是通過描述的這個類,使用new關鍵字創建出來,通過物件就可以呼叫該物件具體的屬性和功能了。 2.5 區域性變數和成員變數區別 理解清楚了類和物件之後,結合前5天的學習知識,發現在描述類的屬性和前面學習定義變數差別不大,唯一區別就是位置發生了改變,那麼類中定義的變數,和在方法定義的變數有啥差別呢? 回憶以前學習時變數的定義方式,和位置,以及現在定義類中屬性的特點。總結下面幾點異同 區別一:定義的位置不同 定義在類中的變數是成員變數 定義在方法中或者{}語句裡面的變數是區域性變數 區別二:在記憶體中的位置不同 成員變數儲存在對記憶體的物件中 區域性變數儲存在棧記憶體的方法中 區別三:宣告週期不同 成員變數隨著物件的出現而出現在堆中,隨著物件的消失而從堆中消失 區域性變數隨著方法的執行而出現在棧中,隨著方法的彈棧而消失 區別四:初始化不同 成員變數因為在堆記憶體中,所有預設的初始化值 區域性變數沒有預設的初始化值,必須手動的給其賦值才可以使用。

package cn.itcast.demo02;

public class Car {
	//定義Car類的屬性	
	//定義顏色屬性
	String color;
	//定義輪胎個數
	int count;	
	//定義跑的功能
	public void run(){
		int x = 1;//he value of the local variable x is not used區域性變數需要賦值
		System.out.println(x);
		System.out.println("小汽車在跑" + "..." + color + "..." + count);
	}
}
package cn.itcast.demo02;
/*
 *** 成員變數和區域性變數的區別
 * 1.定義位置上的區別
 * 		成員變數,定義在類中,方法外
 * 		區域性變數,方法內,語句內
 * 2.作用域不同
 * 		成員變數,作用範圍是整個類
 * 		區域性變數,方法內,語句內
 * 前兩個最重要,因為我們看得到,摸得著
 * 3.預設值不同
 * 		成員變數,有自己的預設值,String - null int - 0 double - 0.0 布林型-false
 * 		區域性變數,沒有預設值,不賦值就不能使用
 * 4.記憶體位置不同
 * 		成員變數,跟隨物件進入堆記憶體中,並且賦預設值
 * 		區域性變數,跟隨自己的方法,進入棧記憶體
 * 5.生命週期不同
 * 		成員變數,跟隨物件,在堆中儲存,在記憶體中等等JVM虛擬機器清理,生命週期相對較長
 * 		區域性變數,跟隨方法,方法彈出棧,生命週期相對較短**
 */
public class CarTest {

	public static void main(String[] args) {
		//創建出Car類的變數,創建出Car型別的物件,小汽車真的有了
		Car c = new Car();
		//物件.呼叫類中的屬性和方法
		c.color = "黑色";
		c.count = 5;	
		c.run();
	}

}

成員變數和區域性變數的區別 1.定義位置上的區別 成員變數,定義在類中,方法外 區域性變數,方法內,語句內 2.作用域不同 成員變數,作用範圍是整個類 區域性變數,方法內,語句內 前兩個最重要,因為我們看得到,摸得著 3.預設值不同 成員變數,有自己的預設值,String - null int - 0 double - 0.0 布林型-false 區域性變數,沒有預設值,不賦值就不能使用 4.記憶體位置不同 成員變數,跟隨物件進入堆記憶體中,並且賦預設值 區域性變數,跟隨自己的方法,進入棧記憶體 5.生命週期不同 成員變數,跟隨物件,在堆中儲存,在記憶體中等等JVM虛擬機器清理,生命週期相對較長 區域性變數,跟隨方法,方法彈出棧,生命週期相對較短 2.6 基本型別和引用型別作為引數傳遞 引用型別資料和基本型別資料作為引數傳遞有沒有差別呢?我們用如下程式碼進行說明,並配合圖解讓大家更加清晰 在這裡插入圖片描述 class Demo { public static void main(String[] args) { int x = 4; show(x); System.out.println(“x=”+x); } public static void show(int x) { x = 5;

}

} 基本型別作為引數傳遞時,其實就是將基本型別變數x空間中的值複製了一份傳遞給呼叫的方法show(),當在show()方法中x接受到了複製的值,再在show()方法中對x變數進行操作,這時只會影響到show中的x。當show方法執行完成,彈棧後,程式又回到main方法執行,main方法中的x值還是原來的值。 在這裡插入圖片描述 class Demo { int x ; public static void main(String[] args) {

	Demo d = new Demo();
	d.x = 5;
	show(d);
	System.out.println("x="+d.x);
}
public static void show(Demo d)
{
	d.x = 6;
}

} 當引用變數作為引數傳遞時,這時其實是將引用變數空間中的記憶體地址(引用)複製了一份傳遞給了show方法的d引用變數。這時會有兩個引用同時指向堆中的同一個物件。當執行show方法中的d.x=6時,會根據d所持有的引用找到堆中的物件,並將其x屬性的值改為6.show方法彈棧。 由於是兩個引用指向同一個物件,不管是哪一個引用改變了引用的所指向的物件的中的值,其他引用再次使用都是改變後的值。

package cn.itcast.demo03;
/*
 * 
 */
public class Person {
	String name;
}
package cn.itcast.demo03;
/*
 * 方法的引數型別,是基本資料型別,引用資料型別
 */
public class PersonTest {

	public static void main(String[] args) {
		int a = 1;
		function(a);
		System.out.println(a);//1
		
		Person p = new Person();
		p.name = "張三";
		System.out.println("初始賦值:" + p.name);
		
		function(p);
		System.out.println("呼叫function函式賦值:" + p.name);
	}
	/*
	 * 定義方法,引數型別是引用資料型別
	 */
	public static void function(Person p){
		p.name = "李四";
	}
	/*
	 * 定義方法,引數型別是基本資料型別
	 */
	public static void function(int a){
		a += 5;
	}
}

在這裡插入圖片描述 第3章 封裝 3.1 封裝概述 提起封裝,大家並不陌生。前面我們學習方法時,就提起過,將具體功能封裝到方法中,學習物件時,也提過將方法封裝在類中,其實這些都是封裝。 封裝,它也是面向物件思想的特徵之一。面向物件共有三個特徵:封裝,繼承,多型。接下來我們具體學習封裝。  封裝表現:  1、方法就是一個最基本封裝體。  2、類其實也是一個封裝體。  從以上兩點得出結論,封裝的好處:  1、提高了程式碼的複用性。  2、隱藏了實現細節,還要對外提供可以訪問的方式。便於呼叫者的使用。這是核心之一,也可以理解為就是封裝的概念。  3、提高了安全性。 3.2 封裝舉例 機箱: 一臺電腦,它是由CPU、主機板、顯示卡、記憶體、硬碟、電源等部件組長,其實我們將這些部件組裝在一起就可以使用電腦了,但是發現這些部件都散落在外面,很容造成不安全因素,於是,使用機箱殼子,把這些部件都裝在裡面,並在機箱殼上留下一些插口等,若不留插口,大家想想會是什麼情況。 總結:機箱其實就是隱藏了辦卡裝置的細節,對外提供了插口以及開關等訪問內部細節的方式。 3.3 私有private 瞭解到封裝在生活的體現之後,又要回到Java中,細說封裝的在Java程式碼中的體現,先從描述Person說起。 描述人。Person 屬性:年齡。 行為:說話:說出自己的年齡。

class Person {
	int age;
	String name;

	public void show() {
		System.out.println("age=" + age + ",name" + name);
	}
}

public class PersonDemo {
	public static void main(String[] args) {
		// 建立Person物件
		Person p = new Person();
		p.age = -20; // 給Person物件賦值
		p.name = "人妖";
		p.show(); // 呼叫Person的show方法
	}
}

通過上述程式碼發現,雖然我們用Java程式碼把Person描述清楚了,但有個嚴重的問題,就是Person中的屬性的行為可以任意訪問和使用。這明顯不符合實際需求。 可是怎麼才能不讓訪問呢?需要使用一個Java中的關鍵字也是一個修飾符 private(私有,許可權修飾符)。只要將Person的屬性和行為私有起來,這樣就無法直接訪問。

class Person {
	private int age;
	private String name;

	public void show() {
		System.out.println("age=" + age + ",name" + name);
	}
}

年齡已被私有,錯誤的值無法賦值,可是正確的值也賦值不了,這樣還是不行,那腫麼辦呢?按照之前所學習的封裝的原理,隱藏後,還需要提供訪問方式。只要對外提供可以訪問的方法,讓其他程式訪問這些方法。同時在方法中可以對資料進行驗證。 一般對成員屬性的訪問動作:賦值(設定 set),取值(獲取 get),因此對私有的變數訪問的方式可以提供對應的 setXxx或者getXxx的方法。

class Person {
	// 私有成員變數
	private int age;
	private String name;

	// 對外提供設定成員變數的方法
	public void setAge(int a) {
		// 由於是設定成員變數的值,這裡可以加入資料的驗證
		if (a < 0 || a > 130) {
			System.out.println(a + "不符合年齡的資料範圍");
			return;
		}
		age = a; 
	}

	// 對外提供訪問成員變數的方法
	public void getAge() {
		return age;
	}
}

 總結: 類中不需要對外提供的內容都私有化,包括屬性和方法。 以後再描述事物,屬性都私有化,並提供setXxx getXxx方法對其進行訪問。  注意:私有僅僅是封裝的體現形式而已。

package cn.itcast.demo04;
/*
 * 描述現實生活中的人-這個事物
 * 	屬性:姓名 年齡--成員變數
 * 	功能:說話--方法
 * 
 * 出現安全問題,age問題,可能出現賦值為負數的情況
 * 負數不會導致程式問題,違反生活中的真實情況
 * 
 * 提高安全問題:讓外面的類,不允許直接呼叫我的成員變數
 * 新的關鍵字private 私有 屬於成員修飾符,不能修飾區域性變數
 * 被private修飾的成員,只能在自己類中被使用
 * 
 *對私有變數,提供公共的訪問方式:方法
 */

public class Person {
	//人的姓名,成員變數
	String name;
	
	//人的年齡,成員變數
	private int age;
	
	//變數age被私有化,提供方法,讓外面的類來使用
	//定義方法,對age變數進行賦值,方法名字,必須set開頭
	public void setAge(int a){
		//對變數引數a進行範圍的限制
		if(a <=0 || a > 100){
			//如果a超過範圍,手動將age賦值為20
			age = 20;
		}else{
			//如果a沒有超過範圍,直接對age賦值
			age = a;
		}
	}
	//定義方法,對變數age獲取值來使用,方法名字必須get開頭
	public int getAge(){
		return age;
	}
	//定義人的說話功能,方法中,要求說出自己的姓名和年齡
	public void speak(){
		System.out.println(name + "..." + age);
	}
}
package cn.itcast.demo04;
/*
 * 定義好的Person類進行測試
 * 建立物件,物件呼叫屬性和方法
 */
public class PersonTest {

	public static void main(String[] args) {
		//建立Person類的物件 new
		Person p = new Person();
		//對成員變數賦值
		//對私有成員變數age賦值,只能使用Set方法賦值
		p.setAge(22);
		
		p.name = "張三";
		//呼叫類中的方法
		p.speak();
		//輸出成員變數age值,必須呼叫getAge方法
		System.out.println(p.getAge());
		
	}
}

在這裡插入圖片描述 3.4 this關鍵字 3.4.1 成員變數和區域性變數同名問題 當在方法中出現了局部變數和成員變數同名的時候,那麼在方法中怎麼區別區域性變數成員變數呢?可以在成員變數名前面加上this.來區別成員變數和區域性變數

class Person {
	private int age;
	private String name;
	
	public void speak() {
		this.name = "小強";
		this.age = 18;
		System.out.println("name=" + this.name + ",age=" + this.age);
	}
}

class PersonDemo {
	public static void main(String[] args) {
		Person p = new Person();
		p.speak();
	}
}

3.4.2 物件的記憶體解釋 我們已經學習瞭如何把生活中的事物使用Java程式碼描述,接下來我們分析物件在記憶體中的分配情況。這裡需要畫圖一步一步演示,嚴格按照畫圖流程講解記憶體物件建立使用過程。

class Person {
	private int age;
	public int getAge() {
		return this.age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}
public class PersonDemo {
	public static void main(String[] args) {
		Person p = new Person();
		p.setAge(30);
		System.out.println("大家好,今年我" + p.getAge() + "歲");
	}
}

下圖為程式中記憶體物件的建立使用過程。 在這裡插入圖片描述 在這裡插入圖片描述 程式執行流程說明: 1、 先執行main方法(壓棧),執行其中的 Person p = new Person(); 2、 在堆記憶體中開闢空間,併為其分配記憶體地址0x1234,緊接著成員變數預設初始化(age = 0);將記憶體地址0x1234賦值給棧內中的Person p 變數 3、 繼續執行p.setAge(30)語句,這時會呼叫setAge(int age)方法,將30賦值為setAge方法中的“age”變數;執行this.age = age語句,將age變數值30 賦值給成員變數this.age為30; 4、 setAge()方法執行完畢後(彈棧),回到main()方法,執行輸出語句System.out.println(),控制檯列印p物件中的age年齡值。  注意:  this到底代表什麼呢?this代表的是物件,具體代表哪個物件呢?哪個物件呼叫了this所在的方法,this就代表哪個物件。  上述程式碼中的 p.setAge(30)語句中,setAge(int age)方法中的this代表的就是p物件。 3.4.3 this的應用 學習this的用法之後,現在做個小小的練習。 需求:在Person類中定義功能,判斷兩個人是否是同齡人

package cn.itcast.demo06;

public class Person {
	private String name;
	
	private int age;
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setAge(int age){
		this.age = age;
	}
	
	public void speak(){
		System.out.println("人的名字:" + this.name + " 人的年齡:" + this.age);
	}
	
	/*
	 * 定義方法,與別人比較年齡大小
	 * 返回值:布林型
	 * 引數:Person
	 */
	public boolean compare(Person p){
		return (this.age == p.age);
	}
}
package cn.itcast.demo06;

public class PersonTest {

	public static void main(String[] args) {
		//建立2個Person的例項物件
		Person p1 = new Person();	
		Person p2 = new Person();
		
		p1.setAge(15);
		p2.setAge(16);
		
		//p1物件呼叫自己的方法compare傳遞p2物件
		boolean b = p1.compare(p2);
		System.out.println(b);
	}
}

在這裡插入圖片描述 第4章 綜合案例—隨機點名案例重構 4.1 案例介紹 隨機點名器,即在全班同學中隨機的找出一名同學,列印這名同學的個人資訊。 此案例在我們前幾天課程學習中,已經介紹,現在我們要做的是對原有的案例進行升級,使用新的方式來實現。 我們來完成隨機點名器,它具備以下3個內容:  儲存所有同學姓名  總覽全班同學姓名  隨機點名其中一人,列印到控制檯 4.2 案例分析 全班同學中隨機的找出一名同學,列印這名同學的個人資訊。 我們對本案例進行分析,得出如下分析結果: 1.儲存全班同學資訊(姓名、年齡) 2.列印全班同學每一個人的資訊(姓名、年齡) 3.在班級總人數範圍內,隨機產生一個隨機數,查詢該隨機數所對應的同學資訊(姓名、年齡)並列印 隨機點名器明確地分為了三個功能。如果將多個獨立功能的程式碼寫到一起,則程式碼相對冗長,我們可以針對不同的功能可以將其封裝到一個方法中,將完整獨立的功能分離出來。 而在儲存同學姓名時,如果對每一個同學都定義一個變數進行姓名儲存,則會出現過多孤立的變數,很難一次性將全部資料持有。此時,我們採用ArrayList集合來解決多個學生資訊的儲存問題。 4.3 重構內容分析 將原來使用的簡單Student類,封裝為包裝屬性和方法的相對完整的Student類,並將所有訪問屬性的地方改為通過get/set方法訪問。 重構部分已使用紅色樣色字體表示 4.4 實現程式碼

package cn.itcast.demo07;
/*
 * 學生類:
 * 	屬性:姓名,年齡
 */
public class Student {
	String name;
	int age;
	
	public void setName(String name){
		this.name = name;
	}
	
	public void setAge(int age){
		if(age <=0 || age > 100){
			this.age = 20;
		}else{
			this.age = age;
		}
	}
	
	public String getName(){
		
		return this.name;
	}
	
	public int getAge(){
		
		return this.age;
	}
	
}

package cn.itcast.demo07;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

/*
 * 隨機點名器
 * 現實中有學生這個事物,使用定義類的形式,描述學生事物
 * 屬性:姓名,年齡
 * 姓名儲存了陣列,將容器換成是集合
 * 
 * 儲存學生:
 * 		學生型別,儲存到集合中
 * 
 * 總覽:遍歷集合
 * 隨機:隨機數類Random,隨機數,作為索引,到集合中找到元素
 * 
 * 三個功能,共享的資料,集合容器
 * 定義三個方法,必須引數傳遞集合
 * 
 * 類-引用資料型別,與之前學習的所有引用資料型別相同
 * 自定義類也是一種資料型別
 * 只是自定義資料型別並非Java為我們預先提供好的型別,而是我們自己定義的一種引用資料型別來描述事物
 * 
 * 建立集合的常用格式在此說明一下:
 * C1:導包:import java.util.ArrayList;
 * C2:建立物件:與其他普通的引用資料型別建立方式完全相同,但是要指定容器中儲存的資料型別
 * C:ArrayList<儲存元素的資料型別> 變數名 = new ArrayList<儲存元素的資料型別>();
 * <儲存元素的資料型別>   ===>  中的資料型別必須是引用資料型別,不能是基本資料型別
 * 
 * 類的名字:首字母大寫,第二個字母首字母大寫,例如:BeiJing
 * 			public classs HelloWorld{
 * 			
 * 			}
 * 方法的名字:首字母小寫,每個單詞首字母大寫,例如:addSchool
 * 			public static void main(String[] args){}
 *
 *隨機數類Random:
 *R1:導包:import java.util.Random
 *R2:建立例項格式:Random 變數名 = new Random();
 *R3:呼叫方法:
 *		public int nextInt(int maxValue)	產生[0,maxValue)範圍的隨機整數,包含0,不包含maxValue;
 *		public double nextDouble()  產生[0,1)範圍的隨機小數,包含0.0,不包含1.0。
 * 
 */
public class CallName {

	public static void main(String[] args) {
		//1.定義集合ArrayList,儲存Student型別
		ArrayList<Student> array = new ArrayList<Student>();
		//2.呼叫新增方法
		addStudent(array);
		//3.進入死迴圈
		//(原因:只允許按到數字3退出系統,才結束整個系統,否則一直迴圈,由於不知道迴圈次數,一般採用while迴圈)
		while(true){
			//4.呼叫輸入選擇數字功能,鍵盤輸入需要的功能對應的數字
			int choose = chooseFunction();
			//5.對序號判斷:1-進入檢視庫存功能 2-進入修改庫存功能 3-結束
			switch (choose) {
			case 1:
					//5.1.呼叫遍歷集合
					printStudent(array);
				break;
				
			case 2:
					//5.2.集合中隨機抽取元素
					randomStudent(array);
				break;
			case 3:
					//5.3.結束系統
				System.out.println("點名系統結束,歡迎下次使用");
				return;
				
			default:
				System.out.println("功能還在完善中,請期待哦...");
				break;
			}
		}
	}
	/*2.呼叫新增方法
	 * 定義方法,儲存Student物件,到集合容器中
	 * 返回值:void
	 * 引數:建立Student型別變數,儲存到集合中
	 */
	public static void addStudent(ArrayList<Student> array){
		//建立Student型別變數,例項化
		Student sn1 = new Student();
		Student sn2 = new Student();
		Student sn3 = new Student();

		sn1.setAge(11);
		sn1.setName("章1");
		
		sn2.setAge(12);
		sn2.setName("章2");
		
		sn3.setAge(13);
		sn3.setName("章3");
		//將Student型別變數,儲存到集合中
		array.add(sn1);
		array.add(sn2);
		array.add(sn3);
		System.out.println("初始化學生資訊完畢");
	}
	/*4.呼叫輸入選擇數字功能,鍵盤輸入需要的功能對應的數字
	 * 定義方法,鍵盤輸入數字,選擇對應功能
	 * 返回值:int
	 * 引數:無
	 */
	public static int chooseFunction(){
		System.out.println("--------------------學生隨機點名系統----------------------");
		System.out.println("1.遍歷學生姓名");
		System.out.println("2.隨機點名功能");
		System.out.println("3.退出系統");
		System.out.println("請輸入要執行的操作序號:");
		//接受鍵盤輸入
		//S2:建立物件例項:Scanner sc = new Scanner(System.in);
		Scanner sc = new Scanner(System.in);
		//S3.呼叫方法:int i = sc.nextInt();//用來接收控制檯錄入的數字
		return sc.nextInt();
	}
	/*
	 * 5.1.呼叫遍歷集合
	 * 定義方法,遍歷集合中的元素,注意事項是:遍歷拿到的是Student型別變數,還需要去獲取Student型別變數所對應的屬性
	 * 返回值:void
	 * 引數:共享的資料集合容器
	 */
	public static void printStudent(ArrayList<Student> array){
		for (int i = 0; i < array.size(); i++) {
			//儲存集合的時候,集合.add(sn1) sn1是Student型別變數
			//獲取的時候,集合.get()獲取出來的是什麼,還是Student型別變數
			//若想獲得Student型別變數相應屬性,需要採用Student型別變數名.屬性
			Student sn = array.get(i);
			System.out.println("姓名:" + sn.getName() + " 年齡:" + sn.getAge());
		}
		System.out.println("============遍歷學生姓名結束==================");
	}
	/*5.2.集合中隨機抽取元素
	 * 定義方法,用隨機類Random,隨機一個索引,拿去集合獲取一個Student型別變數,然後在物件.屬性 列印相應的屬性
	 * 返回值:void
	 * 引數:共享資料的集合容器
	 */
	public static void randomStudent(ArrayList<Student> array){
		System.out.println("開始隨機點名嘍,這次我們點到:");
		//R2:建立例項格式:Random 變數名 = new Random();
		Random ran = new Random();
		// R3:呼叫方法:public int nextInt(int maxValue)	產生[0,maxValue)範圍的隨機整數,包含0,不包含maxValue;
		int index = ran.nextInt(array.size());
		//儲存集合的時候,集合.add(sn1) sn1是Student型別變數
		//獲取的時候,集合.get()獲取出來的是什麼,還是Student型別變數
		//若想獲得Student型別變數相應屬性,需要採用Student型別變數名.屬性
		Student sn = array.get(index);
		System.out.println("姓名:" + sn.getName() + " 年齡:" + sn.getAge());
		System.out.println("隨機點名結束一次...");
	}
}

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述 第5章 總結 5.1 知識點總結  類與物件  類,用於描述多個物件的共同特徵,它是物件的模板。  物件,用於描述現實中的個體,它是類的例項。  類的定義:使用關鍵字class來定義java中的類  格式:

		class 類名 {
				//屬性
				資料型別 變數名;
				…
				//方法
				修飾符 返回值型別 方法名(引數){   }
				…
			}

 建立物件:  格式:  封裝(private關鍵字)  封裝,把物件的屬性與方法的實現細節隱藏,僅對外提供一些公共的訪問方式  封裝的體現:  變數:使用 private 修飾,這就是變數的封裝  方法:也是一種封裝,封裝了多條程式碼  類: 也是一種封裝,封裝了多個方法  private關鍵字,私有的意思  它可以用來修飾類中的成員(成員變數,成員方法)  private的特點:  private修飾的成員只能在當前類中訪問,其他類中無法直接訪問  this關鍵字  this關鍵字,本類物件的引用  this是在方法中使用的,哪個物件呼叫了該方法,那麼,this就代表呼叫該方法的物件引用  this什麼時候存在的?當建立物件的時候,this存在的  this的作用:用來區別同名的成員變數與區域性變數(this.成員變數)

public void setName(String name) {
				this.name = name;
			}