Java程式設計語言提供兩種機制,可以用來定義允許多個實現的類型:介面和抽象方法,這兩者直接醉為明顯的區別在於,抽象類允許某些方法的實現,但介面不允許,一個更為重要的區別在於,為了實現由抽象類定義的類型,類必須成為抽象類的一個子類。任何一個類,只要定義了所有必要的方法,並且遵守通用約定,它就被允許實 ...
Java程式設計語言提供兩種機制,可以用來定義允許多個實現的類型:介面和抽象方法,這兩者直接醉為明顯的區別在於,抽象類允許某些方法的實現,但介面不允許,一個更為重要的區別在於,為了實現由抽象類定義的類型,類必須成為抽象類的一個子類。任何一個類,只要定義了所有必要的方法,並且遵守通用約定,它就被允許實現一個藉口,而不管這個類是處於類層次的哪個位置。因為Java只允許單繼承,所有抽象類作為類型定義受到類極大的限制。
現有的類很容易被更新,以實現新的介面。
如果你希望讓兩個類擴展同一個抽象類,就必須把抽象類放到類型層次結構的高處,以便這兩個類的一個祖先成為它的子類。遺憾的是這樣做會間接到傷害到類層次,迫使這個公共祖先到所有後代類都擴展這個新的抽象類,無論它對於這些後代類是否合適。
介面是定義混合類型的理想選擇。
介面允許我們構造非層次結構的類型框架。
假如我們有兩個介面,一個表示歌唱家,另一個表示作曲家,在現實生活中,有很多人即是歌唱家又是作曲家,如果是介面,我只需要同時實現這兩個介面就可以,如果是抽象類,因為Java是單繼承的,我就沒有辦法描述這一類的人。
雖然介面不允許包含方法的實現,但是,使用介面來定義類型並不妨礙你為程式猿提供實現上的幫助。通過對你導出的每個重要介面都提供一個抽象骨架的實現類,把介面和抽象類的優點都結合起來。介面的作用仍然是定義類型,但是骨架的實現類接管類所有與介面實現相關的工作。
骨架為介面提供實現上的幫助,但又不強加“抽象類被用作類型定義時”所特有的嚴格限制。對於介面大多數的實現來講,擴展骨架實現類是個很顯然的選擇,但不是必須的。如果預製的類無法擴展骨架實現類,這個類始終可以收工實現這個介面。此外,骨架實現類仍然有助於介面的實現。實現類這個介面的類可以把對於這個介面方法的調用,轉發到一個內部私有類的實例上,這個內部私有類擴展骨架實現類。這種方法被稱作模擬多重繼承。這項技術具有多重繼承的絕大多數有點,同時又避免了相應的缺陷。
編寫骨架實現類相對比較簡單,只是有點單調乏味。首先,必須認真研究介面,並確定哪些方法時最為基本的,其他方法則可以根據它們來實現。這些方法將成為骨架實現類中的抽象方法。然後,必須為介面中的所有其他的方法提供具體實現。例如,下麵是Map.Entry介面的骨架實現類:
/** * 介面優於抽象類 * @author weishiyao * * @param <K> * @param <V> */ // Skeletal Implementation public abstract class AbstractMapEntry<K, V> implements Map.Entry<K, V>{ // Primitive operations public abstract K getKey(); public abstract V getValue(); // Entries in modifiable maps must override this method public V setValue(V value) { throw new UnsupportedOperationException(); } // Implements the general contract of Map.Entry.equals @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof Map.Entry)) { return false; } Map.Entry<?, ?> arg = (Map.Entry) obj; return equals(getKey(), arg.getKey()) && equals(getValue(), arg.getValue()); } private static boolean equals(Object obj1, Object obj2) { return obj1 == null ? obj2 == null : obj1.equals(obj2); } // Implements the general contract of Map.Entry.hashCode @Override public int hashCode() { return hashCode(getKey()) ^ hashCode(getValue()); } private static int hashCode(Object obj) { return obj == null ? 0 : obj.hashCode(); } }
骨架實現類時為了繼承的目的而設計的,這種使用方式在平時開發中經常可以見到,很多框架中都有使用方式,之前為也是見過好多次框架中這麼使用,大致能明白這麼寫是乾什麼,這次經過這麼詳細講解,算是徹底明白為什麼要這麼使用了,能想到這種寫法的人真的也是大神了。