為什麼這篇物件導向java鄉民發文收入到精華區:因為在物件導向java這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者givemepass (〆)看板java標題Re: [問題] 物件導向的好處是....時間Tue...
物件導向java 在 工具王 阿璋 Instagram 的精選貼文
2021-04-04 21:34:22
【#工程師之路】電機系vs資工系 到底哪裡不一樣? 這幾天被敲碗詢問的問題, 就是「電機系和資工系到底哪裡不一樣?」 欸對,老實說,其實我高中時也不是很清楚, 讀完4年電資系(電機資訊學士班), 電機系和資工系的課也幾乎修過一遍, 就讓我來跟大家說個明白吧。 ...
※ 引述《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
※ 編輯: givemepass 來自: 61.62.45.162 (12/14 20:28)