日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

JAVA面試題解惑系列(三)——變量(屬性)的覆

系統(tǒng) 2090 0

好東西分享
我們來看看這么一道題:

Java代碼 復(fù)制代碼
  1. class ?ParentClass?{ ??
  2. ???? public ? int ?i?=? 10 ; ??
  3. } ??
  4. ??
  5. public ? class ?SubClass? extends ?ParentClass?{ ??
  6. ???? public ? int ?i?=? 30 ; ??
  7. ??
  8. ???? public ? static ? void ?main(String[]?args)?{ ??
  9. ????????ParentClass?parentClass?=? new ?SubClass(); ??
  10. ????????SubClass?subClass?=? new ?SubClass(); ??
  11. ????????System.out.println(parentClass.i?+?subClass.i); ??
  12. ????} ??
  13. }??
    class ParentClass {
	public int i = 10;
}

public class SubClass extends ParentClass {
	public int i = 30;

	public static void main(String[] args) {
		ParentClass parentClass = new SubClass();
		SubClass subClass = new SubClass();
		System.out.println(parentClass.i + subClass.i);
	}
}

  



控制臺的輸出結(jié)果是多少呢?20?40?還是60?

變量,或者叫做類的屬性,在繼承的情況下,如果父類和子類存在同名的變量會出現(xiàn)什么情況呢?這就是這道題要考查的知識點——變量(屬性)的覆蓋。

這個問題雖然簡單,但是情況卻比較復(fù)雜。因為我們不僅要考慮變量、靜態(tài)變量和常量三種情況,還要考慮private、friendly(即不加訪問修飾符)、protected和public四種訪問權(quán)限下對屬性的不同影響。

我們先從普通變量說起。依照我們的慣例,先來看一段代碼:

Java代碼 復(fù)制代碼
  1. class ?ParentClass?{ ??
  2. ???? private ?String?privateField?=? "父類變量--private" ; ??
  3. ??
  4. ???? /*?friendly?*/ String?friendlyField?=? "父類變量--friendly" ; ??
  5. ??
  6. ???? protected ?String?protectedField?=? "父類變量--protected" ; ??
  7. ??
  8. ???? public ?String?publicField?=? "父類變量--public" ; ??
  9. ??
  10. ???? //?private的變量無法直接訪問,因此我們給他增加了一個訪問方法 ??
  11. ???? public ?String?getPrivateFieldValue()?{ ??
  12. ???????? return ?privateField; ??
  13. ????} ??
  14. } ??
  15. ??
  16. public ? class ?SubClass? extends ?ParentClass?{ ??
  17. ???? private ?String?privateField?=? "子類變量--private" ; ??
  18. ??
  19. ???? /*?friendly?*/ String?friendlyField?=? "子類變量--friendly" ; ??
  20. ??
  21. ???? protected ?String?protectedField?=? "子類變量--protected" ; ??
  22. ??
  23. ???? public ?String?publicField?=? "子類變量--public" ; ??
  24. ??
  25. ???? //?private的變量無法直接訪問,因此我們給他增加了一個訪問方法 ??
  26. ???? public ?String?getPrivateFieldValue()?{ ??
  27. ???????? return ?privateField; ??
  28. ????} ??
  29. ??
  30. ???? public ? static ? void ?main(String[]?args)?{ ??
  31. ???????? //?為了便于查閱,我們統(tǒng)一按照private、friendly、protected、public的順序 ??
  32. ???????? //?輸出下列三種情況中變量的值 ??
  33. ??
  34. ???????? //?ParentClass類型,ParentClass對象 ??
  35. ????????ParentClass?parentClass?=? new ?ParentClass(); ??
  36. ????????System.out.println( "ParentClass?parentClass?=?new?ParentClass();" ); ??
  37. ????????System.out.println(parentClass.getPrivateFieldValue()); ??
  38. ????????System.out.println(parentClass.friendlyField); ??
  39. ????????System.out.println(parentClass.protectedField); ??
  40. ????????System.out.println(parentClass.publicField); ??
  41. ??
  42. ????????System.out.println(); ??
  43. ??
  44. ???????? //?ParentClass類型,SubClass對象 ??
  45. ????????ParentClass?subClass?=? new ?SubClass(); ??
  46. ????????System.out.println( "ParentClass?subClass?=?new?SubClass();" ); ??
  47. ????????System.out.println(subClass.getPrivateFieldValue()); ??
  48. ????????System.out.println(subClass.friendlyField); ??
  49. ????????System.out.println(subClass.protectedField); ??
  50. ????????System.out.println(subClass.publicField); ??
  51. ??
  52. ????????System.out.println(); ??
  53. ??
  54. ???????? //?SubClass類型,SubClass對象 ??
  55. ????????SubClass?subClazz?=? new ?SubClass(); ??
  56. ????????System.out.println( "SubClass?subClazz?=?new?SubClass();" ); ??
  57. ????????System.out.println(subClazz.getPrivateFieldValue()); ??
  58. ????????System.out.println(subClazz.friendlyField); ??
  59. ????????System.out.println(subClazz.protectedField); ??
  60. ????????System.out.println(subClazz.publicField); ??
  61. ????} ??
  62. }??
    class ParentClass {
	private String privateField = "父類變量--private";

	/* friendly */String friendlyField = "父類變量--friendly";

	protected String protectedField = "父類變量--protected";

	public String publicField = "父類變量--public";

	// private的變量無法直接訪問,因此我們給他增加了一個訪問方法
	public String getPrivateFieldValue() {
		return privateField;
	}
}

public class SubClass extends ParentClass {
	private String privateField = "子類變量--private";

	/* friendly */String friendlyField = "子類變量--friendly";

	protected String protectedField = "子類變量--protected";

	public String publicField = "子類變量--public";

	// private的變量無法直接訪問,因此我們給他增加了一個訪問方法
	public String getPrivateFieldValue() {
		return privateField;
	}

	public static void main(String[] args) {
		// 為了便于查閱,我們統(tǒng)一按照private、friendly、protected、public的順序
		// 輸出下列三種情況中變量的值

		// ParentClass類型,ParentClass對象
		ParentClass parentClass = new ParentClass();
		System.out.println("ParentClass parentClass = new ParentClass();");
		System.out.println(parentClass.getPrivateFieldValue());
		System.out.println(parentClass.friendlyField);
		System.out.println(parentClass.protectedField);
		System.out.println(parentClass.publicField);

		System.out.println();

		// ParentClass類型,SubClass對象
		ParentClass subClass = new SubClass();
		System.out.println("ParentClass subClass = new SubClass();");
		System.out.println(subClass.getPrivateFieldValue());
		System.out.println(subClass.friendlyField);
		System.out.println(subClass.protectedField);
		System.out.println(subClass.publicField);

		System.out.println();

		// SubClass類型,SubClass對象
		SubClass subClazz = new SubClass();
		System.out.println("SubClass subClazz = new SubClass();");
		System.out.println(subClazz.getPrivateFieldValue());
		System.out.println(subClazz.friendlyField);
		System.out.println(subClazz.protectedField);
		System.out.println(subClazz.publicField);
	}
}

  


這段代碼的運行結(jié)果如下:

  1. ParentClass parentClass = new ParentClass();
  2. 父類變量--private
  3. 父類變量--friendly
  4. 父類變量--protected
  5. 父類變量--public
  6. ParentClass subClass = new SubClass();
  7. 子類變量--private
  8. 父類變量--friendly
  9. 父類變量--protected
  10. 父類變量--public
  11. SubClass subClazz = new SubClass();
  12. 子類變量--private
  13. 子類變量--friendly
  14. 子類變量--protected
  15. 子類變量--public


從上面的結(jié)果中可以看出,private的變量與其它三種訪問權(quán)限變量的不同,這是由于方法的重寫(override)而引起的。關(guān)于重寫知識的回顧留給以后的章節(jié),這里我們來看一下其它三種訪問權(quán)限下變量的覆蓋情況。

分析上面的輸出結(jié)果就會發(fā)現(xiàn),變量的值取決于我們定義的變量的類型,而不是創(chuàng)建的對象的類型。

在上面的例子中,同名的變量訪問權(quán)限也是相同的,那么對于名稱相同但是訪問權(quán)限不同的變量,情況又會怎樣呢?事實勝于雄辯,我們繼續(xù)來做測試。由于private變量的特殊性,在接下來的實驗中我們都把它排除在外,不予考慮。

由于上面的例子已經(jīng)說明了,當(dāng)變量類型是父類(ParentClass)時,不管我們創(chuàng)建的對象是父類(ParentClass)的還是子類(SubClass)的,都不存在屬性覆蓋的問題,因此接下來我們也只考慮變量類型和創(chuàng)建對象都是子類(SubClass)的情況。

Java代碼 復(fù)制代碼
  1. class ?ParentClass?{ ??
  2. ???? /*?friendly?*/ String?field?=? "父類變量" ; ??
  3. } ??
  4. ??
  5. public ? class ?SubClass? extends ?ParentClass?{ ??
  6. ???? protected ?String?field?=? "子類變量" ; ??
  7. ??
  8. ???? public ? static ? void ?main(String[]?args)?{ ??
  9. ????????SubClass?subClass?=? new ?SubClass(); ??
  10. ????????System.out.println(subClass.field); ??
  11. ????} ??
  12. }??
    class ParentClass {
	/* friendly */String field = "父類變量";
}

public class SubClass extends ParentClass {
	protected String field = "子類變量";

	public static void main(String[] args) {
		SubClass subClass = new SubClass();
		System.out.println(subClass.field);
	}
}

  


運行結(jié)果:

  • 子類變量

?

Java代碼 復(fù)制代碼
  1. class ?ParentClass?{ ??
  2. ???? public ?String?field?=? "父類變量" ; ??
  3. } ??
  4. ??
  5. public ? class ?SubClass? extends ?ParentClass?{ ??
  6. ???? protected ?String?field?=? "子類變量" ; ??
  7. ??
  8. ???? public ? static ? void ?main(String[]?args)?{ ??
  9. ????????SubClass?subClass?=? new ?SubClass(); ??
  10. ????????System.out.println(subClass.field); ??
  11. ????} ??
  12. }??
    class ParentClass {
	public String field = "父類變量";
}

public class SubClass extends ParentClass {
	protected String field = "子類變量";

	public static void main(String[] args) {
		SubClass subClass = new SubClass();
		System.out.println(subClass.field);
	}
}

  


運行結(jié)果:

  • 子類變量


上面兩段不同的代碼,輸出結(jié)果確是相同的。事實上,我們可以將父類和子類屬性前的訪問修飾符在friendly、protected和public之間任意切換,得到的結(jié)果都是相同的。也就是說訪問修飾符并不影響屬性的覆蓋,關(guān)于這一點大家可以自行編寫測試代碼驗證。

對于靜態(tài)變量和常量又會怎樣呢?我們繼續(xù)來看:

Java代碼 復(fù)制代碼
  1. class ?ParentClass?{ ??
  2. ???? public ? static ?String?staticField?=? "父類靜態(tài)變量" ; ??
  3. ??
  4. ???? public ? final ?String?finalField?=? "父類常量" ; ??
  5. ??
  6. ???? public ? static ? final ?String?staticFinalField?=? "父類靜態(tài)常量" ; ??
  7. } ??
  8. ??
  9. public ? class ?SubClass? extends ?ParentClass?{ ??
  10. ???? public ? static ?String?staticField?=? "子類靜態(tài)變量" ; ??
  11. ??
  12. ???? public ? final ?String?finalField?=? "子類常量" ; ??
  13. ??
  14. ???? public ? static ? final ?String?staticFinalField?=? "子類靜態(tài)常量" ; ??
  15. ??
  16. ???? public ? static ? void ?main(String[]?args)?{ ??
  17. ????????SubClass?subClass?=? new ?SubClass(); ??
  18. ????????System.out.println(SubClass.staticField); ??
  19. ???????? //?注意,這里的subClass變量,不是SubClass類 ??
  20. ????????System.out.println(subClass.finalField); ??
  21. ????????System.out.println(SubClass.staticFinalField); ??
  22. ????} ??
  23. }??
    class ParentClass {
	public static String staticField = "父類靜態(tài)變量";

	public final String finalField = "父類常量";

	public static final String staticFinalField = "父類靜態(tài)常量";
}

public class SubClass extends ParentClass {
	public static String staticField = "子類靜態(tài)變量";

	public final String finalField = "子類常量";

	public static final String staticFinalField = "子類靜態(tài)常量";

	public static void main(String[] args) {
		SubClass subClass = new SubClass();
		System.out.println(SubClass.staticField);
		// 注意,這里的subClass變量,不是SubClass類
		System.out.println(subClass.finalField);
		System.out.println(SubClass.staticFinalField);
	}
}

  


運行結(jié)果如下:

  1. 子類靜態(tài)變量
  2. 子類常量
  3. 子類靜態(tài)常量


雖然上面的結(jié)果中包含“子類靜態(tài)變量”和“子類靜態(tài)常量”,但這并不表示父類的“靜態(tài)變量”和“靜態(tài)常量”可以被子類覆蓋,因為它們都是屬于類,而不屬于對象。

上面的例子中,我們一直用對象來對變量(屬性)的覆蓋做測試,如果是基本類型的變量,結(jié)果是否會相同呢?答案是肯定的,這里我們就不再一一舉例說明了。

最后,我們來做個總結(jié)。通過以上測試,可以得出一下結(jié)論:

  1. 由于private變量受訪問權(quán)限的限制,它不能被覆蓋。
  2. 屬性的值取父類還是子類并不取決于我們創(chuàng)建對象的類型,而是取決于我們定義的變量的類型。
  3. friendly、protected和public修飾符并不影響屬性的覆蓋。
  4. 靜態(tài)變量和靜態(tài)常量屬于類,不屬于對象,因此它們不能被覆蓋。
  5. 常量可以被覆蓋。
  6. 對于基本類型和對象,它們適用同樣的覆蓋規(guī)律。


我們再回到篇首的那道題,我想大家都已經(jīng)知道答案了,輸出結(jié)果應(yīng)該是40。

?

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

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

JAVA面試題解惑系列(三)——變量(屬性)的覆蓋


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 镇雄县| 灵宝市| 巍山| 黔南| 峨眉山市| 于田县| 凤冈县| 漠河县| 湖北省| 靖西县| 水城县| 乐业县| 蒙城县| 桦川县| 阳原县| 张掖市| 古丈县| 望江县| 永登县| 托克逊县| 萝北县| 哈密市| 进贤县| 旺苍县| 乌拉特后旗| 奉化市| 崇州市| 中西区| 阜新| 铜川市| 唐海县| 砀山县| 繁峙县| 洞口县| 云安县| 安龙县| 涟源市| 阿城市| 巨鹿县| 辉南县| 恭城|