1. 程式人生 > >隨筆53 java存在繼承關系的類之間的調用

隨筆53 java存在繼承關系的類之間的調用

xtend 應該 sys pan 返回值 setvalue 分享 stat main方法

 1 /**
 2  * Created by zmt on 2016/12/22.
 3  */
 4 public class Test {
 5     public static void main(String [] args){
 6         System.out.println(new B().getValue());
 7     }
 8     static class A{
 9         protected int value;
10         public A(int v) {
11             setValue(v);
12         }
13 public void setValue(int value){ 14 this.value = value; 15 } 16 public int getValue(){ 17 try{ 18 value++; 19 return value; 20 } catch(Exception e){ 21 System.out.println(e.toString()); 22 } finally
{ 23 this.setValue(value); 24 System.out.println(value); 25 } 26 return value; 27 } 28 } 29 static class B extends A{ 30 public B() { 31 super(5); 32 setValue(getValue() - 3); 33 } 34 public
void setValue(int value){ 35 super.setValue(2 * value); 36 } 37 } 38 }

調試看下執行過程。

首先是main方法,new了一個B對象,然後就是調用該對象的getValue()方法,這個沒什麽好說的。

技術分享圖片

接下來就要執行B類的構造方法了,這個也沒啥說的

技術分享圖片

然後執行B的構造方法,super(5);也就是調用B的父類A的構造方法,應該是到A構造的setValue()方法,同時A的成員變量value的值被賦為5,通過調試可以清楚的看到。

技術分享圖片

接下來就是執行setValue()方法了,但是此時A類和B類都有一個setValue()方法,到底執行哪一個呢,我一開始認為是A類的setValue()方法,但是結果並不是這樣的,看下調試過程。

技術分享圖片

執行的是B的setValue()方法,,,因為現在正在執行B類的構造方法,所以默認先會調用B類中的方法,如果B類中沒有,才會調用其父類A中的方法。我們繼續看,,,接下來到super.setValue(2 * value),即執行A類的setValue()方法,這時,A類的成員變量value應該就變成了10

技術分享圖片

繼續往下看,這時B類的構造方法中的super(5)就執行完了,然後就到了setValue(getValue() - 3)方法

技術分享圖片

接著執行getValue()方法,首先在B類中找,但B類沒有getValue()方法,所以就執行A類中的getValue()方法,A類中肯定是有的,要不然編譯就不會通過

技術分享圖片

然後就開始執行try、catch、finally這一塊,給A的成員變量value自增,從之前的10變為11,然後直接返回value,沒有捕獲異常,繼續到finally裏面的this.setValue(value)

技術分享圖片

然後這個this指的到底是A類還是B類呢,答案是B類,因為現在是在執行B的構造方法,所以this指的應該是B類,即調用B類的setValue(int value)方法

技術分享圖片

然後又super.setValue(2 * value);執行父類A的setValue(int value),把2 * 11作為參數傳遞,A類的setValue(int value)把傳進來的value值賦給了A的成員變量value,變成了22。

技術分享圖片

然後this.setValue(value)就執行完了,最後輸出value,22

技術分享圖片

到這兒getValue()方法就執行完了,但是有一點需要註意,此時的value為22,但是getValue()的返回值確是11,因為在try{ }中已經return了,所以這個方法的返回值級已經保存下來了,是11,即使finally{ }裏面又對value的值做出了改變,但是getValue()的返回值是不會變的。接著繼續執行B類構造方法中的setValue(getValue() - 3);getValue()是11,所以B的setValue(int value)方法的參數就為8,接著又到了super.setValue(2 * value)

技術分享圖片

調用A類的setValue(int value)方法,同時將參數賦值給A類的成員變量value,此時value變為16

技術分享圖片

到這兒B類的構造方法就全部執行完了,也就是new B(),然後又調用了該對象 的getValue()方法,B類沒有,但是父類A有,所以,

技術分享圖片

繼續try{ }、catch{ }、finally{ },A類的成員變量value為16,然後value++,再返回,這時getValue()的返回值已經確定了,就是17,即使在finally中對value做出改變,其返回值不會變。然後到finally{ },又是this.setValue(value),前面已經說過了,這個this指的是B類的this,所以調用B類的setValue(int value)

技術分享圖片

接著又是super.setValue(2 * value),調用A類的setValue(),並把2 * 17作為參數傳遞過去。

技術分享圖片

把參數賦給A的成員變量value,這時this.setValue(value)就執行完了,此時的value為34。最後輸出value。

技術分享圖片

需要註意的是,此時的getValue()方法的返回值是17,這個前面已經提到了,到這兒,整個new B().getValue()就執行完了,最後又輸出了getValue的返回值,也就是17。所以整個過程執行完後的輸出結果是22、34、17。。。。。。

技術分享圖片

這道題雖然繞了很多彎,但是我們做完後發現整體過程其實並不是很復雜,就是自類繼承父類,調用方法時先是調用子類中的方法,如果沒有就調用父類中的方法,還有一點就是try{ }、catch{ }、finally{ }返回值的問題,一旦try{ }中返回了某一個值,如果finally有返回值,finally中的返回值會覆蓋try的返回值,如果finally沒有返回值,就是try中的返回值。掌握了這些,這道題就顯得很簡單了。

隨筆53 java存在繼承關系的類之間的調用