###### tags: `Java` # **初階Java筆記** # 模組9(方法)~模組21(使用繼承) ## 模組9_方法 ### 宣告規格 1.修飾存取方式 2.回傳值型別 3.方法名稱 4.傳入參數 ex:1.(public static) 2.viod 3.main 4.(String[] args){...} 參數可省略 不可巢狀宣告方法,每個方法須各自獨立,方法不分先後 ex: for(int i ;i<n;i++){ void abc(){} }此為錯誤 ### 方法呼叫 #### 呼叫不同類別 利用"."運算子來呼叫 ex: animal.show(); #### 呼叫同類別 直接呼叫 ex:在animal中可直接show(); ### 參數與回傳值 在worker method中可能有參數從calling method傳來 若無回傳值該方法需要以void當作回傳型別 若有回傳值則需要有"return"回傳至calling method且需用適當的型別接值 ### 方法覆載(Overloading) 可以用相同方法名稱定義,但需要有以下規定條件其一成立: 1.參數數目不同 2.不同的資料型別 ex: 1.show(int i),show (int i,int j) 2.println(int i), print (String s) 注意!!!!!!!!!!!!!!! 無法根據回傳型態當區別 ex: void show(int i); int show(int i);此為錯誤 補充 會依傳入參數之型別先找完全相容之方法,若無則找可相容 java中API之所以方便也是使用overloading ex: println(); ## 模組10_認識物件 ### 類別與物件 物件必有兩特徵 1.屬性 2.行為 java透過class實現物件 類別組成成員 資料成員 方法成員 ex:貓科的毛色、體重、品種為屬性 貓科會吃、會睡、會叫為行為 先設計類別才能產生物件,物件為某類別產生的一個實體 可用一種類別產生不同的物件實體 ex:黑豹,石虎,寵物貓 ### 物件操作 #### 實體化與初始化物件 宣告 實體化物件 初始化物件 Cat meow = new Cat();//解析成以下 Cat meow; //宣告 new Cat(); //實體化物件 產生物件之記憶體空間,需透過new關鍵字建立 meow = new Cat(); //初始化物件 用=(指定運算子)將物件指派至物件參考變數 注意!!!!!!!! 物件參考變數為位址變數 ex:meow為位址變數 #### 操作屬性與呼叫方法 meow.eat();為呼叫方法,"吃" meow.weight=100;為操作資料,喵的體重一百 #### 屬性預設值 實體變數會有初始值 數值為0 boolean為flase 類別型態為null ## 模組11_物件導向概論 ### 物件參考變數 物件參考變數為儲存記憶體位址(reference/memory address) 基本型別變數儲存"值" (value) ### 記憶體運作 steak Memory//值與址之位置 Heap Memory //址所指引之位址 當物件參考變數指定給另一物件 會造成自己原本的物件若無人指向 就會再無法指定 ### 物件導向程式語言(OOP) 三大特性 1.封裝 實現隱藏資料,提升資料安全性 2.繼承 父類別供子類別使用,擴充同時表現自身特質 3.多形 可用同樣方法引用不同類別之物件,更易專案維護與功能擴充 ## 模組12_陣列_一維陣列 ### 陣列定義 一群相同資料型態的變數所組成的一種資料結構 ### 陣列宣告 陣列也是傳址 new宣告時需指定長度,並且無法再更改 中括號可放前後 int[] x;等同於 int x[]; 建議int[] x; ### 陣列元素的存取 陣列長度 meow,length; 特別注意與string length();不同 一維陣列為元素個數 二維為列數 取得陣列元素索引值起始為0 陣列使用new關鍵字分配好空間之後,會給予初始值 初始值內容與物件預設初始值相同 ## 模組13_陣列_多維陣列 ### 多維陣列觀念 in[][] x= new int [3][4]; 陣列中的陣列 非矩形多維陣列 int[][] x= new int[2][]; x[0]= new int[3]; x[1]= new int[2]; ### 陣列的傳遞 陣列與物件相同 若有兩個陣列位址參考變數指向同一個陣列 當透過第一個更改陣列時 第二個呼叫陣列時所回傳的值會被第一個更改所異動 ### 陣列排序、搜尋、複製(Arrays類別) Array.sort(x);x排序由小到大 Array.binarySearch(x,a);在x陣列中尋找a(二分法) 需排序過之陣列,否則可能會找不到值 Array.copyOf(x,5)複製x陣列,長度為5 不需要new會直接產生一個新陣列 ## 模組14_字串 ### 字串特性 預設儲存位置為pool 若用new產生String,儲存位置會heap 一旦生成就不會改變 ### 字串比較 字串比較並非==而是equals ==會比較記憶體位置 假如相同的字但分別存於heap,pool仍會得到false的答案 因此需要equals才能正確做字串比較 詳見P.65 ex:s1.equal(s2); ### 字串常用方法 charAt(int index)尋找字串中第index+1的字元 length() 回傳長度且包含空白 isEmpty() 長度為0回傳ture substring(int beginIndex)擷取從beginIndex至結尾的字串 上法可在beginIndex加另一參數end成"從begin至end參數" compareTo(s) 字串比較由左至右,依ASCII值比較 ## 模組15_varargs機制 ### main方法參數 程式進入點main方法可以接受零到多個字串當作參數傳入 String[] args即為一個字串陣列 ### 陣列索引值元素存取問題 若程式碼中呼叫main,卻未提供資料,會產生陣列索引例外問題 ### varargs(不固定參數個數/可變參數個數) 方法內可用"..."宣告可變數目的參數 可變參數必須在參數列的最後面 一個方法最多只能有一個不固定參數的宣告 ex: void methodTest(int x ,String... args){...} ## 模組16_封裝(Encapsulation) ### 封裝觀念及目的 透過資料隱藏與存取限制達到避免其他類別濫用 Java使用了"private,default,protected,public" 四種存取修飾子作為封裝權限的等級 ### 存取修飾子 ![](https://i.imgur.com/VhJjjco.png) 1.public 所有類別皆能存取 2.protected 同套件底下之類別 或 所有其子類別 能存取 3.defult(預設) 同套件底下類別可存取 4.private 只有該類別內部可做存取 類別只能用public及預設兩種修飾子 實體變數、方法、建構子則四者通用 method(int i)中的int不能使用存取修飾子,因為沒有意義(區域變數) ## 模組17_封裝設計 ### 一般類別封裝設計 設計類別時,實體變數建議為private,透過方法來存取,避免濫用或誤用 使用getter/setter來做讀取及更改 private>public getXXX>public setXXX 理想的程式碼大多數為private,都要透過get/set來做運用 通常get/set中也可以加入邏輯,確保資料正確性 ## 模組18_建構子(Constructor) ### 建構子 建構子名稱需與類別名稱相同 一個類別可有多個建構子 建構子可傳入0~N個參數 建構子可以有存取修飾子 建構子不會有回傳型別,若加了回傳型別則為一般方法 需要使用new來呼叫建構子產生物件,並同時初始化該物件之實體變數 注意: Java會自動給一個不帶參數的建構子,一旦宣告其他建構子之後, Java會自動將該預設建構子移除 ### this關鍵字 用來代表執行時當前的物件 易混淆的程式碼範圍加以區分 建構子覆載設計使用 ex: public meow (String kind){ this.kind=kind; } 在new喵物件時 傳入kind的參數為喵物件的kind ### 建構子覆載(Overloading) 可以藉由this關鍵字呼叫同類別下的另一個建構子 建構子第一行只要有this(),則進行呼叫其他建構子,且必須在第一行敘述 ex: public meow (String kind,int weight){ this.kind=kind; } public meow (String kind){ this(kind,10); } public meow (int weight){ this("cat",weight); } public meow (){ this("cat",10); } 預設喵為貓,十公斤 ## 模組19_static關鍵字 ![](https://i.imgur.com/dPwQsnJ.png) 變數含有static修飾,稱為類別變數(靜態變數) 方法含有static修飾,稱為類別方法(靜態方法) 宣告static的變數或方法,不由此類別的某物件單獨擁有,而是共同擁有 實體變數為物件各自獨立,彼此不干擾 static為類別變數,但該類別創造之物件可共享共用 儲存類別變數與方法的記憶體空間為global,與heap(儲存物件空間)分開 使用static變數與方法雖可透過任何實體來呼叫,但建議使用類別名呼叫 ### static機制 當類別第一次載入JVM時,在任何實體被建構之前, 靜態方法與變數會先被載入,因此: stiatic不可使用this static不可被覆寫為非static方法 宣告為靜態方法不可存取實體方法與變數只可存取靜態方法與變數 宣告為非靜態方法則可存取實體方法與變數,也可存取靜態方法與變數 static程式區塊裡的程式在載入類別時會先執行一次且只一次 詳見PG.78 ## 模組20_繼承 ### 繼承基本觀念 一個類別繼承父類別所有狀態及行為, 則此類別之為子類別(subclass)延伸(extends)自父類別(superclass) ### 繼承優點與好處 提高程式的重複使用姓 子類別將繼承父類別所有可存取的成員,包括變數與方法 PS:能否在子類直接使用,看修飾關鍵字 ex:private需透過get/set 共同資料只要描述一次 ex:員工編號、電話、姓名、薪資...等 處理共同資料的成員方法也只要描述一次 ex:取得員工名稱、取得員工薪資 子類別繼承父類別功能之後: 還可以加入新的方法與變數 覆寫(override)方法 ### 繼承語法與注意事項 Java不支援多重繼承,一個子類別只能extends一個父類別 建構子不會被繼承 Object為所有類別的共同父類別 ### is a 與 has a 當B繼承自A,以【B is a A】表示 詳見PG.81 ## 模組21_使用繼承 ### 覆寫機制 子類別進行覆寫時,需方法名稱、參數個數、參數型別、回傳值*均相同 *:回傳值為類別,則可以是原方法回傳值型別的子類別 存取修飾子等級不可小於原方法(只能更寬) 提醒:public>protected>default>private ### final關於覆寫的機制 一個類別宣告為final則無法被繼承(最後一種) 方法被宣告為final無法被覆寫(最終方法) 變數宣告為final無法被改變(常數) 一個物件參考變數宣告為final,無法再指向其他物件 ### super呼叫父類別方法 子類別透過super.呼叫上一層類別的方法 ex: super.methodName(); 無法越級呼叫 ### 呼叫父類別的建構子 子類別透過建構子,用super(...)將共同的建構子參數傳給父類別 (指共同的資料應使用父類別的建構子) 目的:確保子類物件中的共同資料都有完成初始化 物件產生時,建構子呼叫的順序為先父類別再子類別,因此: 1.建構子若有出現super(...),則必須擺在第一個敘述位置 2.建構子若未出現super(...),Java則會預設有一個隱形的super()在第一行 補充:super(),this()擇一使用 因兩者都需要在第一行 # 模組22(多型)~ 模組25(介面) 型別多樣化&interface應用(87~93) ## 模組22_多型 ### 型別多樣化 pg.87 要確定產生的物件實體是甚麼, 看new後面所呼叫的建構子為何者。 ex: Employee e1 = new **Manager** ### 類別型別轉換 pg.87 物件為動態產生,動態即指"執行"階段, 所以編譯階段, 編譯器還無法得知參考變數指向哪個物件, 只能從語法先檢查符不符合指定(=)的規則 詳見PG.87 ## 模組23_多型操作 ### 多型資料一致性操作 pg.89 1.Employee 用父類別宣告 讓子類別物件都可以放進這個員工陣列裡 (經理、正職、工讀都是一種員工) 2.getSalary() 雖然是不同種類的資料 但取出來都可以一起呼叫getSalary(); (不同的計算公式) ### 方法動態繫結設計_1 pg.89 編譯時期 編譯器其實也不知道呼叫的方法是哪一個 而是等到**執行時期** 有產生物件實體 再根據是否有override才知道呼叫方法為何者 ### 方法動態繫結設計_2 pg.89 編譯器利用我們宣告的型別來檢查存取的資料或呼叫的方法 是否存在因為身分(資料型別)會決定了這個物件的特徵與行為 ### 動態繫結上使用方法注意事項(補充上項) 宣告之父類別須具備欲使用子類別的方法 否則會產生錯誤 ex: object e1 = new Manager(); X e1.getSalary(); Empolyee e2 = new Manager();O e2.getSalary(); ## 模組24_抽象 ### 抽象類別或方法 pg.92 需在public後,class/method前方,增加abstract 若類別當中有抽象方法,該類別也需成為抽象類別 抽象方法不會有{},因其未有內容,僅需;表示 繼承抽象類別之後的類別,需實現全部的抽象方法, 才可成為實體物件(產生new)"清除全部的abstract" 透過override實現 ### 一個.JAVA檔裡,可有幾個類別(Class) 1.能有多個類別,但只能有一個public class 2.此public class 需跟檔名一樣(helloWorld.java) ex:public class helloWorld.java O class world O class hello O public class hello(與檔名不同) X public class helloWorld(兩個公開)X ### private VS protected差異 private 限該類存取使用(需使用get/set) protected 子類別可直接調用該屬性/值 ### 抽象類別仍可使用建構子 因方便子類別使用該抽象類別之中的值 仍可使用建構子 ex: elephant 繼承自animal elephant的super仍然會從animal來 ### abstract不能建立物件,但仍然能執行內容 abstract不能建立物件,但仍然能執行內容 ex: public abstract class XXX{ psvm{ sop("helloWorld") } }以上為可執行的 ## 模組25_介面Interface ### Interface用途 避免濫用繼承 何謂濫用繼承 1.資料關係與現實生活脫節 2.子類別可能從父類別得到不必要 甚至是錯誤的項目 五大功能 多重繼承 定義規格 貼標籤 型別轉換 降低相依姓 Interface中的屬性與方法 屬性預設修飾子為public static final 方法為public abstract Interface中的類別強制轉為抽象方法 無法在()之後增加{};(因預設abstract) ex: void test(); O void test(){...}; X Interface中的方法預設為Public, 繼承之方法只能用public覆寫(override) Interface可作為宣告用 介面 xx= new class; ### 多重繼承用法 class子類別 extend 父類別 implements 介面1,介面2....{...} or class子類別 implements 介面1,介面2....{...} ### 定義規格 可將介面當作是一種方法皆為抽象的抽象類別 因此子類別必須override所有抽象方法 介面與介面之間可再繼承(extends) ![](https://i.imgur.com/OTDdDNZ.png) # 模組26_介面設計與多型~模組30_包裝類別介紹 ## 模組26_介面設計與多型 ### 凝聚性 相依性 在使用中 我們會希望高凝聚性-低相依性的程式產生 ex:object PC會依賴鍵盤、滑鼠、印表機的產生更動程式碼,此為高相依性、低凝聚性 解決方法: 利用interface製作規格書,此後新增或改變的滑鼠、鍵盤等周邊配件符合規格書即可使用。 ex: //製作規格書USB public class mouse implements USB{ work(); } //電腦本人 public computer{ private USB usb; public void setUSB(USB usb) { this.usb = usb; } public void workWithUSB() { usb.work(); } } //印表機物件 public class Printer2 implements USB { public void work() { System.out.println("列印文件"); } } ### 圖解 ![](https://i.imgur.com/c3Wf4Ps.png) ## 模組27_套件 ### Java原始檔案格式 java編譯非必要,如果有使用這些元素請依下列順序出現 1.package 宣告 2. import 引用敘述 3.class 類別 ex: 1. package myPackageName; 2.import yourPackageName1.*; 3.class MyClass{...} 詳見PG.97 ## 模組28_import&classpath ### 用途 pg.99 給Java編譯器看的 程式碼裡的類別們在那些套件下 ### 使用時機pg.99 程式會自動引用兩種套件: 1.java.lang.*; 2.當前環境中的package 當使用之物件不存在於同一個pageage時 則需要使用import做讀取 ### 不用import的方法 ex: java.sql.date sqldate = new java.sql.date(參數名); 直接使用該類全名(套件名+類別名) date sql date = new date(參數名稱); 上法需要用import ### 注意事項(引入子資料夾之相關) import xxx.*; import xxx.yyy.*; 兩者不同 YYY為子資料夾 並不會被引入 引入只會引入當前資料夾中的class, 不包含子資料夾中的class ### 注意事項 (名稱相同) Date可能會有兩種(uti.sql) 因此要注意 ### static import 僅能調動static(不用產生物件之方法與屬性) ex: import static java.lang.Math.*; 可直接調用 random(); 但 import java.lang.Math.*; 則不能直接調用 random(); ### 類別路徑 1. Bootstrap classes(Core classes) 2.Extension classes 3.Users classes 前兩者電腦自動載入 3設定參考課本 詳見PG.101 ## 模組29_Object類別 所有類別都繼承自object 若無繼承任何類別,java會自動繼承object 以下介紹主要使用之類別 > [color=red]equals 自訂類別產生的物件要進行內容比較,可模仿字串類別 對equals方法做override,內容改成符合自訂類別之比較規則 傳入參數object obj的equals覆寫步驟建議如下: 1.判斷是否完全相同(參考位址) 2.判斷是否obj為null,getclass是否相同(也是比較位址) 3.instanceof判斷是否能轉型,若可以則進行轉型 4.內容之比較 --- > [color=yellow]toString toString通常搭配print方法對物件做列印的動作, 因為print方法會自動呼叫toString方法 主要是方便於觀察內容與除錯時使用 依情況進行override --- > [color=#1bb565]finalize > 由資源回收呼叫,當一個物件不再被參考到時, > 資源回收機制會呼叫該物件的finalize方法並從記憶體做釋放動作 > ex: obj o = new obj(); > obj=null; > system.gc(); > 在GC之後會呼叫finalize方法 --- > [color=blue]clone > 為複製一個新的物件並回傳 > 參考TestCloneableShirt.java(module27_30) > 複製同時會產生一個新的位址 > 需搭配implements Cloneable(標籤化,可使用clone) > 使用時機為該物件需要複製時,標籤在該類別 > ex:public class TestCloneableShirt implements Cloneable 若宣告中有native,則為透過C去使用方法,在jvm中執行 ## 模組30_Wrapper Class(包裝類別介紹) ### 比較兩個物件是否相等 使用equals(Object obj) 包裝類別的equals的方法都已override boxing為裝箱 unboxing拆箱 ### 自動裝/拆箱 JDK5之後產生了自動裝拆箱之功能 JAVA編譯器可根據程式碼自動推斷為裝箱或是拆箱動作 減少以往在轉換上造成程式碼冗長