一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 關(guān)于為何說JAVA中要慎重使用繼承詳解

關(guān)于為何說JAVA中要慎重使用繼承詳解

2021-05-25 13:14Decouple Java教程

Java繼承是面向?qū)ο蟮淖铒@著的一個特征,然而下面這篇文章主要給大家介紹了關(guān)于為何說JAVA中要慎重使用繼承的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧

前言

這篇文章的主題并非鼓勵不使用繼承,而是僅從使用繼承帶來的問題出發(fā),討論繼承機制不太好的地方,從而在使用時慎重選擇,避開可能遇到的坑。

java中使用到繼承就會有兩個無法回避的缺點:

  • 打破了封裝性,子類依賴于超類的實現(xiàn)細節(jié),和超類耦合。
  • 超類更新后可能會導致錯誤。

繼承打破了封裝性

關(guān)于這一點,下面是一個詳細的例子(來源于effective java第16條)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class myhashset<e> extends hashset<e> {
 private int addcount = 0;
 
 public int getaddcount() {
  return addcount;
 }
 
 @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);
 }
}

這里自定義了一個hashset,重寫了兩個方法,它和超類唯一的區(qū)別是加入了一個計數(shù)器,用來統(tǒng)計添加過多少個元素。

寫一個測試來測試這個新增的功能是否工作:

?
1
2
3
4
5
6
7
8
9
10
public class myhashsettest {
 private myhashset<integer> myhashset = new myhashset<integer>();
 
 @test
 public void test() {
  myhashset.addall(arrays.aslist(1,2,3));
  
  system.out.println(myhashset.getaddcount());
 }
}

運行后會發(fā)現(xiàn),加入了3個元素之后,計數(shù)器輸出的值是6。

進入到超類中的addall()方法就會發(fā)現(xiàn)出錯的原因:它內(nèi)部調(diào)用的是add()方法。所以在這個測試里,進入子類的addall()方法時,數(shù)器加3,然后調(diào)用超類的addall(),超類的addall()又會調(diào)用子類的add()三次,這時計數(shù)器又會再加三。

問題的根源

將這種情況抽象一下,可以發(fā)現(xiàn)出錯是因為超類的可覆蓋的方法存在自用性(即超類里可覆蓋的方法調(diào)用了別的可覆蓋的方法),這時候如果子類覆蓋了其中的一些方法,就可能導致錯誤。

關(guān)于為何說JAVA中要慎重使用繼承詳解

比如上圖這種情況,father類里有可覆蓋的方法a和方法b,并且a調(diào)用了b。子類son重寫了方法b,這時候如果子類調(diào)用繼承來的方法a,那么方法a調(diào)用的就不再是father.b(),而是子類中的方法son.b()。如果程序的正確性依賴于father.b()中的一些操作,而son.b()重寫了這些操作,那么就很可能導致錯誤產(chǎn)生。

關(guān)鍵在于,子類的寫法很可能從表面上看來沒有問題,但是卻會出錯,這就迫使開發(fā)者去了解超類的實現(xiàn)細節(jié),從而打破了面向?qū)ο蟮姆庋b性,因為封裝性是要求隱藏實現(xiàn)細節(jié)的。更危險的是,錯誤不一定能輕易地被測出來,如果開發(fā)者不了解超類的實現(xiàn)細節(jié)就進行重寫,那么可能就埋下了隱患。

超類更新時可能產(chǎn)生錯誤

這一點比較好理解,主要有以下幾種可能:

1、超類更改了已有方法的簽名。會導致編譯錯誤。

2、超類新增了方法:

  • 和子類已有方法的簽名相同但返回類型不同,會導致編譯錯誤。
  • 和子類的已有方法簽名相同,會導致子類無意中復寫,回到了第一種情況。
  • 和子類無沖突,但可能會影響程序的正確性。比如子類中元素加入集合必須要滿足特定條件,這時候如果超類加入了一個無需檢測就可以直接將元素插入的方法,程序的正確性就受到了威脅。

設計可繼承的類

設計可以用來繼承的類時,應該注意:

  • 對于存在自用性的可覆蓋方法,應該用文檔精確描述調(diào)用細節(jié)。
  • 盡可能少的暴露受保護成員,否則會暴露太多實現(xiàn)細節(jié)。
  • 構(gòu)造器不應該調(diào)用任何可覆蓋的方法。

詳細解釋下第三點。它實際上和 繼承打破了封裝性 里討論的問題很相似,假設有以下代碼:

?
1
2
3
4
5
6
7
8
public class father {
 public father() {
  somemethod();
 }
 
 public void somemethod() {
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
public class son extends father {
 private date date;
 
 public son() {
  this.date = new date();
 }
 
 @override
 public void somemethod() {
  system.out.println("time = " + date.gettime());
 }
}

上述代碼在運行測試時就會拋出nullpointerexception :

?
1
2
3
4
5
6
7
8
public class sontest {
 private son  son = new son();
 
 @test
 public void test() {
  son.somemethod();
 }
}

因為超類的構(gòu)造函數(shù)會在子類的構(gòu)造函數(shù)之前先運行,這里超類的構(gòu)造函數(shù)對somemethod()有依賴,同時somemethod()被重寫,所以超類的構(gòu)造函數(shù)里調(diào)用到的將是son.somemethod(),而這時候子類還沒被初始化,于是在運行到date.gettime()時便拋出了空指針異常。

因此,如果在超類的構(gòu)造函數(shù)里對可覆蓋的方法有依賴,那么在繼承時就可能會出錯。

結(jié)論

繼承有很多優(yōu)點,但使用繼承時應該慎重并多加考慮。同樣用來實現(xiàn)代碼復用的還有復合,如果使用繼承和復合皆可(這是前提),那么應該優(yōu)先使用復合,因為復合可以保持超類對實現(xiàn)細節(jié)的屏蔽,上述關(guān)于繼承的缺點都可以用復合來避免。這也是所謂的復合優(yōu)先于繼承。

如果使用繼承,那么應該留意重寫超類中存在自用性的可覆蓋方法可能會出錯,即使不進行重寫,超類更新時也可能會引入錯誤。同時也應該精心設計超類,對任何相互調(diào)用的可覆蓋方法提供詳細文檔。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/xz816111/p/9080173.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日韩国产成人 | 国产播放啪视频免费视频 | 三体动漫在线观看免费完整版2022 | 1313午夜精品久久午夜片 | 婷婷丁香色综合狠狠色 | 日本嫩模 | 国产精品永久免费自在线观看 | 美国雪白人妖sarina | 亚洲成色爱我久久 | 亚洲成片在线看 | 成人18网址在线观看 | 香蕉精品 | 美女的隐私无遮挡撒尿 | 国产成人综合久久精品红 | 久久久久久久久a免费 | 青青青国产精品国产精品久久久久 | 手机看片福利盒子久久 | 和两个男人玩3p好爽视频 | 日产乱码卡1卡2卡三免费 | 四虎影院永久网址 | 欧美一区二区三区四区视频 | 欧美 变态 另类 人妖班 | 菠萝视频5正版在线观看 | 国产大片线上免费观看 | 美女扒开屁股让男人进去 | 青青青在线视频 | 好涨好大我快受不了了视频网 | 国产精品igao视频网网址 | 亚洲视频在线看 | 日韩天堂在线 | 欧美高清无砖专区欧美精品 | 欧美精品日韩一区二区三区 | 变态 调教 视频 国产九色 | 女人是男人的未来1分49分 | 亚洲日本久久一区二区va | 色花堂中文字幕98堂网址 | 顶级尤物极品女神福利视频 | 欧美日韩视频在线第一区二区三区 | 久久久久久久伊人电影 | 欧美性高清另类videosex死尸 | 亚洲天堂色视频 |