亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

多態對象特性

當創建一個父類的引用指向本類的對象時,如何使用這個對象調取本類的特性?例如:

父類:Traveltool;本類:Taxi;他們的特性:int site;如何調用對象obj3來調用Taxi里面的site值?

Traveltool obj3 = new Taxi();

System.out.println(obj3.site);

這個命令輸出的是Traveltool中的site值。為什么obj3是Taxi的對象,卻調用了父類的特性?

正在回答

5 回答

由于你聲明成員變量是都是public,導致Taxi類中實際上存在兩個site,兩個way變量,當對象為Traveltool時條用的則是父類的site(沒有初值默認為零),就是你的這種情況。想要輸出5則要創建一個子類的對象,如Taxi taxi = (Taxi)obj;System.out.println(taxi.site);結果就是5.

0 回復 有任何疑惑可以回復我~
#1

Levin2016 提問者

謝謝你的回答。但是,如果這個是這樣,那么是不是site里也有兩個canDo()方法呢?而當我用obj調用canDo()方法的時候,輸出的卻是Taxi的canDo()方法,即Taxi can travel fast on road!為什么不是調用父類的方法呢?
2016-07-24 回復 有任何疑惑可以回復我~
#2

Smile丶微冷 回復 Levin2016 提問者

方法和變量不同,由于是繼承關系子類已經將原本父類中的canDo方法覆蓋,也就是創建的對象中只有一個canDo函數,由于是通過new Taxi創建,自然調用的是子類的canDo方法
2016-07-24 回復 有任何疑惑可以回復我~
#3

Levin2016 提問者 回復 Smile丶微冷

謝謝,我還是沒理解透徹。語句:Traveltool obj = new Taxi(); ,實際創建的是Traveltool的對象還是Taxi的對象呢? 如果是Traveltool的對象,為什么調用的是Taxi的方法? 如果是Taxi的對象,為什么調用的是Traveltool的變量值呢?
2016-07-24 回復 有任何疑惑可以回復我~
#4

Smile丶微冷 回復 Levin2016 提問者

實際創建的永遠是new后的類型,new類型時系統是按照Taxi開辟了一塊內存,由于Traveltool是它的父類所以可以引用這塊內存,即Traveltool obj = new Taxi();但實際的內存空間還是Taxi類型。當調用變量時,系統會根據當前的類型就近匹配變量,也就是Traveltool 使用Traveltool 的變量,Taxi使用Taxi的變量。當調用方法時,由于Taxi重寫了Traveltool 的方法,在Taxi只存在一個canDo方法,所以不論用Traveltool 還是Taxi類型的變量去調用canDo方法,調用的都是Taxi重寫過后的方法。
2016-07-24 回復 有任何疑惑可以回復我~
#5

Smile丶微冷 回復 Levin2016 提問者

切記不可以把成員變量的方法的調用過程混淆,父類子類聲明相同的公共變量時是共存的,而方法的重寫意義相當于覆蓋,不能同時存在。
2016-07-24 回復 有任何疑惑可以回復我~
#6

Levin2016 提問者

非常感謝你的耐心解答!
2016-07-25 回復 有任何疑惑可以回復我~
#7

Levin2016 提問者 回復 Smile丶微冷

多謝大神耐心解答!我還有一個疑問,就是如果我用Traveltool obj = new Taxi();創建了對象,我是不是就無法調用taxi的site了?也就是說,我如果想調用子類的成員變量的時候,就不能用繼承的方法創建子類的對象呢?
2016-07-25 回復 有任何疑惑可以回復我~
#8

Smile丶微冷 回復 Levin2016 提問者

當調用Taxi中的site時可以先將Traveltool obj強制轉換成Taxi類型Taxi obj2 = (Taxi)obj;不過出于封裝的考慮,一般情況下是不會將類中的成員變量設置為public,而是通過適當的方法來調用,當子類想要調用父類變量或者方法時使用super,輸出本身的變量時則用this,這樣就既可以得到父類的變量又可以輸出自己的變量。不過子類如果擁有與父類同名的變量時,表示子類的新特性,一般情況不會再去調用父類的同名變量。
2016-07-25 回復 有任何疑惑可以回復我~
查看5條回復

這個通過存儲地址很好解釋,比如創建一個類A占用1.0M內存,類B繼承類A ,創建類B 則占用1.5M內存(即類B內存大小0.5M),當我們new B();時,編譯器為我們分配1.5M內存,分別為(A+B),當我們對象類型是類A時,類A對象就只指向1.0M內存中的數據,所以輸出0,當我們調用方法時,因為B繼承A,并且B類重寫了A的方法,所以我們看到是調用B中的方法。當然,對象類型為B時,對象指向1.5M的內存,我們輸出?site的值也就是B中的數值!(注:個人理解)

0 回復 有任何疑惑可以回復我~

謝謝,我還是沒理解透徹。語句:Traveltool obj = new Taxi(); ,實際創建的是Traveltool的對象還是Taxi的對象呢?

如果是Traveltool的對象,為什么調用的是Taxi的方法?

如果是Taxi的對象,為什么調用的是Traveltool的變量值呢?

0 回復 有任何疑惑可以回復我~

package com.imooc;

//父類

public class Traveltool {

public String way = "Traveltoll can travel!" ;

public int site;

public void canDo(){

System.out.println("Traveltool can travel fast on road! " + "Bike can take " + site + " people!");

}

}

package com.imooc;

//子類

public class Taxi extends Traveltool {

String way = "Taxi travel by road";

int site = 5;

public void canDo(){

System.out.println("Taxi can travel fast on road! " + "Bike can take " + site + " people!");

}

}

package com.imooc;

//初始化類

public class Initial {

public static void main(String[] args) {

// TODO Auto-generated method stub

Traveltool obj = new Taxi();

System.out.println(obj.site);

}

}

結果為什么是0而不是5?

0 回復 有任何疑惑可以回復我~

(我不太清楚你的意思,你是指父類和子類都定義了site這個數據嗎?額,還有,site這個數據你不封裝起來嗎?或者是site是一個方法?)根據多態性,編譯器在編譯的時會通過動態綁定生成一個方法表,如果方法中,有同樣的簽名,會自動調用一個最合適的方法。

0 回復 有任何疑惑可以回復我~
#1

Levin2016 提問者

public class Traveltool {//父類 public int site; public class Taxi extends Traveltool {//子類 String way = "Taxi travel by road"; int site = 5; public class Initial {//初始化類 public static void main(String[] args) { System.out.println(obj.site); //為什么結果是0而不是5?
2016-07-23 回復 有任何疑惑可以回復我~
#2

Levin2016 提問者

public class Initial { public static void main(String[] args) { Traveltool obj = new Taxi(); System.out.println(obj.site); 為什么結果是0而不是5?因為我創建的是子類的對象,為什么不調用子類的site值呢
2016-07-23 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消
Java入門第二季 升級版
  • 參與學習       531144    人
  • 解答問題       6326    個

課程升級!以終為始告別枯燥,在開發和重構中體會Java面向對象編程的奧妙

進入課程

多態對象特性

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號