如何解決Java多重繼承的問題

潘家羲 Sparrow Pan

  • 精誠資訊/恆逸教育訓練中心-資深講師
  • 技術分類:程式設計

 

 

蛤…有沒有搞錯?如何解決Java多重繼承的問題?Java不是單一繼承的語言嗎?怎麼會有多重繼承的問題呢?

話說當年,Java在設計之初為了改善C++多重繼承所衍生的問題,Java捨棄了C++多重繼承的語言特性,從而改為單一繼承的語言。可是從物件導向的設計觀點來看,多重繼承對系統的彈性跟靈活性都至關重要,怎麼可以隨便放棄呢?別擔心,Java語言的創始人James Gosling說,Java可藉由interface的技術來達到多重繼承的目的,同時也解決了多重繼承的缺點,原因是interface的方法只有簽章(Method Signature)而沒有實作(Method Implementation),也就是interface的方法都是抽象(abstract)的,這麼一來,就不會發生不同的父類別出現實作衝突的問題。

可是隨著時間跟技術的演進,考量到語言的擴充性、相容性跟穩定性,Java從SE8開始,陸續開放在interface提供static、default跟private方法的實作。可是為什麼interface需要提供方法實作呢?舉例來說:

teamMember.stream().forEach(m->m.raiseSalary(0.10));

為了讓Java的集合(Collection)物件可從迴圈語法的處理方式,改成用Lambda語法的處理方式,Java勢必得在整個Collection框架擴充stream()這個方法。問題是,這麼大的繼承架構要怎麼擴充才能確保多型的特性呢?首先Java得在最上層的Collection interface定義抽象的stream()方法,接著得在所有的Collection子類別提供重複的stream()方法實作。哇…很顯然的,對龐大的Collection繼承體系來講,這種擴充方式不但麻煩,而且笨重、不切實際。因此,如果可以把這個stream()方法的實作直接搬到Collection interface,那麼偌大的Collection繼承架構只需要修改Collection interface,其它所有的子類別都完全不需要更動,哈哈!是不是很完美呢?
可是Java的類別可以實作多個interface,那不就會有多重繼承的問題嗎?
是的!一點都沒錯!這正是為什麼要討論如何解決Java多重繼承的問題。為了解決多重繼承的問題,Java規格書定義了下列的規則:

規則一、父類別(具體類別或抽象類別)的方法優先於interface default方法



規則二、subtype interface default方法優先於supertype interface default方法



規則三、如果出現default方法實作上的衝突,default方法會被視為抽象方法,所以具體的子類別需負責實作該default方法。




您可在下列課程中了解更多技巧喔!