作者:
NullLife (廢材大叔有點累)
2015-09-27 14:09:19原文吃光光,就interface跟abstract class講一下我體悟的概念
interface就像是技能類,例如今天你老闆需要一個java人才
所以你頭上掛著名為Java的interface,宣告著我會java,
然後你就可以被老闆使喚(咦!?)
但做得好不好,只有你知道,你老闆不會知道,
因為老闆只會跟你說"東西呢?"。
因此上述這段話用code來描述就是
public interface Java {
public String coding();
}
public class You implements Java {
@Override
public String coding() {
System.out.println("要不然你來做啊"); // 這裡是OS
boolean deadLineIsComing = true;
String report = deadLineIsComing ? "快好了" : "快好了";
return report; // 給老闆的話
}
}
public class Boss {
public static void main(String[] args) {
Java javaSkillGuy = new You();
Boss boss = new Boss();
boss.cryNorth(javaSkillGuy);
}
public void cryNorth(Java freshLiver) {
String report = freshLiver.coding();
System.out.println(report);
}
}
上述老闆的cryNorth這個method是接Java這個技能,
因此進去之後,老闆只會知道你有coding這個method可以使喚,
(因為Java這個interfac裡面只有coding的method)
如果你有其他例如唱歌跳舞的method可以使喚,你老闆並不會知道,
因為在他cryNorth的時候是用Java來看你這個人(instance)。
那interface有什麼優點?
"過共同的介面耦合不同實作,而不需要去管實作細節,達到低耦合高內聚。"
(關於低耦合高內聚這句話請自行估狗,看不懂也沒關係,
我也是寫個兩年後才能體悟這句話的精隨,先有概念就好了。)
上述這句話套到剛剛個例子就老闆需要一個會Java的人使喚(共同的介面),
例如我跟你都會Java,都可以被使喚coding(不同實作),
但我們寫作風格、習慣不同(實作細節),
對老闆而言,他不care我們的寫作風格、習慣(不需要管實作細節),
他只知道使喚你之後必須得到一個結果(一個字串)。
那麼interface既然是技能類,就代表其實每一個人(instance)可以有好多個技能,
因此一個類可以implements好多個interface,等著需要的人來使喚你(工具人的概念)。
如果上面看懂了的話,
延伸一個思考"如果兩個interface有一模一樣的method同時被實作時怎麼辦?"
這個問題很簡單,自己實作一下,就會有答案囉。 (我當初自學也是這樣學 :))
現在來談abstract class。
這跟繼承概念有關,但這裡我只針對abstract method解釋(因為我懶了 XD),
若看不懂的話,繼承概念請再多估狗囉。
例如今天你想成一個魔法師,像我一樣(咦!?)
然後魔法師這個職業擁有戴上墨鏡跟酸酸這兩個方法,
這時候我們去承襲了魔法師這個職業之後,我們就擁有了這兩個方法,對吧?
然後今天突然系統改版,魔法師多了一個方法叫combo,
就是今天走在路上被閃光攻擊時,會被trigger這個combo方法,
那這個方法會做戴上墨鏡>崩潰>酸酸這三件事,
這時候魔法師這個職業,不想知道崩潰的細節,
(因為知道的話可能所有的魔法師都崩潰了)
因此它將崩潰宣告為abstract,讓子類去實作細節,
然後在combo裡照順序呼叫就好了。
因此我跟你就會分別實作了崩潰,當然我們崩潰方式不一樣啦 XD
總之,這個時候我們的實作裡面只會看到override崩潰這個方法,乾乾淨淨,
看不到其他東西。
這意思是什麼?
意思就是說如果有一系列固定的動作,想讓不同的人去做,
但又有其中一兩個動作不一樣時,
可以透過這樣的方法,讓子類可以專注在崩潰上面,而不用去管其他事情。
(除非你想改變魔法師戴上墨鏡這個方法,那就overrider戴上墨鏡,
讓combo呈現不同的結果,其實這也就是繼承之後,能夠拓展父類的概念。)
而對於放閃光攻擊的人,就是呼叫combo這個方法,讓你執行這三件事情。
大意上是這樣,但怎麼設計又是另一門藝術,我也還在學習中。
其實上述這件事情,也可以抽出來變成一個interface,
裡面包含combo、戴上墨鏡、崩潰、酸酸四個方法,
然後再多一個玩家的abstract class去implements這個interface,不實作任何一個方法。
讓魔法師去繼承玩家,實作combo、戴上墨鏡、酸酸這三個方法,
將崩潰留給子類去實作。
這樣子修改之後,對於我們(子類)來說完全沒有變,我們不會知道上面發生了時候事情,
但這時候放閃光的人,就可以對任何implements這個interface的玩家(或者是NPC?),
trigger combo這個方法。
(上述我懶得寫code了,有興趣自己照著描述去寫code吧@@)
這樣就可以在不影響實作類(就是我跟你)的狀況下修改結構,讓呼叫的層級拉到介面,
擴大能被調用的可能性。
其實重點就是分層的概念,我在寫這支class的時候,
我不想看到或不在乎然後又會需要存在的東西,把它往上放到父類,
這樣我就可以專注在自己的實作上。
以上是小弟我寫了三年的心得,如有任何錯誤,歡迎指正。
PS:其實這個概念我很早就知道了,只是直到最近新公司,
給我極大的權限讓我handle整個系統,我在開發modle的時候,
才真正可以理解設計時該如何拆這些東西,達到好的彈性的架構。
因此概念懂歸懂,還是要不斷的寫才能有深刻的體悟啊 (菸)