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灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP