先舉一個多重繼承的例子,我們定義一個動物(類)既是狗(父類1)也是貓(父類2),兩個父類都有“叫”這個方法。那么當我們調用“叫”這個方法時,它就不知道是狗叫還是貓叫了,這就是多重繼承的沖突。
而java對此的解決方法是,一個物體的本質只能有一個。一個動物只能是狗或只能是貓,如果你想創造一個會玩毛線球的狗,那么只需要創造一個描述這類行為的接口(就叫玩耍吧),然后在自己的類里面實現“玩耍”接口,具體實現這些玩的行為,最終你同樣會得到一個既像狗又像貓的動物。如果你想讓這個動物叫起來像貓而不是狗,那么使用重寫(override)機制,子類里重新定義“叫”這個行為即可。但是無論如何,這樣得到的類是絕對不會有多重繼承的沖突的。
再來說說abstract class和interface的區別。
abstract class的核心在於,我知道一類物體的部分行為(和屬性),但是不清楚另一部分的行為(和屬性),所以我不能自己實例化。還是剛才那個例子,如果你有個abstract class叫哺乳動物,那么你可以定義他們胎生,恆定體溫等共同的行為,但是具體“叫”這個行為時,你得留着讓非abstract的狗和貓等等子類具體實現。
interface的核心在於,我只知道這個物體能干什么,具體是什么不需要遵從類的繼承關系。比如上述的“玩耍”interface,狗有狗的玩法,貓有貓的玩法,妖魔鬼怪機器人都可以玩耍,只要你告訴我這個物體有玩耍接口,我就能讓它玩起來(๑•̀ㅂ•́) ✧
所以abstract class和interface是不能互相替代的,interface不能定義(它只做了聲明)共同的行為,事實上它也不能定義“非常量”的變量。而abstract class只是一種分類的抽象,它不能橫跨類別來描述一類行為,它使得針對“別的分類方式”的抽象變得無法實現(所以需要接口來幫忙)。而多重繼承不但會造成沖突,還讓一個類變得不倫不類,看不出這個類的本質,所以java毅然舍棄掉了這個禍害。
多繼承:
單繼承:
