java 板


LINE

※ 引述《kidd0730 (大阪掛川大不同)》之銘言: : 我目前對物件的認知是可以延伸出很多類似的類別 : 比如人的物件 可以延伸出男人女人等類別 : 且可以擁有各自的屬性或行為 : 這樣就是物件導向 可以減少相同的code出現 : 如果我的認知沒錯的話 : 那問題來了 : 以前非物件導向的語言 透過method或是function的呼叫 : 不是也可以做到"類似"的功能嗎?? : 還是物件導向有其他更強大的地方呢? 強大的地方就是在多型!! 寫了一個例子 有點長 如果觀念有錯 請大家鞭策一下^^ 假設你已經創造一個遊戲 裡面有一個角色是一個劍士 class SwordsMan{ public String name; public SwordsMan(String userName){ name = userName; } public void run(){ System.out.println("跑"); } public void fight(){ System.out.println("揮舞劍"); } } 裡面又有一個角色是魔法師 class Magician { public String name; public Magician(String userName){ name = userName; } public void run(){ System.out.println("跑"); } public void fight(){ System.out.println("魔法攻擊"); } } 這時候你就會想到 每一個角色當中 都有重複的跑方法 這樣好了 我就寫一個方法 然後讓所有的角色來繼承(inheritance) 於是就寫出了這樣的程式 class Character{ public String name; public Character(String userName){ name = userName; } public void run(){ System.out.println("跑"); } public void fight(){} } 因為每個角色的攻擊方式都不一樣 然後所有的角色都去推翻fight()這個方法(覆寫) class SwordsMan extends Character{ public SwordsMan(String username){ super(username); } public void fight(){ System.out.println("揮舞劍"); } } class Magician extends Character{ public Magician(String username){ super(username); } public void fight(){ System.out.println("魔法攻擊"); } } ...其他角色同樣繼承覆寫... 這時候 只要將魔法師 、劍士或其他角色實體化(instance) 就可以使用各自的方法了 可是這樣會出現一個問題,就是程式靈活度不夠, 想看看今天我有50個角色,裡面有20個角色攻擊都是揮舞劍, 這樣我每個角色都要去覆寫fight()不就累死了, 再說,如果我要修改每一個揮舞劍的角色改成揮舞刀, 那這樣也是會浪費很多時間, 所以我們就必須要把常常會變動的部分取出來, 所以我們將fight()拿出來寫成介面(interface) interface class FightMethod{ public void fight(); } 然後我們用SwordsMan這個類別去繼承它嗎? 不! 我們已經繼承Character, Java不允許多重繼承 所以我們實作(implement)它嗎? 不!這樣跟剛剛覆寫fight()方法不就一樣的問題? 複合才是我們要的答案! 我們定義一個使用劍的類別去實做它 class UseSword implements FightMethod{ public void fight(){ System.out.println("揮舞劍"); } } 然後在劍士的類別改成這樣 class SwordsMan extends Character{ private UseSword charUseSword; public SwordsMan(String username){ super(username); charUseSword = new UseSword(); charUseSword.fight(); } } 這樣寫很有問題! 什麼問題? 回想剛剛的問題,又在這裡發生了,這樣每一個角色都必須宣告一個攻擊的物件, 並且配置實體給它,那100個角色仍然要配置100個實體, 你會累死... 怎麼辦呢? 多型就是用在這個地方 我們這樣宣告 FightMethod fm = new UseSword(); fm.fight(); FightMethod fm是形式型態的宣告,而 new UseSword()才是你實際型態的宣告。 關於多型(Polymorphism),「當某變數的實際型態(actual type)和形式型態 (formal type)不一致時,呼叫此變數的 method,一定會呼叫到「正確」的版本, 也就是實際型態的版本。 所以我們這樣就可以在Character類別直接這樣宣告 class Character{ public String name; protected FightMethod fm; public Character(String userName){ name = userName; } public void run(){ System.out.println("跑"); } protected void useWeapon(){ fm.fight(); } } 而在SwordsMan內直接這樣宣告 class SwordsMan extends Character{ public SwordsMan(String username){ super(username); fm = new UseSword(); } } 這樣劍士要改變攻擊方式就可以直接換成useKnife(); 或者要增加一百個角色,也可以直接在介面上增加攻擊方式。 你看出多型的好處了嗎? 參考: 深入淺出JAVA(book) 深入淺出設計模式 歐萊禮網頁http://www.oreilly.com.tw/column_sleepless.php?id=j022 良葛格http://caterpillar.onlyfun.net/Gossip/JavaEssence/InheritanceWhat.html --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.221.115.4
1F:推 lancelotte:寫個簡單又清楚:) 12/14 16:59
2F:推 chrisQQ:好文推! 12/14 17:24
3F:→ LoveCheer:有些引數傳遞的地方寫反了 還有一些名詞前後不太一致@@ 12/14 19:27
感謝提醒!已經修改 不過名詞是指?^^"
4F:→ LoveCheer:^^" 謝謝你花時間修改 ex: charUseSword 前面沒有宣告 12/14 20:00
5F:→ LoveCheer:我最近也在思考復合跟轉發的問題 還掌握不到精髓所在 12/14 20:02
6F:→ LoveCheer:我在想是不是可以將各職業寫成interface呢? 12/14 20:04
7F:→ LoveCheer:class player extends Character implements 魔法, 劍士 12/14 20:07
8F:→ LoveCheer:這樣就可以有復合職業了(像DQ一樣A_A) (抱怨:推文等好久 12/14 20:09
已經修改好了 感謝 你要考慮is-a 跟 has-a的關係喔! ※ 編輯: givemepass 來自: 61.62.45.162 (12/14 20:28)
9F:推 tomap41017:推強大說明 12/14 22:55
10F:推 solomn:推 12/15 09:04
11F:推 lovelycateye:好文推 12/15 10:52
12F:→ LoveCheer:我是有在JAVA版看你文章的人@@ 12/15 22:21
13F:→ LoveCheer:回水球變推文@@ 12/15 22:22
14F:推 LoveCheer:推大大! 太開心了 經由跟大大學習我終於明白了! 12/16 09:49
15F:→ LoveCheer:複合+多型是為了改良 文章前半部使用多型的方式 12/16 09:52
16F:→ LoveCheer:請問是說未來遇到要使用多型時 都盡量改以複合+多型 嗎? 12/16 10:10
17F:推 dream1124:策略模式 12/16 12:23
18F:→ givemepass:是策略模式沒錯 12/16 14:30
19F:推 computer5566:推 12/16 16:54
20F:推 tkhunter:好文,該m起來 12/18 19:31
21F:推 papayamilk:推 04/20 21:17
22F:推 dick51207:推 寫的好棒!! 08/19 12:42







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP