Effective Java Item 18 note

Prefer interfaces to abstract classes

Arwii
mycodingjourney
3 min readJun 14, 2018

--

— — — — — — Java對於繼承有提供兩種方式:

interface:

  • 單純只有method,不實現。

abstracted:

  • 允許某些method實現。

— — — — — — 使用上的比較:

interface:

  • 用implement的方式繼承,比較彈性,要增加功能時也比較安全一點。
  • 可以解決例如一個人有多種角色存在的這種情形,不過書上這裡的例子是一個作曲家可以也是歌唱家,所以會同時implements這兩個interface,但我覺得也可以改用另一個角度,例如是一個人的class可以會唱歌,也會作曲(這就是從合成的角度去看),感覺設計class是否有必要到一定要繼承是可以好好想想的。
public class Human implements Author, Singer 

public class Human {
Author author;
Singer singer;
}
  • 設計要相當謹慎,一但publish就要假定是不能修改了,可以試著在publish之前多找一些人implement看看有沒有什麼漏洞。

abstracted:

  • 用extends的方式繼承,只能extends一個,比較不彈性。
  • 如果要新增功能然後讓已經extends的class都可以使用到的角度來說,是比較好的選擇(class的沿用性大於彈性的時候),interface就不能達到這樣的效果了。如果在interface要增加method,是一定會要已經implements這個interface的class都要修改的,不然會沒辦法編譯。

AbstractInterface:

  • 適用於想要提供一個骨架出去,但又想要自己實作一些細節的時候就可以把這兩個混著用。
  • 如果有了interface,那最好也考慮提供abstractInterface
  • 像是Collections Framework就是這樣做的
    Ex:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {

而這個實現方式也可以達到書上說的多重繼承(simulated multiple inheritance,照理說Java中只能extends一個class,記得是以避免C++上面的多重繼承diamond問題,但在Java上面還是可以利用底下的這個方式,達到跟多重繼承有類似的效果,實現方式就是把你要的功能也變成abstract class,然後屬於你的class該實作的部分給抽象,然後在你的class裡面用一個匿名的

class extends 該abstract class,就可以達到類似效果,程式碼可以參考:https://www.javaworld.com/article/2072159/core-java/simulate-multiple-inheritance-in-java.html)

--

--

Arwii
mycodingjourney

Try not to become a man of success, but rather try to become a man of value — A. Einstein