亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Effective Java

2019-11-14 22:41:27
字體:
來源:轉載
供稿:網友
Effective java - 復合模式優于繼承

繼承是實現代碼重用的方法之一,但使用不當則會導致諸多問題。

繼承會破壞封裝性,對一個具體類進行跨包訪問級別的繼承很危險。即,子類依賴父類的實現細節。如果父類的實現細節發生變化,子類則可能遭到破壞。

舉個例子,擴展HashSet,記錄HashSet實例創建以來一共進行了多少次添加元素的操作。HashSet有兩個添加元素的方法——add(E e)和addAll(Collection<? extends E> c)。那就覆蓋這兩個方法,在添加操作執行前記錄次數:

public class InstrumentedHashSet<E> extends HashSet<E> {    // The number of attempted element insertions    PRivate int addCount = 0;    public InstrumentedHashSet() {    }    public InstrumentedHashSet(int initCap, float loadFactor) {        super(initCap, loadFactor);    }    @Override    public boolean add(E e) {        addCount++;        return super.add(e);    }    @Override    public boolean addAll(Collection<? extends E> c) {        addCount += c.size();        return super.addAll(c);    }    public int getAddCount() {        return addCount;    }}

測試一下,通過addAll方法添加3個元素:

public static void main(String[] args) {    InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();    s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));    System.out.println(s.getAddCount());}

結果是: wKioL1PLrWjBf_fsAADIJ3WV64w978.jpg

導致這種結果的原因很簡單。參考AbstractCollection中的add(E e)和addAll(Collection<? extends E> c),add(E e)中只有一段throw new UnsupportedOperationException();而addAll(Collection<? extends E> c)的文檔注釋中有這么一段話:

* <p>Note that this implementation will throw an* <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is* overridden (assuming the specified collection is non-empty).

解決這個問題的方法很簡單,只需要去掉覆蓋的addAll方法即可。但這樣卻不能解決根本問題,即HashSet的addAll方法不保證在以后的發行版本中不發生變化。即,子類實現依賴父類實現,父類發生變化時子類遭到破壞。也許我們可以覆蓋父類方法重新實現,雖然解決問題,但這樣費力不討好,毫無意義。

另外,父類增加或者移除方法也會對子類產生影響。舉個例子,子類擴展了某個集合類,覆蓋了所有添加元素的方法,在添加元素之前對元素進行檢查,讓所有元素滿足某個條件。如果在后來的版本中,父類增加了新的添加元素的方法,而子類沒有覆蓋該方法,導致非法元素添加到集合中。

反之,也有可能出現這種情況。即便父類的實現沒有問題,但也可以因為子類實現不當而破壞父類的約束。比如,父類恰好增加了和子類相同簽名和返回類型的方法。

于是,為了應對這些情況,可以使用復合模式(composition)代替繼承。即,在一個forwarding class中增加一個private field引用現有類的實例,forwarding class中的方法對應現有類的方法。代碼如下:

import java.util.Collection;import java.util.Iterator;import java.util.Set;public class ForwardingSet<E> implements Set<E> {    private final Set<E> s;    public ForwardingSet(Set<E> s) {        this.s = s;    }    public void clear() {        s.clear();    }    public boolean contains(Object o) {        return s.contains(o);    }    public boolean isEmpty() {        return s.isEmpty();    }    public int size() {        return s.size();    }    public Iterator<E> iterator() {        return s.iterator();    }    public boolean add(E e) {        return s.add(e);    }    public boolean remove(Object o) {        return s.remove(o);    }    public boolean containsAll(Collection<?> c) {        return s.containsAll(c);    }    public boolean addAll(Collection<? extends E> c) {        return s.addAll(c);    }    public boolean removeAll(Collection<?> c) {        return s.removeAll(c);    }    public boolean retainAll(Collection<?> c) {        return s.retainAll(c);    }    public Object[] toArray() {        return s.toArray();    }    public <T> T[] toArray(T[] a) {        return s.toArray(a);    }    @Override    public boolean equals(Object o) {        return s.equals(o);    }    @Override    public int hashCode() {        return s.hashCode();    }    @Override    public String toString() {        return s.toString();    }}

使用時直接繼承forwarding class:

public class InstrumentedSet<E> extends ForwardingSet<E> {    private int addCount = 0;    public InstrumentedSet(Set<E> s) {        super(s);    }    @Override    public boolean add(E e) {        addCount++;        return super.add(e);    }    @Override    public boolean addAll(Collection<? extends E> c) {        addCount += c.size();        return super.addAll(c);    }    public int getAddCount() {        return addCount;    }}

forwarding class通過Set接口提供了相應方法。這種設計也有其靈活性,繼承只能選擇Set的某個特定實現,但使用復合我們可以選擇任何接口實現。比如:

public static void main(String[] args) {    InstrumentedSet<String> s = new InstrumentedSet<String>(            new HashSet<String>());    s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));    System.out.println(s.getAddCount());}

如何從繼承和復合之間做出選擇?比較抽象的說法是,只有子類和父類確實存在"is-a"關系的時候使用繼承,否則使用復合?;蛘弑容^實際點的說法是,如果TypeB只需要TypeA的部分行為,則考慮使用復合。


上一篇:Ubuntu14.04安裝JDK

下一篇:Mysql數據庫亂碼

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91热福利电影| 国产自摸综合网| 激情久久av一区av二区av三区| 一区二区三欧美| 国产精品成久久久久三级| 91九色视频导航| 久久综合免费视频影院| 日本久久久久亚洲中字幕| 国产精品高潮粉嫩av| 成人黄色午夜影院| 国产精品一区二区三区在线播放| 亚洲性猛交xxxxwww| 国产在线a不卡| 日韩经典中文字幕| 欧美情侣性视频| 久久久亚洲成人| 欧美高清视频一区二区| 亚洲天堂日韩电影| 一区二区欧美亚洲| 欧美一级电影久久| 日韩欧美在线网址| 日韩亚洲在线观看| 国产精品久久久久久久久久久久| 青青久久aⅴ北条麻妃| 久久久久久中文字幕| 国产在线精品一区免费香蕉| 亚洲精品网站在线播放gif| 欧美极品欧美精品欧美视频| 欧美在线精品免播放器视频| 8050国产精品久久久久久| 日韩欧美亚洲范冰冰与中字| 国产91对白在线播放| 欧美电影电视剧在线观看| 色伦专区97中文字幕| 青青久久av北条麻妃黑人| 综合国产在线观看| 欧美大胆a视频| 成人在线免费观看视视频| 欧美裸体视频网站| 久久久久久久久91| 国产亚洲xxx| 国产视频一区在线| 国内精品视频在线| 欧美小视频在线| 色综合久久精品亚洲国产| 久久精品电影一区二区| 欧美极品少妇xxxxx| 国产精品永久免费视频| 色综合视频一区中文字幕| 狠狠躁夜夜躁久久躁别揉| 国产精品美乳在线观看| 欧美亚洲一区在线| 国产精品一区二区三区久久久| 午夜精品美女自拍福到在线| 亚洲天堂网站在线观看视频| 高跟丝袜欧美一区| 欧美中文字幕在线视频| 韩国日本不卡在线| 国产成人91久久精品| 久久久精品国产网站| 欧美日韩久久久久| 欧美成人免费观看| 亚洲综合精品伊人久久| 91探花福利精品国产自产在线| 久久99精品视频一区97| 久久亚洲精品国产亚洲老地址| 欧美老女人性生活| 久久成人在线视频| 97热在线精品视频在线观看| 中文一区二区视频| 欧美成人亚洲成人日韩成人| 亚洲精品aⅴ中文字幕乱码| 欧美精品videos另类日本| 狠狠久久五月精品中文字幕| 久久国产加勒比精品无码| 亚洲成人网久久久| 日韩av一区二区在线观看| 91在线观看免费高清| 久久精品国产亚洲7777| 国精产品一区一区三区有限在线| 最近中文字幕mv在线一区二区三区四区| 亚洲精品久久久久中文字幕二区| 国产成人在线一区二区| 亚洲成人动漫在线播放| 欧美日韩在线视频一区二区| 亚洲xxx自由成熟| 中文字幕av一区| 97久久伊人激情网| 国产欧美一区二区三区视频| 92看片淫黄大片看国产片| 国产精品视频不卡| 久久久免费高清电视剧观看| 国产精品日日做人人爱| 精品高清一区二区三区| 日韩欧美国产中文字幕| 国产精品爱啪在线线免费观看| 亚洲欧美一区二区三区久久| 久久免费少妇高潮久久精品99| 国产精品扒开腿爽爽爽视频| 亚洲色图15p| 欧美中文在线字幕| 日韩精品极品毛片系列视频| 亚洲精品乱码久久久久久按摩观| 一本久久综合亚洲鲁鲁| 国产亚洲在线播放| 日本精品久久久久久久| 欧美成人性生活| 黄色成人在线免费| 免费91麻豆精品国产自产在线观看| 91精品国产乱码久久久久久蜜臀| 成人乱人伦精品视频在线观看| 国产亚洲欧洲黄色| 国产欧美精品xxxx另类| 欧美寡妇偷汉性猛交| 精品中文字幕在线| 高清欧美性猛交xxxx黑人猛交| 亚洲精品二三区| 日韩视频免费大全中文字幕| 日韩久久午夜影院| 色噜噜狠狠狠综合曰曰曰88av| 亚洲国产免费av| 日韩经典中文字幕在线观看| 国产乱人伦真实精品视频| 北条麻妃一区二区在线观看| 国产91精品最新在线播放| 中文字幕亚洲综合久久筱田步美| 国产91精品久久久久久久| 久久久之久亚州精品露出| 久久国产精品亚洲| 久久99国产精品久久久久久久久| 最近中文字幕日韩精品| 欧美做受高潮电影o| 国产成人综合久久| 久久亚洲电影天堂| 亚洲三级 欧美三级| 久久精品在线播放| 精品久久久久久久久国产字幕| 日韩精品极品毛片系列视频| 色偷偷88888欧美精品久久久| 蜜臀久久99精品久久久久久宅男| 国产专区精品视频| 岛国视频午夜一区免费在线观看| 国产精品自产拍在线观看中文| 2019中文字幕免费视频| 精品色蜜蜜精品视频在线观看| 欧美国产在线视频| 国产97在线|日韩| 日韩视频―中文字幕| 4438全国亚洲精品在线观看视频| 色哟哟亚洲精品一区二区| 国产精品久久久久久久久久ktv| 久久久999国产精品| 久久精品视频中文字幕| 久久久久久久电影一区| 亚洲天堂av图片| 78m国产成人精品视频| 欧美寡妇偷汉性猛交| 亚洲欧洲在线视频| 亚洲精品v天堂中文字幕| 国产亚洲欧洲黄色| 色综合91久久精品中文字幕| 欧美激情一区二区三区高清视频| 久久久噜噜噜久久久| 亚洲www永久成人夜色|