Java 物件導向(Object-Oriented) === --- ##### 以下內容來自我至今所學,若有不正確內容歡迎指教 ##### 此文章目標是讓物件導向能夠簡單理解,並且給讀者更深入的觀念,方便銜接 --- [TOC] --- 進入物件導向的世界 --- ### 為什麼需要物件導向? 1. 當撰寫長到爆的程式時你開始會有==第三者閱讀的困難==及==維修的困難==,因此這個時候就是物件導向派上用場的地方!負責將每個區塊以類別分類,物件化東西,有系統地整理程式碼 2. 物件導向不僅能解決上述問題,還能自己寫一個==類別==很像是做出一個咖啡機,如此一來,你想要喝咖啡的時候,就直接把咖啡機拿出來使用,相當方便 ### 物件導向是什麼?-RPG遊戲的角色與技能 1. 類別與物件: RPG遊戲想必是大家都玩過的,老掉牙的那幾個職業就像是:==拳擊手==、==魔法師==、==劍客==、==刺客==、==弓箭手== 不知道各位是否有想過,如果你的角色是弓箭手,那麼究竟你的角色是==名為弓箭手的一個物件==還是說你的角色是==一種弓箭手類別中的物件==,也許你的回答是前者或後者或者你覺得:哭啊不是都一樣嗎? 如果我這樣提醒你,你就肯定能明白,如果你把你的角色取名為:汪汪,那如果==名為弓箭手的一個物件==是正確,就顯得不合邏輯了!你的角色有兩個名字! :::info 物件導向的邏輯:根據上述可以得知,類別有類別名稱(弓箭手、魔法師),物件有物件名稱(我的角色較喵喵、你的角色叫汪汪),並且類別的層級比物件還要大(汪汪是一種弓箭手,但弓箭手不一定就是指稱汪汪)。 ::: 2. 物件的屬性: RPG遊戲中,很常數值化一些數據像是==ATK==、==MATK==、==DEF==、==DEX==等等 這些是屬於角色專有的屬性,並且是數字資料 而==長髮==、==棕色毛髮==等等則是文字資料 當然,也可以是布林值像是==馬尾:有==、==披風:無==等等布林值資料 :::info 看到這邊大家都有概念了吧?沒錯,屬性正是資料,有並且擁有資料型別,簡單來說,就是專屬於物件的資料 ::: 3. 物件的方法: 當然,說到RPG最厲害的果然還是那些炫砲的技能,比方說弓箭手技能==隱匿==、==超猛的射擊==、==點火射擊==當然,也有一些非攻擊型技能例如==跳舞==、==挑釁==的動作 :::info 文字中,若要描述一個人有動詞、名詞、形容詞、(還有副詞)這些常常用來描述一個人的用法,如果我們說物件是名詞,那麼屬性肯定是修飾他的形容詞,方法肯定是他的動詞(+副詞) 在程式語言中,方法就是物件可以執行的操作 ::: 4. 共享方法與屬性: 那你肯定會發現:啊如果我說屬性:人、方法:呼吸,是不是每個物件都有,如果我今天要敘述或者使用,每個人都要建立屬性、方法會不會太煩? 你的想法是對的,因此,Java的static靜態能夠共享屬性或方法,這會在後面介紹到,暫時先不提 ### 類別操作 ```mermaid graph TD; 介面-->子類別; 抽象類別-->子類別; 父類別-->子類別; 子類別-->實作介面; 子類別-->繼承抽象類別; 子類別-->繼承父類別; 子類別--->本身屬性與類別; ``` ### 物件與類別與屬性方法的關係 我們會說==屬性或方法是被物件所擁有的==;但當我們說==此類別的方法或屬性==則是想要表達,這個類別的所有物件都有這種方法和屬性 ```mermaid graph TD; 類別-->物件; 物件-->屬性與方法; ``` Java物件導向 --- 0. 物件導向區塊 ```java= class A { //放入物件A的屬性和方法 public void method() { //方法中可以建立A或B物件 //方法中的物件可以呼叫方法或屬性 } } class B { //放入物件B的屬性和方法 public void method() { //方法中可以建立A或B物件 //方法中的物件可以呼叫方法 } } ``` * 由此可知,我們程式執行都是在方法裡面執行,就連我們熟悉的main都是一個方法 1. 類別建立、屬性與方法 ```java= //封裝方式 class 類別名稱 {} public class Archer { // 型別 屬性名稱 = 屬性資料; int DEX = 100; //attribute // 封裝方式 型別 方法名稱(); public void showDEX() { //method System.out.println(DEX); } } ``` * 以上可以發現,屬性真的就只是在class裡面寫一個變數而已! 方法則是可以用來呼叫並且執行,方法都有==型別==與變數一樣,而其==型別==則表示這個方法會回傳什麼 * public是一種封裝方式,在後面會介紹到,這邊先閉著眼睛用上public就好 :::info ==型別==:在Java中,任何資料或者物件都有型別,表示他們儲存何種資料 1. 基本型別(例如int、String等,這邊不詳細列舉) 例如:如果是int則表示儲存數字的資料,在此不詳細列舉 2. 不回傳(void) 物件的方法中特別有void型別,當你的方法是要用來執行某些操作,沒有要回傳任何東西,則可以在前面加上void 3. ==類別== 當新建一個類別,這個類別就自然成為其物件的型別,比方說物件barkbark是Archer型別的物件 ::: 2. 物件建立,呼叫屬性與方法 ```java= //類別名稱 物件名稱 = new 類別名稱(); Archer barkbark = new Archer(); //建立物件 ``` ```java= //物件名稱.屬性名稱; //可以直接當成一般變數使用 barkbark.DEX; ``` ```java= //物件名稱.方法名稱(); //若有回傳值,則可以用變數儲存;若無,也可以直接當成一行 barkbark.showDEX(); ``` 完整程式: ```java= public class Archer { int DEX = 100; //attribute public void showDEX() { //method System.out.println(DEX); } } public class Main { public static void main(String[] argv) { Archer barkbark = new Archer(); //建立物件 int n = barkbark.DEX; barkbark.showDEX(); System.out.println(n); } } ``` ``` 100 100 ``` :::info ==接受資料的方法== 當執行方法操作時,可以輸入資料,用==逗點==隔開 ```java= public void updateDEX(int n, int m, int p) { // 在方法的框框裡面寫入資料 DEX += (n + m + p); System.out.println("DEX增加了" + (n + m + p)); } ``` ::: :::info ==型別與回傳值==:我們說一個東西的回傳值就是他型別的資料 1. 以下是變數回傳值的例子 ```java= int a = 1; //變數:當被呼叫的時候回傳int int b = 2; //變數:當被呼叫的時候回傳int int c = a + b; //當程式碼寫到a、b就是呼叫他們的過程 ``` 2. 以下是方法回傳值的例子 ```java= public class Main { public String method() { return "I am barkbark"; } public static void main(String[] argv) { Main Object = new Main(); System.out.println(Object.method()); // 從method回傳了String型別的資料,並且輸出 } } ``` ::: 3. 靜態(static) 屬性前面加static:表示所有==物件==共享此屬性 * 當其中一個物件改變了他的值,所有物件的此屬性皆會被改變 * 可以用類別名稱呼叫此屬性 * ==方法也可以有相同的做法,留給各位實作== ```java= public class Archer { static int DEX = 100; //attribute public void showDEX() { //method System.out.println(DEX); } } public class Main { public static void main(String[] argv) { Archer barkbark = new Archer(); Archer meowmeow = new Archer(); barkbark.showDEX(); meowmeow.showDEX(); barkbark.DEX += 100; // 物件共享的屬性都被改變了! barkbark.showDEX(); meowmeow.showDEX(); System.out.println(Archer.DEX); // 用類別名稱呼叫屬性 } } ``` ``` 100 100 200 200 200 ``` :::info ==主程式執行區塊== ```java= public static void main(String[] argv) {} ``` 由此可得知,平常我們打的主程式區塊也是物件導向的方法 1. public:封裝方式-公開 2. static:靜態-用於共享 3. void:不回傳值的型別 4. main:主程式名稱 5. String[] argv:輸入的argv字串陣列 ::: 物件導向名詞指引與繼承 --- 由於這篇文章是為了讓新手步入物件導向的內容,這邊將只對以下內容提供概念性講解。未來有機會會再撰寫相關的例子 ### 方法(Method) 可以處理運算等操作並且回傳特定型別的資料,也可以僅操作不回傳資料 ### 屬性(Attribute) 回傳基本型別等資料 ### 繼承(Inherit)、父類別(Parent)、子類別(Child) 繼承是一個承接關係,就好像是類別在生小孩 ==當一個子類別A繼承了一個父類別B==,則子類別A會得到父類別B的所有方法和屬性 ```mermaid graph TD 父類別-->方法A; 父類別-->方法B; 父類別-->屬性C; ``` ==當子類別繼承了父類別,並且多宣告方法D和屬性E,則以下是子類別== ```mermaid graph TD 子類別-->方法A_繼承; 子類別-->方法B_繼承; 子類別-->屬性C_繼承; 子類別-->方法D; 子類別-->屬性E; ``` ### 多形(Polymorphism) 用來讓繼承發揮作用 簡單來說就是使父類別變成操作介面,方便操作其子類別 ### 抽象類別(Abstract Class) 抽象類別與一般類別的關係,就如同父類別和子類別,不同的地方是,抽象類別==只能敘述說:有何種方法、有回何種資料==,不能夠真正輸入方法功能或屬性,故稱作抽象,不難理解,抽象類別本身沒有作用,就是專門被繼承的。他就類似一種==ppt的模版==,繼承他就是拿模版來操作的概念 ### 介面(Interface) 當類別之間擁有相似性質,例如:==劍客和刺客有相同技能:刺擊==,如過有很多種職業都有刺擊這項技能,當製作成類別就會變得相當麻煩,這個時候就是界面的功用,他負責==統整不同類別的共同屬性和方法==,如果我們說==劍客實作自刀劍介面==,那就是讓劍客擁有所有刀劍技能 額外重要觀念 --- 由於這篇文章是為了讓新手步入物件導向的內容,這邊將只對以下內容提供概念性講解。未來有機會會再撰寫相關的例子 ### 封裝 * 封裝是隱藏資訊的一種,舉個例子,如果你今天使用了別人的類別於你現在自己寫的程式,如果他有一個變數int x = 1;然而,他沒有做封裝,則當你在自己類別定義int x的時候就會發生衝突! * 以下是封裝方式及其可以存取的範圍: | 封裝方式 | public | prodected | private | default(都不加) | |:--------:|:--------:|:---------:|:-------:|:---------------:| | 存取權 | 都可以存 | 子類別 | 同類別 | 同套件 | ### 套件 是一種能將多種類別整合起的工具,也含有從某某套件引入某某類別進而在其他地方使用別人寫好的方法的操作方式。 END --- 讀完這篇文章還想更深入了解可以參考其他文章,感謝閱讀 ###### tags:`Object-Oriented` `Java` `progamming` `物件導向`