繼承自抽象類的題目


寫這個案例的時候,看到了有一些提問:關於繼承時,子類調用父類無參構造器時,是否會產生父類對象的問題。答案是不會,舉個簡單的例子,如果父類是抽象類時,肯定不會產生對象了,調用父類無參的構造器,只是完成了父類的初始化操作。

下面這個案例整合了繼承,靜態成員,構造器的執行順序以及就近原則問題的分析,看到很多面試題經常會出此類的題目,具體看例子。


父類:

public abstract class Fu {
    static int count=3;
    int a=3;
    
    static{
    	System.out.println("父類的靜態代碼塊");
    }
    
    public Fu() {
		a=5;
		System.out.println("執行父類的構造方法");		
	}
	
    public void display(){
    	System.out.println("父類的diaplay()方法");
    	System.out.println(a);
    	show();
    }
    
	public void show(){
		System.out.println("父類的show方法");
	}
      
}

子類:

public class Zi extends Fu {	
	 static int count=10;
     int a=6;
     
     static{
    	 System.out.println("子類的靜態代碼塊");
     }
     
     public Zi() {
		System.out.println("執行子類的構造方法");		
	}

	public void show(){
    	 System.out.println("子類的show方法");
    	 System.out.println(a);
     }
}

測試類:

public class Test {
	static{
		System.out.println("測試類的靜態代碼塊!");
	}
	
	public static void main(String[] args) {
		Zi zi = new Zi();
		zi.display();
	}
         
}

執行main(),會得到怎樣的結果呢?看控制檯的輸出結果:

測試類的靜態代碼塊!        1
父類的靜態代碼塊                2
子類的靜態代碼塊                3
執行父類的構造方法            4
執行子類的構造方法            5
父類的diaplay()方法            6
5                                              7
子類的show方法                   8
6                                              9

下面是關於執行步驟的分析:

1.jvm加載含有main()的類,打印結果1
2.執行main(),創建子類對象,會在創建子類對象之前調用父類無參的構造方法,所以初始化父類,打印結果2
3.初始化完父類,初始化子類,打印結果3
4.執行父類的構造方法,完成父類的初始化,但不會創建父類對象(抽象類,即使不是抽象類,也不會創建父類對象,只有new,纔會創建對象)。打印結果4
5.執行子類的構造方法,準備創建子類對象,打印結果5
6,調用子類的display()方法,子類沒有重寫,所以調用父類的diaplay()方法,打印結果6
7.然後輸出父類的成員,就近原則(看圖)打印結果7
8.在display()中調用show()方法,子類覆蓋了其show(),子類的空間也有,調用的是子類的show()方法。打印結果8
9.最後就近,打印子類的成員,打印結果9


爲此我還爲繼承的關係畫了個內存圖


關於內存圖的需要解釋的地方:子類繼承父類時,創建子類對象以後,會在堆內存中給子類對象分配一塊內存空間,這個子類中空間中還存有一個父類的空間裝着父類的一些成員。可以總結爲,一塊地址,兩片空間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章