面向对象程序设计_面向对象的程序设计(续)
寫在前面:這里是續(xù)之前的那篇文章,同樣源于本人的個(gè)人博客,在知乎為了一個(gè)備份
這里是7-10章
Chapter 7: Arrays 數(shù)組 記得在C語(yǔ)言里面,也有提到過(guò)數(shù)組這個(gè)概念 記得RT也說(shuō)過(guò)這玩意會(huì)很難結(jié)果花了3節(jié)課來(lái)講這玩意 還好期末考試沒(méi)考.... [scode type="green"]Array Basic[/scode] 首先老樣子先來(lái)看看語(yǔ)法 int a[] = new int5; //套公式的話就像這樣elementType[] arrayRefVar; //舉個(gè)栗子 double [] myList; 數(shù)組能被視作一個(gè)變量或者是一個(gè)數(shù)據(jù)集合 不過(guò)值得一提的是,當(dāng)一個(gè)數(shù)組被創(chuàng)建出來(lái)之后,其大小就是固定的不會(huì)被改變的了 其實(shí)數(shù)組就像冰塊盒,單行的那種,我們能往盒子里放東西,同樣也能取東西出來(lái) 哦對(duì)了記得數(shù)組是從 0 開(kāi)始的啊 public static void main(String[] atgs) { int[] array1; double[] array2; char[] array3; } 我們可以聲明一個(gè)數(shù)組(也就是上面的那個(gè)array1)為一個(gè)變量,相似于int a; 既然我們已經(jīng)聲明了一個(gè)數(shù)組,但是并沒(méi)有真正的創(chuàng)建出來(lái) 為了創(chuàng)建一個(gè)數(shù)組,剩下的需要做的事情就是給它賦值了 array1 = new int10; array 2 = new char[100]; 上面的那個(gè)就是聲明變量并且創(chuàng)建變量,但是這個(gè)過(guò)程其實(shí)可以在一行代碼中就解決掉 int [] array4 = new int5; 不過(guò)我覺(jué)得能用兩行還是用兩行比較好 比較到后面檢查來(lái)說(shuō)的話也比較方便嘛 一行就像濃縮咖啡,容易嗆著 關(guān)于我們用數(shù)組和它的儲(chǔ)值的話可以用一張圖來(lái)表示出來(lái)
之后,想再次查看數(shù)組的長(zhǎng)度的話,可以使用 數(shù)組名字.length 來(lái)查看數(shù)組的長(zhǎng)度 [collapse status="false" title="關(guān)于數(shù)組的其他操作"] 當(dāng)我們輸入數(shù)組后加個(gè)句號(hào)(英文的句號(hào))的時(shí)候,就會(huì)彈出這樣一個(gè)菜單
這個(gè)菜單列出的都是關(guān)于數(shù)組的基本操作 可以選擇一些需要的 [/collapse] 記得之前CC講過(guò)一個(gè)message.length, 感覺(jué)這兩個(gè)玩意的性質(zhì)應(yīng)該都差不多是一個(gè)意思 就是用來(lái)計(jì)算長(zhǎng)度的嘛 那么問(wèn)題來(lái)了,如果說(shuō)我們需要輸出一個(gè)數(shù)組里面的數(shù)字,咋整? 講道理用一個(gè)循環(huán)就好了 數(shù)組輸出的套路一般都是array[i],其中的i要求就是i++,說(shuō)白了就是加一加一加一這樣來(lái)輸出 用代碼表示的話可以表示為 for ( int i = 0; i < 5 ; i++) { System.out.println("array[i]"); } 這樣子就沒(méi)問(wèn)題了 當(dāng)我們前面對(duì)array數(shù)組進(jìn)行了一系列的賦值操作之后,這里就能一行一行地顯示出來(lái)數(shù)組里的數(shù)字 [scode type="green"]Accessing Array Elements 引用數(shù)組元素[/scode] 這里提到的一點(diǎn)就是 當(dāng)我們?nèi)ヒ梦覀儎?chuàng)建的數(shù)組里某一個(gè)具體位置的元素的時(shí)候,這個(gè)數(shù)組下標(biāo)是從 0 開(kāi)始的 然后最大的數(shù)字是一直到 (數(shù)組大小 - 1) 的這個(gè)位置 比如說(shuō)我們創(chuàng)建了一個(gè)大小為10的數(shù)組,那這個(gè)數(shù)組的下標(biāo)的最大值就是 9 而不是 10 [scode type="green"]Foreach Loops 關(guān)于Foreach 循環(huán)[/scode] 這里補(bǔ)充一個(gè)小知識(shí)點(diǎn) 可以把它叫做數(shù)組的便利 就是可以用比較簡(jiǎn)潔的方法來(lái)將數(shù)組里的元素快速地提取出來(lái) 首先先來(lái)看語(yǔ)法 for (double e: myList) { System.out.println(e); } 就是在for循環(huán)中加上 double e: array 就可以了 里面的x可以換成任意的變量,只要不沖突的就行 這句話的意思就是將數(shù)組里的數(shù)字取出來(lái)存放在變量X中,這里我們可以在循環(huán)內(nèi)部加上一個(gè)println語(yǔ)句來(lái)將其輸出出來(lái) 哦對(duì)了,我們定義的這個(gè)用來(lái)存放數(shù)據(jù)的這個(gè)數(shù)據(jù)類型,一定要和數(shù)組里面的數(shù)據(jù)類型是一致的 比如數(shù)組里的是分?jǐn)?shù)的話,那我們定義數(shù)組類型的時(shí)候就不能定義為int 還是以前那句話,double保平安 [scode type="green"]數(shù)組的綜合運(yùn)用[/scode] 這節(jié)課老師用邊上課邊講的方式,喊我們做了個(gè)綜合的小練習(xí) 這里就po出我的答案啦 package ClassWork; public class ArrayExerise { public static void main(String[] args) { // TODO Auto-generated method stub int[] Jackey; Jackey = new int5; //or you can write like that: //int[] Jackry = new int5 //or int Jackry[] = new int5 //both ok //Initializing arrys with random values 使用隨機(jī)數(shù)字初始化數(shù)組 for (int i = 0; i < Jackey.length ; i++) { Jackey[i] = (int)(Math.random() * 100); //[0,1) //0.555555 -- 5.5555555 -- 55 //() will change the level //加了括號(hào)的內(nèi)容會(huì)改變運(yùn)算的優(yōu)先級(jí) } //Display arrays 顯示數(shù)組內(nèi)容 for (int i = 0; i < Jackey.length ; i++) { System.out.print(Jackey[i] + " "); } System.out.println(); //Sum all elements int sum = 0; for (int i = 0; i < Jackey.length; i++) { sum += Jackey[i]; } System.out.println("sum :" + sum); //Find the largest element int large = Jackey[0]; for (int i = 1; i < Jackey.length ; i++) { if(Jackey[i] > large) { large = Jackey[i]; } //這里就算去掉上面這個(gè)if的花括號(hào)也是ok的 } //上面這個(gè)for的花括號(hào)也可以省略 //因?yàn)槔锩娴膇f是一條語(yǔ)句 //在Java的語(yǔ)法中,只有分號(hào)會(huì)被視為一條語(yǔ)句 System.out.println("largest : " + large); //Random shuffling 隨機(jī)洗牌 for (int i = Jackey.length - 1; i > 0 ; i--) { //generate a random index j //[0 , i] int j = (int)(Math.random() * (i + 1)); int temp = Jackey[i]; Jackey[i] = Jackey[j]; Jackey[j] = temp; } for (int a = 0; a < Jackey.length ; a++) { System.out.print(Jackey[a] + " "); } //Display arrys System.out.println(); //shift elements 移位 int temp = Jackey[0]; for (int i = 1; i < Jackey.length ; i++) { Jackey[i - 1]= Jackey [i]; } Jackey[Jackey.length - 1] = temp; //Display arrays //foreach loop for (int output: Jackey) { System.out.print(output + " "); } } } [scode type="green"]Copying Arrays 數(shù)組的復(fù)制[/scode] 如果說(shuō)人類史上最偉大的發(fā)明是什么 那我會(huì)回答是Ctrl + c and Ctrl + v 當(dāng)然這種方法也能用在數(shù)組上 首先我們先看回到我們以前的賦值方法 在我們賦值數(shù)字的時(shí)候,一般都是用a = b 來(lái)將b的值賦值給a 不過(guò)你放心,在數(shù)組里的方法肯定不一樣,因?yàn)閯”静辉试S 首先我們要先清楚數(shù)組的概念 數(shù)組可以將其理解為一個(gè)小倉(cāng)庫(kù)和名字,假如我們有兩個(gè)小倉(cāng)庫(kù),名字分別為list1 和 list2
list1 和 list2 都分別有對(duì)應(yīng)的倉(cāng)庫(kù)與其連接,互不干擾 但是當(dāng)我們執(zhí)行l(wèi)ist2 = list1 這個(gè)語(yǔ)句之后,其就會(huì)變?yōu)?
可以看到原本屬于list1的倉(cāng)庫(kù)被貼上了list2的標(biāo)簽,這也就意味著list1 和 list2都指向同一個(gè)倉(cāng)庫(kù)了 結(jié)果空巢倉(cāng)庫(kù)list2就沒(méi)人管了 這顯然不是我們想要的結(jié)果 那么什么是正確操作呢? 為了給數(shù)組進(jìn)行正確的賦值操作,使得兩個(gè)數(shù)組的值完全一模一樣,我們可以用3種方法
首先我們先來(lái)看一個(gè)一個(gè)賦值的基本方法 比如先把數(shù)組導(dǎo)入到一個(gè)循環(huán)里面,然后使用循環(huán)將數(shù)組里面的數(shù)字一個(gè)一個(gè)的提取出來(lái),并賦值到它應(yīng)該去的地方 先用一段代碼來(lái)表示這個(gè) int[] sourceArray = {2, 3, 4, 5, 10}; int[] targetArray = new int [scourceArray.length]; for (int i = 0; i < sourceArray.length; i++) { targetArray[i] = sourceArray[i]; } 這里就不解釋代碼了,這段代碼比較簡(jiǎn)單易懂 我們把重點(diǎn)放在第二種方法上----arraycopy method 數(shù)組復(fù)制 所謂的arraycopy方法其實(shí)就是調(diào)用一個(gè)存在于系統(tǒng)里的方法,來(lái)給指定的數(shù)組進(jìn)行復(fù)制 arraycopy(sourceArray, srcPos, targetArray, tarPos, length); 括號(hào)內(nèi)的東西:原數(shù)組的名字,原數(shù)組的位置,目標(biāo)數(shù)組的名字,目標(biāo)數(shù)組的位置,賦值對(duì)少個(gè) 所謂原數(shù)組的位置的意思就是你想從幾號(hào)元素開(kāi)始復(fù)制 最后的賦值多少個(gè)的意思就是 按照2345這樣的順序依次復(fù)制下去 比如我們最開(kāi)始希望把源數(shù)組的2號(hào)位置賦值給目標(biāo)數(shù)組的一號(hào)位置,如果我們最后那個(gè)數(shù)字填的是10,那第一個(gè)數(shù)字賦值完成后,就會(huì)開(kāi)始把源數(shù)組3號(hào)位置的值賦值給目標(biāo)數(shù)組的2號(hào)位置,并且以此類推 現(xiàn)在有一個(gè)問(wèn)題,已經(jīng)聲明大小的數(shù)組,我們能用相同的語(yǔ)句去改變它的大小嘛 用代碼來(lái)表示的話就是 int[] myList; myList = new int10; mylist = new int20; 答案是不行的 因?yàn)檫@樣的代碼并沒(méi)有改變數(shù)組的大小 原來(lái)那個(gè)大小為10的數(shù)組任然在內(nèi)存中駐留 而我們的myList指向了另外一個(gè)大小為20的數(shù)組 因?yàn)樵趦?nèi)存里面,數(shù)組是隨著創(chuàng)建的完成就會(huì)被分配出一個(gè)空間來(lái)儲(chǔ)存它的 當(dāng)我們輸入myList = new int20的時(shí)候,內(nèi)存就會(huì)自動(dòng)分配一個(gè)20空間的地方來(lái)存放這個(gè)新數(shù)組 但是原來(lái)那個(gè)數(shù)組就沒(méi)人管了 又成了個(gè)空巢數(shù)組 [scode type="green"]Passing Array to Methods 把數(shù)組在不同方法中傳遞[/scode] 我們可以先自定義一個(gè)方法 public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.println(array[i] + " "); } } 然后我們可以在主方法中call它,記得在括號(hào)內(nèi)放上需要的數(shù)據(jù) printArray(new int [] {3, 1, 2, 6, 4, 2}) 這樣子就沒(méi)問(wèn)題了 至于使用什么方法傳遞出去的話,可以在call方法前先定義int數(shù)組,到時(shí)候傳遞的話就是直接把整個(gè)數(shù)組個(gè)發(fā)過(guò)去了 哦對(duì)了,這個(gè)和我們之前那個(gè)pass by value 有一個(gè)很重要的區(qū)別 當(dāng)我們調(diào)用一個(gè)方法的時(shí)候改變的是變量的值而不是變量本身 但是我們把Array傳遞到其他方法的時(shí)候,我們可以在傳遞的時(shí)候會(huì)加上具體的數(shù)字,比如 printArray(new int[] {1, 2, 3, 4, 5}); 或者也可以直接使用 printArray (a); 來(lái)將數(shù)組直接顯示出來(lái) (看起來(lái)之前那個(gè)有些麻煩) 這樣子就能將數(shù)組傳遞到別的方法里,然后數(shù)組在方法內(nèi)部進(jìn)行了修改,意味著數(shù)組本身就被修改了 我們把數(shù)組傳遞給方法的時(shí)候,可以被描述為 pass by-sharing 即通過(guò)分享的方式進(jìn)行傳遞,意味著array所指代的東西被分享給了調(diào)用的方法。哦對(duì)了,方法內(nèi)部的數(shù)組和被傳遞過(guò)去的被調(diào)用的數(shù)組是同一個(gè)數(shù)組 這個(gè)和數(shù)值在方法之間的傳遞有著根本的區(qū)別 所以我們?cè)诜椒▋?nèi)部改變其內(nèi)容的時(shí)候,數(shù)組的內(nèi)容是真的被改變了的 當(dāng)我們回到主方法再調(diào)用其的時(shí)候,其內(nèi)容是真的被改變了的 [scode type="green"]Heap 堆[/scode] 我們之前講過(guò)一個(gè)Stack 棧 的概念 這玩意是后進(jìn)先出,就像往桶子里放東西一樣 如果要拿出來(lái)的話都是先拿最上面的,也就是后進(jìn)來(lái)的 但是Heap 堆 這玩意就有點(diǎn)點(diǎn)不同了 這個(gè)像個(gè)管子,先進(jìn)來(lái)的就會(huì)先出去
[scode type="green"]Return an Array from a Method 把數(shù)組作為一個(gè)返回值 [/scode] 我們不止可以用一個(gè)返回值將結(jié)果從一個(gè)方法輸出出來(lái),也可以試試看數(shù)組 舉個(gè)栗子 public static int[] reserse (int[] list) //我們需要在方法頭定義我們需要返回一個(gè)數(shù)組 { int[] result = new int[list.length]; for (int i = 0, j = result.length - 1; i , list.length; i++, j--) { result[j] = list[i]; } return result; //這里返回一個(gè)數(shù)組 } 哦對(duì)了你知道什么是return 0 嘛 記得在C語(yǔ)言里面,call一個(gè)方法是必須要Return的,如果沒(méi)啥可返回的話,那就Ruturn 0 但是在Java中,如果沒(méi)啥可返回的話,那就在方法頭那里定義為void就可以了 但是在需要返回東西的方法里面,方法頭定義void的話是一定會(huì)報(bào)錯(cuò)的 舉個(gè)栗子,比如我們需要返回一個(gè)一維數(shù)組 那我們方法頭就應(yīng)該寫 int[] [scode type="green"]Searching Arrays 數(shù)組的搜尋[/scode] 搜尋和排序是計(jì)算機(jī)里的非常重要的內(nèi)容,在未來(lái)我們會(huì)學(xué)習(xí)一門磚門的課程來(lái)詳細(xì)講解 這里我們需要有一個(gè)基本的了解 我記得上學(xué)期CC在一開(kāi)學(xué)就講過(guò)這個(gè)東西,還是熟悉的PPT還是熟悉的內(nèi)容 就是在一堆名字中找到一個(gè)指定的名字 首先將名字按照首字母排序完成,然后按照二分搜索 Binary Search 來(lái)搜索 [scode type="green"]The Linear Search Approach 線性查找法[/scode] 說(shuō)白了就是按順序 sequentially 的 依次比較數(shù)組中的元素 我們只需要用一個(gè)循環(huán)去查找就行了就是把數(shù)組里的元素一個(gè)一個(gè)和我們的關(guān)鍵字進(jìn)行對(duì)比 然后返回結(jié)果 就算沒(méi)匹配到也要返回結(jié)果 舉個(gè)栗子 public class LinearSearch public static int linearSearch(int[] list, int key) { for (int i = 0; i < list.length; i++) { if (key == list[i]) { return i; } return -1; } } 如果能找到的話,就返回指定數(shù)字位于數(shù)組中的第幾位 然后如果找不到的話,就返回一個(gè)指定的數(shù)字,當(dāng)然這個(gè)數(shù)字我們可以自定義的 然后我們?cè)贛ain里面只需要call一下這個(gè)方法就可以了 比如 int i = linearSearch(list, 4); 其返回值應(yīng)為 1,意識(shí)是找到了,在數(shù)組的第二位 哦對(duì)了,這里再?gòu)?qiáng)調(diào)一下,數(shù)組是從0開(kāi)始計(jì)算的! [scode type="green"]The Binary Search Approach 二分查找法[/scode] 如果我們想使用二分查找法的話,這個(gè)方法會(huì)更快一點(diǎn) 所謂的二分法就是 先將現(xiàn)有數(shù)據(jù)排序 must already be ordered ,然后將數(shù)據(jù)的中間值和關(guān)鍵字做對(duì)比 如果在數(shù)據(jù)中間值之前,那就搜索中間值往上的內(nèi)容,往下的內(nèi)容就不考慮了 在中間值往上的內(nèi)容中,取中點(diǎn)在進(jìn)行一次運(yùn)算和取值 這樣子就有點(diǎn)像2的多少次方的感覺(jué) 因?yàn)槎际且话胍话氲貋?lái)做 這樣子能夠大大提高搜索的效率 這個(gè)方法叫做二分查找法
package binarySearch; import java.util.Scanner; public class TestBinarySearch { public static void main(String[] args) { int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79}; Scanner input = new Scanner(http://System.in); int num = input.nextInt(); int i = binarySearch(list, num); if(i >= 0) { System.out.println("Found " + list[i] + ". Its index is " + i); } else { System.out.println("Not found."); } input.close(); } public static int binarySearch(int[] list, int key) { int low = 0; int high = list.length; //取數(shù)組最大位數(shù)為最大循環(huán)數(shù) while(high >= low) //這里是啟用一個(gè)循環(huán),循環(huán)內(nèi)部是最大數(shù)和最小數(shù) { int mid = (low + high) / 2; //取中位數(shù) if(key < list[mid]) //比較中位數(shù)和關(guān)鍵字的位置 { high = mid - 1; //縮小取值范圍,將中位數(shù)的前一位數(shù)設(shè)置為最大值 } else if (key == list[mid]) //直到找到與關(guān)鍵字相匹配的中位數(shù)為止 { return mid; } else { low = mid + 1; } } return -1; } } [scode type="green"]Sorting Arrays 選擇排序[/scode] 真的,當(dāng)我看到老師放的這個(gè)視頻的時(shí)候,我就知道已經(jīng)沒(méi)有說(shuō)太多的必要了 直接點(diǎn)擊視頻就可以看了 一個(gè)視頻勝過(guò)千言萬(wàn)語(yǔ) 那么問(wèn)題來(lái)了,如何使用代碼實(shí)現(xiàn)這個(gè)操作呢? 開(kāi)整: package selectionSort; public class TestSelectionSort { public static void main(String[] args) { int [] list = {34, 13, 5, 25, 56, 21, 59, 85, 2, 43}; selectionSort(list); for(int i: list) { System.out.println(i + ""); } } public static void selectionSort(int[] list) { for (int i = 0; i < list.length - 1; i++) { int currentMin = list[i]; int currentMinIndex = i; for (int j = i = 1; j < list.length; j++) { if (currentMin > list[j]) { currentMin = list[j]; currentMinIndex = j; } } if (currentMinIndex != i) { list[currentMinIndex] = list[i]; list[i] = currentMin; } } } } 其實(shí)說(shuō)到排序方法的話 還是用一個(gè)視頻來(lái)講比較好 這樣子可以說(shuō)簡(jiǎn)單明了了 (我感覺(jué)最后那個(gè)好好玩啊哈哈哈哈哈哈哈) 就有那種嗚啦啦啦啦啦~的感覺(jué) Chapter 8: Multidmensional Arrays 我們之前講過(guò)一維數(shù)組,關(guān)于一維數(shù)組的概念這里就不BB啦 實(shí)在是記不得里的話可以向上看看 現(xiàn)在我們來(lái)講講二維數(shù)組 [scode type="green"]Introduction 簡(jiǎn)介[/scode] 這個(gè)時(shí)候可能就有人要來(lái)問(wèn)了,我們?yōu)樯兑獙W(xué)這玩意列? 其實(shí)我也不知道(小聲) 但柿!根據(jù)可靠消息,我們可以在以后用這個(gè)來(lái)處理矩陣 再往深?yuàn)W一點(diǎn)的意義來(lái)講的話 計(jì)算機(jī)圖形學(xué)里面,一張圖片的所有信息能用一個(gè)二維矩陣全部裝下去 (我估計(jì)可能使用數(shù)字表示顏色,用二維矩陣來(lái)表示坐標(biāo)像素點(diǎn)位置) 總之就是非常重要(揚(yáng)聲器最大聲) 老樣子我們先來(lái)看看二位數(shù)組的語(yǔ)法 double [] [] sample = { {2, 2}, {2, 2} }; 這里有幾點(diǎn)需要注意的
一般的,我們使用兩個(gè)中括號(hào)來(lái)表示這個(gè)是個(gè)二維數(shù)組 [scode type="green"]Two-Dimensional Arrays Basics 二維數(shù)組的入門到放棄[/scode] 這里首先來(lái)講講數(shù)組的命名規(guī)則 int [] [] matrix;//declare the matrix matrix = new int 5;//fu zhi the matrix 二維數(shù)組的創(chuàng)建和一維數(shù)組的創(chuàng)建總是有無(wú)限的接近 不過(guò)后面那兩個(gè)中括號(hào)可大有講究 第一個(gè)中括號(hào)表示行 第二個(gè)中括號(hào)表示列 這個(gè)順序是無(wú)法被改變的 哦對(duì)了,這里有個(gè)很坑的地方,就是 emmmmmmm...... 得了我感覺(jué)我不懂怎么表達(dá) 還是用圖片來(lái)說(shuō)比較好
你看括號(hào)內(nèi)的是5,但是這個(gè)數(shù)組最高的就是到4而已 因?yàn)閿?shù)組是從0開(kāi)始噠! 在看到上面那個(gè)圖片的第三個(gè)數(shù)組 這個(gè)就是直接把創(chuàng)建個(gè)命名弄到一起去了 不過(guò)記得前面提到過(guò)的創(chuàng)建數(shù)組的幾個(gè)點(diǎn) 那么如果我們想知道數(shù)組的長(zhǎng)度呢? 這里可以使用 x.length 來(lái)獲取 不過(guò)在二位數(shù)組里,我們不止想知道數(shù)組有多少行,還想知道數(shù)組有多少列呢? 這里可以用 x [0].length 來(lái)獲取 簡(jiǎn)單的來(lái)說(shuō),想要多少行就直接用 x.length,想要多少列就直接用 x[0].length 我估計(jì)這玩意用在考試?yán)锟隙ê芩崴?[scode type="green"]Ragged Arrays 鋸齒狀數(shù)組[/scode]
一張圖片解決戰(zhàn)斗 這個(gè)是說(shuō)明如何創(chuàng)建這個(gè)數(shù)組的 并且這里說(shuō)明了一個(gè)很重要的一點(diǎn) 二位數(shù)組的每一行都可以是不一樣的 他們每一行都是一個(gè)獨(dú)立的一維數(shù)組 不過(guò)可能有人說(shuō),不喜歡上面的這個(gè)創(chuàng)建的方法,希望能有更厲害的方法呢? 這里有個(gè)可以讓代碼看起來(lái)更厲害的方法 int[][] triangeArray = new int5; triangleArray[0] = new int5; triangleArray1 = new int4; triangleArray2 = new int3; triangleArray3 = new int2; triangleArray4 = new int1; 這樣子其實(shí)達(dá)到的效果和上面那個(gè)是一樣的 這里看到上面在定義數(shù)組的時(shí)候,多少列這里是留空的 也就意味著這玩意可以不寫 我們?cè)诤竺嬖偃ヂ暶骶涂梢粤?我們可以通過(guò)一個(gè)小程序來(lái)簡(jiǎn)單的了解數(shù)組應(yīng)該如何正確食用 package multi; import java.util.Scanner; public class TestArray { public static void main(String[] args) { //declare, create, assign //method 1 int[][] matrix; matrix = new int[3][42]; //matrix 2 int [][] matrix2 = new int[3][43]; //method 3 int[][] matrix3 = { {1, 2}, {3, 4}, {5, 6} }; //1. Initializing arrays with input by user Scanner input = new Scanner(System.in); System.out.println("Enter " + matrix.length + " rows and " + matrix[0].length + "colums interger numbers:"); for (int i = 0; i < matrix.length ; i++) { for (int j = 0; j< matrix[0].length; j++) { matrix[i][j] = input.nextInt(); } } //2.Printing arrays for (int i = 0; i < matrix.length ; i++) { for (int j = 0; j< matrix[0].length; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); } //3. Summing all elements //4. Summing elements by column for (int column = 0; column < matrix[0].length; column++) { int total = 0; for(int row = 0; row < matrix.length; row++) { total = total + matrix[row][column]; } System.out.println("The Sum of this column " + column + " is " + total); } } } [scode type="green"]Processing Two-Dimensional Arrays 把二位數(shù)組作為參數(shù)傳遞到不同方法中[/scode] emmmm....... 這玩意和一維數(shù)組的完全一樣 感覺(jué)不想多BB了 直接看前面的把 pass by sharing的概念都是一樣的 Chapter 9: Object and classes 之前咱們講了半天,歸根結(jié)底還是一句話 --找不到對(duì)象 這句話在現(xiàn)實(shí)中也是很實(shí)用的 (:з」∠) [scode type="green"]Defining Class for Object 定義[/scode] Object-oriented programming (OOP) 對(duì)象編程 一個(gè)對(duì)象可以表示顯示生活中的實(shí)體entity 這些實(shí)體都有一些獨(dú)特的一些特征,比如狀態(tài)之類的 雖然所有的貓都是貓,但是卻不是同樣的實(shí)體 比如CC的貓,所有的貓都有不同的貓 因?yàn)樗麄冇幸恍┨囟ǖ膶傩?#xff0c;一些特定的行為 比如最喜歡的是何物,毛發(fā),年齡之類的 這就意味著每一個(gè)貓都是獨(dú)一無(wú)二的對(duì)象 但是這些貓都屬于同一個(gè)種類,這個(gè)就叫類Class
數(shù)據(jù)域 data files 數(shù)據(jù)域用來(lái)表示這一個(gè)類所有的對(duì)象的屬性 方法 Method 表示這一個(gè)類的對(duì)象的行為,也就是他所做的事情 一個(gè)對(duì)象擁有非常獨(dú)特的特征,比如它會(huì)在晚上12點(diǎn)的時(shí)候起來(lái)去看看家里有沒(méi)有老鼠 反正我是沒(méi)見(jiàn)過(guò)抓老鼠的貓 可能我看的都是假貓 類 Class 記得我們之前說(shuō)過(guò),所有的貓都可以被定義為“貓”這個(gè)類 類是一個(gè)藍(lán)圖,是一個(gè)抽象的概念 它定義了有著相同屬性的對(duì)象 而對(duì)象是類的一個(gè)實(shí)例 An object is an instance of a class 那么問(wèn)題來(lái)了,是先有類還是先有對(duì)象呢? 答案是先有類 因?yàn)檎也坏綄?duì)象... 好了言歸正傳,我們把用類轉(zhuǎn)換為實(shí)例的過(guò)程稱之為 實(shí)例化 Instantiation ,就是通過(guò)類來(lái)生成這么一些對(duì)象的這個(gè)過(guò)程 下面我們來(lái)看一個(gè)栗子
這是個(gè)關(guān)于幾何圖形的小程序,在未來(lái)很多的編程類型中,我們會(huì)基于這一個(gè)基礎(chǔ)來(lái)發(fā)展開(kāi)來(lái) 幾何圖形有很多種不同的類型,假如是一個(gè)特定的圖形,那他們都會(huì)有一個(gè)相同的特征 今天我們先來(lái)看看圓形 看到上面的object 1、2、3,這3個(gè)方法都屬于上面這個(gè)circle這個(gè)類 然后所有object中不同的區(qū)別就是在于圓的半徑 這里圓的半徑Radius叫做這個(gè)圓的數(shù)據(jù)域 data files 假如我們先創(chuàng)建出來(lái)一個(gè)小圓,當(dāng)我們把這個(gè)圓放大的時(shí)候,實(shí)際的動(dòng)作其實(shí)是改變這個(gè)圓的半徑 假如我們需要計(jì)算這個(gè)圓的半徑、周長(zhǎng),這里都是用方法來(lái)實(shí)現(xiàn)的 這里可能有人要問(wèn)了,如何用代碼來(lái)實(shí)現(xiàn)這個(gè)看起來(lái)很不錯(cuò)的功能呢? class Circle //這里注意,類的首字母需要大寫 { //data fields or data members double radius; //constructors //default constructor Circle() { radius = 1; } //the second constructor Circle(double newRadius) { radius = newRadius; } //methods double getArea() { return radius * radius * Math.PI; } double getPerimeter() { return 2* radius * Math.PI; } double setRadius(double newRadius) { radius = newRadius; } } 這玩意感覺(jué)是C語(yǔ)言... 哦對(duì)了,有時(shí)候我們可能會(huì)看到一個(gè)玩意,叫UML Unified Modeling Language (UML) 統(tǒng)一建模語(yǔ)言,一般會(huì)以縮寫的形式存在 這玩意就是大家遵循這樣的規(guī)則來(lái)對(duì)某個(gè)事情進(jìn)行概括
哦對(duì)了,這里有個(gè)玩意叫 Constructors 構(gòu)造方法 A constructor is invoked to create an object using the new operator 構(gòu)造方法是用來(lái)生成一個(gè)用來(lái)生成一個(gè)屬于這個(gè)類的對(duì)象 類似于普通的方法一樣,我們可以調(diào)用這個(gè)構(gòu)造方法 但是調(diào)用構(gòu)造方法的目的和作用就是生成一個(gè)屬于這個(gè)類的對(duì)象 構(gòu)造方法有3個(gè)特征: [scode type="blue"]
[/scode] 那么可能有人要問(wèn)了,這個(gè)有什么意義呢? 出現(xiàn)了!一意義怪! 其實(shí)我也不知道(攤手) 下節(jié)課再說(shuō)唄 哦對(duì)了,當(dāng)我們寫完了程序之后,我們能在電腦中找到這個(gè)玩意的源文件 至于文件保存在什么地方的話,就是在創(chuàng)建的時(shí)候設(shè)置的地方 然后編譯器也會(huì)把我們所寫的源文件編寫為.class文件 Java會(huì)直接去執(zhí)行編譯完成的.class文件而不會(huì)去執(zhí)行java源文件 [scode type="green"]Via Reference variables[/scode] 哦對(duì)了 不知道你注意到?jīng)]有 前面那個(gè)代碼,好像沒(méi)有main 記得之前Cc說(shuō)過(guò),所有程序的開(kāi)頭永遠(yuǎn)是從main方法開(kāi)始的 但是前面這個(gè)沒(méi)有 那我們就需要再創(chuàng)建一個(gè)main方法出來(lái) 所以我們?cè)谏弦粋€(gè)pacage內(nèi)再創(chuàng)建一個(gè)class 取名為TestCircle(再提一次,類的首字母要大寫) 然后這里就可以勾上最喜聞樂(lè)見(jiàn)的Main方法了 pacage circle; public class TestCircle { public static void main(String[] args) { //int radius; Circle circle1 = new Circle(); //calling the constructor of Circle Class System.out.print(circle1.radius); System.out.println(circle1.grtAtea()); System.out.println(circle1.getPerimeter()); //get method form class Circle circle1.radius = 100; System.out.println(circle1.getArea()); circle.setRadius(10000); System.out.println(circle1.getArea()); //we can change the value in constructor Circle circle2 = new Circle(20.000); //calling the second construction of Circle Class System.out.print(circle2.radius); System.out.println(circle2.grtAtea()); } } 首先我們先把視線放在 Circle circle1 = new Circle(); 這一行上 先來(lái)對(duì)比這兩行代碼 int[] array = new int10; Circle circle1 = new Circle(); 可以看到,和創(chuàng)建數(shù)組的語(yǔ)句類似,創(chuàng)建和引用構(gòu)造方法是非常類似的 我們首先需要先聲明這個(gè)是個(gè)什么類的,當(dāng)然這個(gè)類是我們已經(jīng)自定義的了 其實(shí)Circle circle1 = new Circle();這玩意可以拆分為兩行 Circle circle1; circle1 = new Circle(); 當(dāng)然這個(gè)和數(shù)組的也是非常類似 因?yàn)閿?shù)組也能拆分為兩行 int[] array; array = new int10; 然后circle1這個(gè)是可以自定義的名字,有個(gè)更專業(yè)的名字叫 Reference Vriable ,雖然專業(yè)名字更讓人看不懂,但是這也不影響我們可以給circle1取什么名字都可以,但是要遵循命名規(guī)則 比如iLikeLion 首字母小寫,其后每個(gè)單詞首字母都需要大寫 之后的那個(gè)new是一個(gè)特定的操作符,后面接著的是構(gòu)造方法,用來(lái)生成一個(gè)對(duì)象 Circle() 表示調(diào)用 類 Circle 構(gòu)造方法 這里有一點(diǎn)值得注意,當(dāng)我們使用Circle(100)的時(shí)候,表示向方法中傳遞數(shù)字,這里就不會(huì)使用Circle()這個(gè)方法,而會(huì)使用 Circle(double radius)這個(gè)方法 這里我們引入一個(gè)概念: instance 實(shí)例的 對(duì)象是類的實(shí)例化 這個(gè)概念還是蠻重要的 舉個(gè)栗子,instance vaiable實(shí)例變量 ,比如我們前面那個(gè)小程序中的半徑就是實(shí)例變量 instance method 實(shí)例方法,比如我們前面的getArea方法,因?yàn)檫@個(gè)方法都是由某一個(gè)具體的對(duì)象所決定的 換句話說(shuō),當(dāng)圓的半徑改變的時(shí)候,getArea得出來(lái)的值也會(huì)隨之改變 [scode type="green"]Call method from another package[/scode] 假如有一天,我們想引入其他package里面的類甚至是類里面的方法,是否有這個(gè)操作呢 我們可以使用import 來(lái)實(shí)現(xiàn)這樣的操作 這個(gè) 詞我們之前也曾提到過(guò) 就是import java.util.Scanner這個(gè) 講道理這兩個(gè)東西真的是太相似了 舉個(gè)栗子
在上面這張圖中,假如為我們想在rectange里調(diào)用circle里的東西呢 只需要使用 import circle.Circle; 就可以了 import //導(dǎo)入 circle. //來(lái)自package circle Circle //package circle 里的 類Circle 但是,當(dāng)你引用了這個(gè)東西,它或許還會(huì)報(bào)錯(cuò) 畢竟報(bào)錯(cuò)就是java的靈魂 沒(méi)有報(bào)錯(cuò)的java是不完成的java 這個(gè)是因?yàn)槲覀冎霸趯戭怌ircle的時(shí)候,里面的構(gòu)造方法沒(méi)有設(shè)定為publie 簡(jiǎn)單的來(lái)說(shuō),如果不加public的話,這個(gè)method就是僅限內(nèi)部員工使用的 當(dāng)我們給類Circle的構(gòu)造方法Circle() 加上public 之后,它應(yīng)該變?yōu)檫@樣 public Circle() { } 這樣就沒(méi)問(wèn)題了 哦對(duì)了,雖然說(shuō)一個(gè)Java源文件中能包含多個(gè)類,但是public這玩意也不能亂用 [scode type="red"] "one or more classes in one java file. But only one class coule be defined as 'public' "
- 每個(gè)類里面只能有一個(gè)public
"the public class's name should be exactly same as the file name"
- 有public的類必須和類的名字相同(就是左邊那個(gè)列表里出現(xiàn)的類的名字)
"main() will be put inside a public class , public class is like a string point"
- main()里的public是不可少的,也就是說(shuō)在main方法所在的類必須要加public
" if there is no public class, then your main method coule be put in any one class. but if there is a public class, your main method must be in the public class"
- 如果一個(gè)源文件中沒(méi)有public類的話,那main()放在哪個(gè)類里面都是ok的。但是程序中有一個(gè)public類的話,主方法必須要放在public類里面
[/scode] 用一張圖來(lái)總結(jié)類和對(duì)象的關(guān)系
[scode type="green"]different between Cariables of Primitive Types and Reference Types[/scode] 這里要撤回去一個(gè)概念,我們回到原始數(shù)據(jù)類型 primitive type 原始數(shù)據(jù)類型一共有8種,int, double ,float, char, boolean, byte, short, long 對(duì)于原始數(shù)據(jù)類型,我們?yōu)槠滟x值的時(shí)候,其實(shí)就是用所需要的的值去覆蓋去替換掉原始數(shù)值 假設(shè)我們寫了一條指令 int i = 1; 這個(gè)實(shí)際上就是在我們電腦內(nèi)存中,有這么一個(gè)棧,這個(gè)棧存放了我們寫這一行代碼的信息 同時(shí),int會(huì)被賦值為1,這也就意味著在電腦存放 i 這個(gè)位置的地方會(huì)被 1 所代表的值所取代 那么現(xiàn)在的類和對(duì)象的概念有啥不同呢 記得之前在第七章數(shù)組這個(gè)概念中,提到過(guò)數(shù)組的賦值方法是 pass by sharing 也就是箭頭和倉(cāng)庫(kù)(地址)的問(wèn)題(詳情可以在右邊找Chapter7 ) 雖然數(shù)組會(huì)被賦值但是原始數(shù)組并沒(méi)有消失,只是沒(méi)有指向這個(gè)數(shù)組的標(biāo)志了 其實(shí)類的在電腦桌存放的概念和數(shù)組非常相似 這玩意叫 Reference Type
當(dāng)我們將c2的值賦值給c1的時(shí)候,c1將會(huì)指向c2所在的那個(gè)倉(cāng)庫(kù)(address) 但是實(shí)際上c1原來(lái)所指代的那個(gè)倉(cāng)庫(kù)還是保留在內(nèi)存中的 我們改變的就是c1所指代的位置 [scode type="green"]Static Variables, Constants, Methods[/scode] static,靜態(tài)的 static variables 靜態(tài)的變量 static constant 靜態(tài)的常量 static method 靜態(tài)的方法 那么到底什么是靜態(tài)的呢? 我們來(lái)舉個(gè)例子,假如一群人去吃火鍋,我往里面瞎了眼一份牛肉丸 那么這些肉丸大家都可以吃得到,因?yàn)槲覀兪浅缘耐粋€(gè)火鍋 static 但是如果是一人一個(gè)小鍋,我往我自己的鍋里面下了一份牛肉丸,那么這一份牛肉丸就是我自己獨(dú)有的 private 這里就是借助牛肉丸的概念來(lái)理解static的意思 static是能被所有對(duì)象共享的,所有的方法都可以訪問(wèn)它
記得之前在寫圓的面積周長(zhǎng)啥的時(shí)候,我們有一個(gè)圓的半徑,就是 π 這個(gè)玩意 π 需要被多個(gè) method 共同使用,但是卻沒(méi)有任何東西能改變它的大小 這個(gè)時(shí)候, π 就是一個(gè)靜態(tài)的常量 static constant 所以我們可以在代碼的第一行中加入 final static double PI = 3.1415926; 來(lái)給定 π 的值 這樣我們?cè)诤竺娴拇a中就不需要使用math.PI了,就可以直接使用PI 接下來(lái)我們來(lái)看看靜態(tài)的變量 static variables 假如我們需要一個(gè)變量來(lái)記錄這個(gè)程序到底執(zhí)行了多少次 雖然只需要使用count++就能解決的事情 但是這個(gè)變量還是有類型的 這個(gè)類型就是靜態(tài)的變量 比如我們?cè)趫?zhí)行完方法1后,使用count++來(lái)記錄方法1執(zhí)行的次數(shù) 這個(gè)時(shí)候我們?nèi)?zhí)行方法2,但是也使用count++來(lái)記錄方法2的執(zhí)行次數(shù) 在這里方法1和方法2使用的都是同一個(gè)count來(lái)記錄的 這一個(gè)變量它不是僅僅依賴于某一個(gè)具體的源變量本身,而是被所有的源對(duì)象共享的 我們把這樣的變量叫做 static variables 因?yàn)檫@個(gè)變量是被這個(gè)類所共享的,所以也能叫類變量 class variable 在創(chuàng)建靜態(tài)變量的時(shí)候,我們可以使用 static int circleNumber = 0; //如果我們最開(kāi)始不定義其為0的話,它會(huì)默認(rèn)賦值為int類的初始值,也就是0 說(shuō)到static method, 感覺(jué)也挺簡(jiǎn)單的 這玩意創(chuàng)建的方法就是 static int getNumberObjects() { return numberOfObjects; } 沒(méi)了 不過(guò)值得注意的一點(diǎn)是,我們?nèi)绻M赨ML中表示出這個(gè)方法是靜態(tài)的方法的話,需要在其下加一條下劃線 同樣在變量中也是一樣的,加了下劃線的表示靜態(tài)的變量 用圖表示的話就像這樣
那么,對(duì)于靜態(tài)的方法和實(shí)例的方法有什么區(qū)別呢? 簡(jiǎn)單的來(lái)說(shuō),實(shí)例的方法可以訪問(wèn)這個(gè)類的所有的方法和變量(數(shù)據(jù)域) 但是靜態(tài)的方法被設(shè)計(jì)為只能訪問(wèn)靜態(tài)的方法和變量(數(shù)據(jù)域),不能調(diào)用實(shí)例的方法和實(shí)例的變量 我們之前提到過(guò),靜態(tài)的變量是屬于這個(gè)類的方法都可以訪問(wèn)的數(shù)據(jù)域,它的值可以被所有方法更改 而靜態(tài)的方法就像是專業(yè)為靜態(tài)變量而生的,它們會(huì)對(duì)這些靜態(tài)的變量進(jìn)行一系列的操作來(lái)打到目的 比如獲得某個(gè)變量的值getNumber 而那些實(shí)例的變量來(lái)說(shuō),它們的值是隨時(shí)都可以改變的 舉個(gè)栗子,之前的圓的半徑的問(wèn)題 無(wú)論是圓1的半徑還是圓2的半徑,它們的值都是屬于它們自己的,都不是共享的 所以去訪問(wèn)它的不應(yīng)該是一個(gè)靜態(tài)的方法,因?yàn)殪o態(tài)的方法是大家共享的一個(gè)方法 靜態(tài)方法去訪問(wèn)一個(gè)實(shí)例變量的時(shí)候,由于實(shí)例變量往往是屬于某一個(gè)方法的,在訪問(wèn)的時(shí)候可能會(huì)出現(xiàn)最喜聞樂(lè)見(jiàn)的話 “找不到對(duì)象” 那我們還是舉個(gè)栗子吧 package classhomework; public class ClassHomework { int i = 5; static int k = 2; public static void main(String[] args) { int j = i; m1(); } public void m1() { i = i + k + m2(i , k); } public static int m2(int i, int j) { return (int)(Math.pow (i, j)); } } 上面這個(gè)有沒(méi)有問(wèn)題咧 答案在下面 [collapse status="false" title="答案"] package classhomework; public class ClassHomework { int i = 5; static int k = 2; public static void main(String[] args) { int j = i; //在這個(gè)方法前面,有個(gè)int i = 5 //這也就意味著i是一個(gè)實(shí)例變量 //但是這個(gè)方法里帶有static字眼,表示這玩意是個(gè)靜態(tài)方法 //我們之前提到過(guò),靜態(tài)方法不能調(diào)用實(shí)例變量 //所以我們這里是會(huì)報(bào)錯(cuò)的 m1(); //你看下面的方法m1中有沒(méi)有static字眼 //沒(méi)錯(cuò)我也沒(méi)找到 //所以m1方法是個(gè)實(shí)例方法 //然而這個(gè)主方法是個(gè)靜態(tài)的方法 //所以肯定是不行的 } public void m1() { i = i + k + m2(i , k); //你看這里可是個(gè)實(shí)例方法哦 //實(shí)例方法可調(diào)用一切 } public static int m2(int i, int j) { return (int)(Math.pow (i, j)); } } 那么問(wèn)題來(lái)了,如果說(shuō)我一定要在靜態(tài)方法里使用實(shí)例方法呢 package classhomework; public class ClassHomework { int i = 5; static int k = 2; public static void main(String[] args) { ClassHomework a = new ClassHomework(); //這里其實(shí)就是將靜態(tài)的方法指定為一個(gè)新的方法,然后再在其中作為新的變量插入 int j = a.i; a.m1(); } public void m1() { i = i + k + m2(i , k); } public static int m2(int i, int j) { return (int)(Math.pow (i, j)); } } 啊,這classhomework打的真是煩死了 下次起個(gè)短一點(diǎn)的名字 [/collapse] [collapse status="false" title="前情提要(關(guān)鍵詞復(fù)習(xí))"] primitive type variables 原始數(shù)據(jù)類型變量 reference type variables 引用類型變量 static ( variable / constant / method ) 靜態(tài)的 變量/常量/方法 static variable = class variable static constant ---> final static datatype name 靜態(tài)的方法和實(shí)例的方法是互相對(duì)比滴 [/collapse] [scode type="green"] access specifier 訪問(wèn)修飾符 [/scode] 寫在前面:access specifier 訪問(wèn)修飾符 也可以寫作 visibility modifiers 可見(jiàn)性修飾符 我們之前寫代碼的時(shí)候,第一條永遠(yuǎn)是 public static void main(String[] args) 但是好像沒(méi)人問(wèn)過(guò)這句話到底是啥意思 至少我是沒(méi)問(wèn)過(guò)的 因?yàn)槔蠋熆隙〞?huì)講嘛(攤手) 其實(shí)說(shuō)起訪問(wèn)修飾符的話,一共是這4個(gè) public 公共的 default 默認(rèn)的 private 私有的 provate 被保護(hù)的 這四個(gè)單詞都是用來(lái)表示某一個(gè)東西是否是可見(jiàn)的 說(shuō)白了就是在另外一個(gè)地方能不能訪問(wèn)到它 這四個(gè)關(guān)鍵詞都是用來(lái)修飾一個(gè)類的,或者是類內(nèi)部的變量、方法之類的 當(dāng)我們?cè)趯懘a的時(shí)候,我們可以使用不同的可見(jiàn)性修飾符來(lái)定義它 比如我們之前在寫圓這個(gè)代碼的時(shí)候,我們可以使用不同的修飾符來(lái)修飾其中不一樣的方法 一定要注意,這個(gè)能夠放在類和方法的前面 首先我們先來(lái)看 public public 和 static是不一樣的 雖然說(shuō)我們把使用static將方法設(shè)置為一個(gè)靜態(tài)的方法 也就是所有對(duì)象都能夠訪問(wèn)它 但是這并不意味著他是一個(gè)公開(kāi)的 這兩個(gè)單詞所表示的范疇是完全不一樣的 [scode type="blue"]
- static 是只能夠修飾方法,不能夠修飾類的
- static 的作用就是把某一個(gè)方法或者變量設(shè)定為當(dāng)前類都能夠訪問(wèn),當(dāng)這個(gè)變量的值改變的時(shí)候,會(huì)對(duì)當(dāng)前類產(chǎn)生影響
- public 當(dāng)給一個(gè)類設(shè)定為公共的之后,對(duì)于其他的類而言,這個(gè)類是可見(jiàn)的 。舉個(gè)栗子,我給圓這個(gè)類設(shè)定為public之后,當(dāng)我創(chuàng)建一個(gè)長(zhǎng)方形類的時(shí)候,對(duì)于長(zhǎng)方形這個(gè)類來(lái)說(shuō),圓這個(gè)類是可見(jiàn)的。意味著在長(zhǎng)方形類里面可以使用Circle cc = new circle; 去訪問(wèn)和調(diào)用圓類的代碼來(lái)創(chuàng)建一個(gè)對(duì)象
- public 假如我有一瓶肥宅快樂(lè)水,當(dāng)我將這瓶肥宅快樂(lè)水設(shè)定為public之后,就意味著是共享肥宅快樂(lè)水了
[/scode] [scode type="blue"]
- default 當(dāng)我們沒(méi)對(duì)類進(jìn)行詳細(xì)定義的時(shí)候,也就是說(shuō)類前面是個(gè)光頭的時(shí)候,就意味著它會(huì)默認(rèn)地使用default
- default 并不用可刻意地寫在方法前面,當(dāng)我們沒(méi)有這3個(gè)字的時(shí)候,它就會(huì)默認(rèn)為default
- default 當(dāng)一個(gè)類被設(shè)定為default的時(shí)候,其會(huì)被默認(rèn)為 package-private包內(nèi)訪問(wèn),也就意味著能夠在一個(gè)包內(nèi)互相訪問(wèn)。換句話說(shuō) ,隔壁包就無(wú)法被訪問(wèn)了
[/scode] [scode type="blue"]
- private 這玩意用來(lái)修飾類內(nèi)部的變量或者方法,并不會(huì)修飾一個(gè)類
- private 因?yàn)榘杨愒O(shè)定為私有的話好像就沒(méi)啥意義了
- private 可能就是用來(lái)保護(hù)啥東西了的
[/scode] private 這里就不多BB了 感覺(jué)以后肯定是超級(jí)麻煩的茬 能咸魚一天算一天 [scode type="green"]Private and public in UML[/scode] 那么,在UML中又該怎么表示呢? 讓我猜猜,肯定有人忘了UML是啥 [collapse status="false" title="UML答案--點(diǎn)開(kāi)了自覺(jué)抄10遍"] Unified Modeling Language 統(tǒng)一建模語(yǔ)言 [/collapse] 其實(shí)也挺簡(jiǎn)單的 如果是private 的話就在方法前加個(gè)減號(hào),就像 - 這樣 反過(guò)來(lái)如果是public 的話就在方法前加個(gè)加號(hào),就像 + 這樣 整體來(lái)看的話就像這樣
[scode type="green"]Data Field Encapsulation 數(shù)據(jù)域封裝[/scode] 這里說(shuō)到了蟲子(BUG)攻擊 據(jù)說(shuō)電腦BUG之所以叫BUG是因?yàn)樽钤嫉碾娔X真的會(huì)被一直蟲子搞的BUG出來(lái) 不過(guò)今天的可不像以前那樣了 今天我們講究安全性 當(dāng)我們?cè)趯懗绦虻臅r(shí)候,一般都要有一種意識(shí),就是別人不能隨隨便便改我的程序 就算我留有接口給別人調(diào)用都好,但是本應(yīng)該屬于程序的變量時(shí)不會(huì)改變的 所以這里就涉及到一個(gè)東西,叫 Encapsulation 封裝 說(shuō)白了就是組裝好了的機(jī)械,能夠正常的去運(yùn)行,但是你并不知道機(jī)械內(nèi)部到底是什么歌情況,也不允許查看其中的東西 當(dāng)我們?cè)诿恍┓椒ǖ臅r(shí)候,一般可以用 getter 和 setter 來(lái)對(duì)其進(jìn)行命名 getter 就是當(dāng)我們想獲得一些私人的變量的值的時(shí)候,需要寫的一個(gè)特定的方法來(lái)獲得這個(gè)變量的值 setter 也是針對(duì)私有的數(shù)據(jù)域或者改變它的值,才會(huì)被稱為setter [scode type="green"]Passing Objects To Methods [/scode] 其實(shí)我們可以通過(guò)一個(gè)小栗子來(lái)簡(jiǎn)單地理解 package circle; public class TestPassCircle { public static void main(String[] args) { Circle cc = new Circle(10); int n = 5; printAreas(n , cc); System.out.println ("After calling method:"); System.out.println("Radius is " + cc.getRadius()); System.out.println("n is " + n); } public static void printAreas (int times, Circle c) //先看到這里的這個(gè)Circle C //我們需要在這個(gè)方法中接受一個(gè)來(lái)自類 Ciecle 的對(duì)象(c 變量為屬于類Circle ) //這里感覺(jué)就像是拿了一個(gè)Circle的變量來(lái)用,還是原封不動(dòng)的那種 { System.out.println("Radius tArea"); while(times >= 1) { System.out.println(c.getRadius() + "t" + c.getArea()); c.setRadius(c.getRadius() + 1); times--; } System.out.println("Radius is " + c.getRadius() + "n"); } } 這玩意輸出結(jié)果雖然有蠻多的,但是真正重要的就三行 balabalabala Radius is 15.0 After calling method: Radius is 15.0 n is 5 這里可真正體現(xiàn)了 pass-by-value 的精髓了 你看變量n 最開(kāi)始我們傳遞過(guò)去的時(shí)候,它的值是5 這個(gè)在傳遞的時(shí)候,是把變量的值,也就是10傳遞了過(guò)去,而不是傳遞變量本身 變量本身的值還是不會(huì)改變的 在方法內(nèi)部n的值因?yàn)檠h(huán)的原因每一次都在改變 但是無(wú)論n的值如何改變,主方法里n的值永遠(yuǎn)不會(huì)改變,也就是不會(huì)影響到主方法里的 這里得和數(shù)組在方法之間的傳遞區(qū)分開(kāi)來(lái) 我這里就不寫出來(lái)了不然看著也亂 數(shù)組就是pass-by-Sharing 具體是啥就回到數(shù)組哪兒去看看吧 [scode type="green"]array of object[/scode] 記得在之前的時(shí)候,我們講過(guò)如何創(chuàng)建一個(gè)int類型的數(shù)組 int[] arrayName = new int[ 10 ]; 那么你可能猜到了,為啥要在講對(duì)象的時(shí)候提到這個(gè)數(shù)組列 當(dāng)然是因?yàn)槲覀冇辛诉@個(gè)對(duì)象數(shù)組啦 和int類型的數(shù)組一樣,這個(gè)也能被簡(jiǎn)單地創(chuàng)建出來(lái) Circle[] circleArray = new Circle10; 對(duì)比一下之前的那個(gè),是不是非常的相似? 當(dāng)這個(gè)語(yǔ)句運(yùn)行完成之后,系統(tǒng)就會(huì)自動(dòng)分出一個(gè) Heap 堆 來(lái)存放這個(gè)玩意 只不過(guò)這個(gè)里面還是空的,也就是空值 因?yàn)樵谶@個(gè)時(shí)候數(shù)組確實(shí)是用來(lái)存放Circle類的對(duì)象,但是這個(gè)時(shí)候還沒(méi)被創(chuàng)建出來(lái) 所以這個(gè)時(shí)候我們需要使用一個(gè)循環(huán)來(lái)生成它們 這里要注意是生成生成,不是像之前那樣的直接賦值 舉個(gè)栗子 for(int i = 0; i < circleArray.length; i++) { circleArray[i] = new Circle(5); } 那么為啥之前交生成它們呢? 因?yàn)檫@個(gè)數(shù)組我們?cè)谧龅钠鋵?shí)是單純的付給它一個(gè) reference variables 就是給它了一個(gè)小倉(cāng)庫(kù)的地址 這樣子數(shù)組就能夠在每個(gè)位置指向?qū)儆谒约旱膫}(cāng)庫(kù)了
[scode type="green"]The Scope of Variable 變量的作用域[/scode] 我們之前確實(shí)講過(guò)變量的作用域 這里之所以再講一次是因?yàn)?一個(gè)類的代碼包含兩大部分,一個(gè)是這個(gè)類的數(shù)據(jù)成員 data fileds (或者可以叫類的變量 class's variables) 第二個(gè)部分是類的行為,就是類的對(duì)象的行為 不過(guò)值得一提的是,當(dāng)在類里面使用變量的時(shí)候,就算先用后聲明也是ok的 這些數(shù)據(jù)域的成員可以放在整個(gè)類的任何一個(gè)地方 可以是最開(kāi)始也可以是最后面都是ok的 舉個(gè)栗子 public class Circle { public double findArea() { return radius * radius * Math.PI; } private double radius = 1; } 你看在上面這個(gè)例子中,方法findArea位于類Circle中 但是我們是先用再聲明 這樣也不會(huì)報(bào)錯(cuò)的 但是有個(gè)問(wèn)題要注意一下 我們來(lái)看這樣一個(gè)例子 public class F { private int i; private int j = i + 1; } 如果是這樣的話它就會(huì)報(bào)錯(cuò) 因?yàn)閖的值是基于i的值的 所以在這種情況之下就不能交換它們之間的位置 在這里老師引入了一個(gè)很有趣的小栗子 這個(gè)栗子可以充分幫助我們理解變量的作用域的問(wèn)題 public class Test { private static int i = 0; private static int j = 0; public static void main(String[] args) { // TODO Auto-generated method stub int i = 2; int k = 3; { int j = 3; System.out.println("i + j is " + i + j); } k = i + j; System.out.println("k is " + k); System.out.println("j is " + j); } } [collapse status="false" title="小栗子答案"] 首先先來(lái)說(shuō)說(shuō)答案 i + j is 23 k is 2 j is 0 如果能正確地說(shuō)出答案的話那就沒(méi)必要看解析啦 當(dāng)然為此一次就是沒(méi)做對(duì)滴 很絕望 那個(gè) i + j 根本不按套路出牌 過(guò)分了過(guò)分了 public class Test { private static int i = 0; private static int j = 0; //這里的叫做類的變量class's variables //上面講過(guò),這句話無(wú)論放在這個(gè)類的前面和后面效果都一樣的 public static void main(String[] args) { int i = 2; int j = 3; //這里的就是考點(diǎn)了 //這里的兩個(gè)變量,如果在eclipse里面輸入的話,會(huì)發(fā)現(xiàn)它兩的顏色和上面的類變量不一樣 //因?yàn)樗麄儍蓚€(gè)的作用域不同 //這兩個(gè)的作用域就是僅僅限于這個(gè)block 塊的 //我們可以看到,優(yōu)先級(jí)還是以方法內(nèi)的優(yōu)先 //就算外面有個(gè)類變量,方法內(nèi)的變量還是被優(yōu)先考慮的 { int j = 3; //老師說(shuō)過(guò),變量的作用域表示的就是它所在的這個(gè)塊 block //然而區(qū)分每個(gè)塊的標(biāo)志就是花括號(hào) //這里會(huì)優(yōu)先以 j = 3 來(lái)計(jì)算 System.out.println("i + j is " + i + j); } k = i + j; //在上面的 j = 3 的作用域已經(jīng)完成,這里就不屬于它的作用域了 //所以我們往上找找,剩下的就只是類變量里的 j = 0了 //所以在這里j的值應(yīng)該為0 System.out.println("k is " + k); System.out.println("j is " + j); } } [/collapse] [scode type="green"]The this reference [/scode] 接下來(lái)我們來(lái)講一個(gè)關(guān)鍵字,這個(gè) 就是這個(gè) “這個(gè)” this this表示的就是某個(gè)變量 其實(shí)我們平時(shí)在寫代碼的時(shí)候都沒(méi)寫 this 這個(gè)關(guān)鍵字,是因?yàn)镴ava自動(dòng)幫我們加上去了 因?yàn)槊總€(gè)變量都得寫這玩意的話看著都煩 當(dāng)然寫上才是正確的姿勢(shì) 那么這個(gè)時(shí)候可能有人會(huì)問(wèn)了,有什么意義呢 還真有些時(shí)候必須要自己寫上 private double radius; public void setRadius (double radius) { radius = radius; } 你看這里就是個(gè)小栗子 雖然這樣子確實(shí)是不會(huì)報(bào)錯(cuò) 但是會(huì)有一個(gè)警告 因?yàn)镴ava根本不知道到底左邊的是啥右邊的是啥 這個(gè)時(shí)候就需要加個(gè)this了 我們將賦值語(yǔ)句改為 this.radius = radius; 用來(lái)表示左邊的這個(gè)是我們類的變量半徑,右邊的是接收到的 哦對(duì)了this還有個(gè)很高端的操作 因?yàn)樗陬惱锩婵梢灾复@個(gè)類本身 比如我們需要調(diào)用這個(gè)類的構(gòu)造方法的時(shí)候,我們就會(huì)使用 Circle(10); 但是用this來(lái)表示的話,可以寫成這樣 this(10); 表示的效果都是一樣的 Chapter 10: Object-Oriented Thinking Class absraction 類的抽象 class encapsulation 類的封裝 我們?cè)谟煤芏喾椒ǖ臅r(shí)候,很多時(shí)候我們都不知道這玩意到底該怎么用的 就是只知道怎么使用就行了 其實(shí)在Java世界里,所有的對(duì)象所有的方法都是會(huì)被寫在類里面的 我們?cè)趯懘a的時(shí)候往往都會(huì)先定義一個(gè)類出來(lái) 然后我們?cè)僭陬惱锩嫒懘a 所以我們之前討論到的方法的抽象和封裝實(shí)際上就是類的抽象和封裝 結(jié)束語(yǔ) 在這里感謝抽出寶貴時(shí)間幫我檢查筆記的CC Teacher~ 感謝網(wǎng)頁(yè)沒(méi)有在我碼字到一半的時(shí)候崩潰 感謝我的小博客 感謝自己高中買的咖啡豆還能喝還沒(méi)過(guò)期 還要感謝小獅子!!! 小獅子天下第一!!!!
- ----to be continue
總結(jié)
以上是生活随笔為你收集整理的面向对象程序设计_面向对象的程序设计(续)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ensp启动设备蓝屏_为什么早期的Win
- 下一篇: python numpy库安装winer