亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

JAVA面試題解惑系列(九)——繼承、多態(tài)、重載

系統(tǒng) 2053 0

好東西分享

什么是多態(tài)?它的實(shí)現(xiàn)機(jī)制是什么呢?重載和重寫的區(qū)別在那里?這就是這一次我們要回顧的四個(gè)十分重要的概念:繼承、多態(tài)、重載和重寫。

繼承(inheritance)

簡(jiǎn)單的說,繼承就是在一個(gè)現(xiàn)有類型的基礎(chǔ)上,通過增加新的方法或者重定義已有方法(下面會(huì)講到,這種方式叫重寫)的方式,產(chǎn)生一個(gè)新的類型。繼承是面向?qū)ο蟮娜齻€(gè)基本特征--封裝、繼承、多態(tài)的其中之一,我們?cè)谑褂肑AVA時(shí)編寫的每一個(gè)類都是在繼承,因?yàn)樵贘AVA語(yǔ)言中,java.lang.Object類是所有類最根本的基類(或者叫父類、超類),如果我們新定義的一個(gè)類沒有明確地指定繼承自哪個(gè)基類,那么JAVA就會(huì)默認(rèn)為它是繼承自O(shè)bject類的。

我們可以把JAVA中的類分為以下三種:

  1. 類:使用class定義且不含有抽象方法的類。
  2. 抽象類:使用abstract class定義的類,它可以含有,也可以不含有抽象方法。
  3. 接口:使用interface定義的類。


在這三種類型之間存在下面的繼承規(guī)律:

  • 類可以繼承(extends)類,可以繼承(extends)抽象類,可以繼承(implements)接口。
  • 抽象類可以繼承(extends)類,可以繼承(extends)抽象類,可以繼承(implements)接口。
  • 接口只能繼承(extends)接口。


請(qǐng)注意上面三條規(guī)律中每種繼承情況下使用的不同的關(guān)鍵字extends和implements,它們是不可以隨意替換的。大家知道,一個(gè)普通類繼承一個(gè)接口后,必須實(shí)現(xiàn)這個(gè)接口中定義的所有方法,否則就只能被定義為抽象類。我在這里之所以沒有對(duì)implements關(guān)鍵字使用“實(shí)現(xiàn)”這種說法是因?yàn)閺母拍钌蟻?lái)說它也是表示一種繼承關(guān)系,而且對(duì)于抽象類implements接口的情況下,它并不是一定要實(shí)現(xiàn)這個(gè)接口定義的任何方法,因此使用繼承的說法更為合理一些。

以上三條規(guī)律同時(shí)遵守下面這些約束:

  1. 類和抽象類都只能最多繼承一個(gè)類,或者最多繼承一個(gè)抽象類,并且這兩種情況是互斥的,也就是說它們要么繼承一個(gè)類,要么繼承一個(gè)抽象類。
  2. 類、抽象類和接口在繼承接口時(shí),不受數(shù)量的約束,理論上可以繼承無(wú)限多個(gè)接口。當(dāng)然,對(duì)于類來(lái)說,它必須實(shí)現(xiàn)它所繼承的所有接口中定義的全部方法。
  3. 抽象類繼承抽象類,或者實(shí)現(xiàn)接口時(shí),可以部分、全部或者完全不實(shí)現(xiàn)父類抽象類的抽象(abstract)方法,或者父類接口中定義的接口。
  4. 類繼承抽象類,或者實(shí)現(xiàn)接口時(shí),必須全部實(shí)現(xiàn)父類抽象類的全部抽象(abstract)方法,或者父類接口中定義的全部接口。


繼承給我們的編程帶來(lái)的好處就是對(duì)原有類的復(fù)用(重用)。就像模塊的復(fù)用一樣,類的復(fù)用可以提高我們的開發(fā)效率,實(shí)際上,模塊的復(fù)用是大量類的復(fù)用疊加后的效果。除了繼承之外,我們還可以使用組合的方式來(lái)復(fù)用類。所謂組合就是把原有類定義為新類的一個(gè)屬性,通過在新類中調(diào)用原有類的方法來(lái)實(shí)現(xiàn)復(fù)用。如果新定義的類型與原有類型之間不存在被包含的關(guān)系,也就是說,從抽象概念上來(lái)講,新定義類型所代表的事物并不是原有類型所代表事物的一種,比如黃種人是人類的一種,它們之間存在包含與被包含的關(guān)系,那么這時(shí)組合就是實(shí)現(xiàn)復(fù)用更好的選擇。下面這個(gè)例子就是組合方式的一個(gè)簡(jiǎn)單示例:

Java代碼 復(fù)制代碼
  1. public ? class ?Sub?{ ??
  2. ???? private ?Parent?p?=? new ?Parent(); ??
  3. ??
  4. ???? public ? void ?doSomething()?{ ??
  5. ???????? //?復(fù)用Parent類的方法 ??
  6. ????????p.method(); ??
  7. ???????? //?other?code ??
  8. ????} ??
  9. } ??
  10. ??
  11. class ?Parent?{ ??
  12. ???? public ? void ?method()?{ ??
  13. ???????? //?do?something?here ??
  14. ????} ??
  15. }??
    public class Sub {
	private Parent p = new Parent();

	public void doSomething() {
		// 復(fù)用Parent類的方法
		p.method();
		// other code
	}
}

class Parent {
	public void method() {
		// do something here
	}
}

  


當(dāng)然,為了使代碼更加有效,我們也可以在需要使用到原有類型(比如Parent p)時(shí),才對(duì)它進(jìn)行初始化。

使用繼承和組合復(fù)用原有的類,都是一種增量式的開發(fā)模式,這種方式帶來(lái)的好處是不需要修改原有的代碼,因此不會(huì)給原有代碼帶來(lái)新的BUG,也不用因?yàn)閷?duì)原有代碼的修改而重新進(jìn)行測(cè)試,這對(duì)我們的開發(fā)顯然是有益的。因此,如果我們是在維護(hù)或者改造一個(gè)原有的系統(tǒng)或模塊,尤其是對(duì)它們的了解不是很透徹的時(shí)候,就可以選擇增量開發(fā)的模式,這不僅可以大大提高我們的開發(fā)效率,也可以規(guī)避由于對(duì)原有代碼的修改而帶來(lái)的風(fēng)險(xiǎn)。

多態(tài)(Polymorphism)

多態(tài)是又一個(gè)重要的基本概念,上面說到了,它是面向?qū)ο蟮娜齻€(gè)基本特征之一。究竟什么是多態(tài)呢?我們先看看下面的例子,來(lái)幫助理解:

Java代碼 復(fù)制代碼
  1. //汽車接口 ??
  2. interface ?Car?{ ??
  3. ???? //?汽車名稱 ??
  4. ????String?getName(); ??
  5. ??
  6. ???? //?獲得汽車售價(jià) ??
  7. ???? int ?getPrice(); ??
  8. } ??
  9. ??
  10. //?寶馬 ??
  11. class ?BMW? implements ?Car?{ ??
  12. ???? public ?String?getName()?{ ??
  13. ???????? return ? "BMW" ; ??
  14. ????} ??
  15. ??
  16. ???? public ? int ?getPrice()?{ ??
  17. ???????? return ? 300000 ; ??
  18. ????} ??
  19. } ??
  20. ??
  21. //?奇瑞QQ ??
  22. class ?CheryQQ? implements ?Car?{ ??
  23. ???? public ?String?getName()?{ ??
  24. ???????? return ? "CheryQQ" ; ??
  25. ????} ??
  26. ??
  27. ???? public ? int ?getPrice()?{ ??
  28. ???????? return ? 20000 ; ??
  29. ????} ??
  30. } ??
  31. ??
  32. //?汽車出售店 ??
  33. public ? class ?CarShop?{ ??
  34. ???? //?售車收入 ??
  35. ???? private ? int ?money?=? 0 ; ??
  36. ??
  37. ???? //?賣出一部車 ??
  38. ???? public ? void ?sellCar(Car?car)?{ ??
  39. ????????System.out.println( "車型:" ?+?car.getName()?+? "??單價(jià):" ?+?car.getPrice()); ??
  40. ???????? //?增加賣出車售價(jià)的收入 ??
  41. ????????money?+=?car.getPrice(); ??
  42. ????} ??
  43. ??
  44. ???? //?售車總收入 ??
  45. ???? public ? int ?getMoney()?{ ??
  46. ???????? return ?money; ??
  47. ????} ??
  48. ??
  49. ???? public ? static ? void ?main(String[]?args)?{ ??
  50. ????????CarShop?aShop?=? new ?CarShop(); ??
  51. ???????? //?賣出一輛寶馬 ??
  52. ????????aShop.sellCar( new ?BMW()); ??
  53. ???????? //?賣出一輛奇瑞QQ ??
  54. ????????aShop.sellCar( new ?CheryQQ()); ??
  55. ????????System.out.println( "總收入:" ?+?aShop.getMoney()); ??
  56. ????} ??
  57. }??
    //汽車接口
interface Car {
	// 汽車名稱
	String getName();

	// 獲得汽車售價(jià)
	int getPrice();
}

// 寶馬
class BMW implements Car {
	public String getName() {
		return "BMW";
	}

	public int getPrice() {
		return 300000;
	}
}

// 奇瑞QQ
class CheryQQ implements Car {
	public String getName() {
		return "CheryQQ";
	}

	public int getPrice() {
		return 20000;
	}
}

// 汽車出售店
public class CarShop {
	// 售車收入
	private int money = 0;

	// 賣出一部車
	public void sellCar(Car car) {
		System.out.println("車型:" + car.getName() + "  單價(jià):" + car.getPrice());
		// 增加賣出車售價(jià)的收入
		money += car.getPrice();
	}

	// 售車總收入
	public int getMoney() {
		return money;
	}

	public static void main(String[] args) {
		CarShop aShop = new CarShop();
		// 賣出一輛寶馬
		aShop.sellCar(new BMW());
		// 賣出一輛奇瑞QQ
		aShop.sellCar(new CheryQQ());
		System.out.println("總收入:" + aShop.getMoney());
	}
}

  


運(yùn)行結(jié)果:

  1. 車型:BMW? 單價(jià):300000
  2. 車型:CheryQQ? 單價(jià):20000
  3. 總收入:320000


繼承是多態(tài)得以實(shí)現(xiàn)的基礎(chǔ)。從字面上理解,多態(tài)就是一種類型(都是Car類型)表現(xiàn)出多種狀態(tài)(寶馬汽車的名稱是BMW,售價(jià)是300000;奇瑞汽車的名稱是CheryQQ,售價(jià)是2000)。將一個(gè)方法調(diào)用同這個(gè)方法所屬的主體(也就是對(duì)象或類)關(guān)聯(lián)起來(lái)叫做綁定,分前期綁定和后期綁定兩種。下面解釋一下它們的定義:

  1. 前期綁定:在程序運(yùn)行之前進(jìn)行綁定,由編譯器和連接程序?qū)崿F(xiàn),又叫做靜態(tài)綁定。比如static方法和final方法,注意,這里也包括private方法,因?yàn)樗请[式final的。
  2. 后期綁定:在運(yùn)行時(shí)根據(jù)對(duì)象的類型進(jìn)行綁定,由方法調(diào)用機(jī)制實(shí)現(xiàn),因此又叫做動(dòng)態(tài)綁定,或者運(yùn)行時(shí)綁定。除了前期綁定外的所有方法都屬于后期綁定。


多態(tài)就是在后期綁定這種機(jī)制上實(shí)現(xiàn)的。多態(tài)給我們帶來(lái)的好處是消除了類之間的耦合關(guān)系,使程序更容易擴(kuò)展。比如在上例中,新增加一種類型汽車的銷售,只需要讓新定義的類繼承Car類并實(shí)現(xiàn)它的所有方法,而無(wú)需對(duì)原有代碼做任何修改,CarShop類的sellCar(Car car)方法就可以處理新的車型了。新增代碼如下:

Java代碼 復(fù)制代碼
  1. //?桑塔納汽車 ??
  2. class ?Santana? implements ?Car?{ ??
  3. ???? public ?String?getName()?{ ??
  4. ???????? return ? "Santana" ; ??
  5. ????} ??
  6. ??
  7. ???? public ? int ?getPrice()?{ ??
  8. ???????? return ? 80000 ; ??
  9. ????} ??
  10. }??
    // 桑塔納汽車
class Santana implements Car {
	public String getName() {
		return "Santana";
	}

	public int getPrice() {
		return 80000;
	}
}

  



重載(overloading)和重寫(overriding)

重載和重寫都是針對(duì)方法的概念,在弄清楚這兩個(gè)概念之前,我們先來(lái)了解一下什么叫方法的型構(gòu)(英文名是signature,有的譯作“簽名”,雖然它被使用的較為廣泛,但是這個(gè)翻譯不準(zhǔn)確的)。型構(gòu)就是指方法的組成結(jié)構(gòu),具體包括方法的名稱和參數(shù),涵蓋參數(shù)的數(shù)量、類型以及出現(xiàn)的順序,但是不包括方法的返回值類型,訪問權(quán)限修飾符,以及abstract、static、final等修飾符。比如下面兩個(gè)就是具有相同型構(gòu)的方法:

Java代碼 復(fù)制代碼
  1. public ? void ?method( int ?i,?String?s)?{ ??
  2. ???? //?do?something ??
  3. } ??
  4. ??
  5. public ?String?method( int ?i,?String?s)?{ ??
  6. ???? //?do?something ??
  7. }??
    public void method(int i, String s) {
	// do something
}

public String method(int i, String s) {
	// do something
}

  


而這兩個(gè)就是具有不同型構(gòu)的方法:

Java代碼 復(fù)制代碼
  1. public ? void ?method( int ?i,?String?s)?{ ??
  2. ???? //?do?something ??
  3. } ??
  4. ??
  5. public ? void ?method(String?s,? int ?i)?{ ??
  6. ???? //?do?something ??
  7. }??
    public void method(int i, String s) {
	// do something
}

public void method(String s, int i) {
	// do something
}

  


了解完型構(gòu)的概念后我們?cè)賮?lái)看看重載和重寫,請(qǐng)看它們的定義:

  • 重寫,英文名是overriding,是指在繼承情況下,子類中定義了與其基類中方法具有相同型構(gòu)的新方法,就叫做子類把基類的方法重寫了。這是實(shí)現(xiàn)多態(tài)必須的步驟。
  • 重載,英文名是overloading,是指在同一個(gè)類中定義了一個(gè)以上具有相同名稱,但是型構(gòu)不同的方法。在同一個(gè)類中,是不允許定義多于一個(gè)的具有相同型構(gòu)的方法的。


我們來(lái)考慮一個(gè)有趣的問題:構(gòu)造器可以被重載嗎?答案當(dāng)然是可以的,我們?cè)趯?shí)際的編程中也經(jīng)常這么做。實(shí)際上構(gòu)造器也是一個(gè)方法,構(gòu)造器名就是方法名,構(gòu)造器參數(shù)就是方法參數(shù),而它的返回值就是新創(chuàng)建的類的實(shí)例。但是構(gòu)造器卻不可以被子類重寫,因?yàn)樽宇悷o(wú)法定義與基類具有相同型構(gòu)的構(gòu)造器。

?

向原作者致敬,轉(zhuǎn)自:

作者:臧圩人(zangweiren)
網(wǎng)址: http://zangweiren.iteye.com

JAVA面試題解惑系列(九)——繼承、多態(tài)、重載和重寫


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 国产精品夜色视频一区二区 | 免费观看欧美一级毛片 | 免费观看黄色毛片 | 国产情侣普通话刺激对白 | 91综合久久婷婷久久 | 亚州毛片| 国产尤物在线视频 | 亚洲h在线观看 | 日韩中文字幕免费观看 | 热久久在线观看 | 四虎国产精品永久地址51 | 四虎影视国产精品永久在线 | 精品无人乱码区1区2区3区 | 91视频网址入口 | 老师粗又长好猛好爽视频 | 天天上天天操 | 亚洲区一区 | 干亚洲美女 | 黄黄视频在线观看 | 奇米影视亚洲狠狠色777不卡 | 成年人天堂 | 久久99精品久久久久久 | 色综合久久综合网 | 国产综合在线播放 | 韩国高清乱理伦片中文 | 天天干天天操天天操 | 亚洲一区二区三区日本久久九 | 夜夜操免费视频 | 91精品日本久久久久久牛牛 | 亚洲专区中文字幕 | 99热久久精里都是精品6 | 国产区在线观看视频 | 黄片毛片在线观看 | 日本人成18在线播放 | 狠狠综合视频精品播放 | 日韩一级a毛片欧美一级 | 欧美v亚洲v国产v | 特级做人爱c级特级aav毛片 | 久久久久久综合 | 美女视频黄是免费的 | 一区二区三区在线免费看 |