Android面試筆記總結(三)

有總結的工作纔有意義,有總結的人生纔會有進步。

本系列面試筆記所有問題,源自面試過程中的記錄總結,主要涉及Java和Android,但是由於面試過程中任何問題都有可能被問到,所以也會涉及一些其他方向的知識。部分答案參考網上朋友的文章,如有錯誤之處,歡迎批評指正。奮鬥

在面試的過程中,經常被問到一些平時編程忽略的細節問題,比如強制類型轉換什麼時候可以強制轉換,什麼可以編譯通過卻報運行錯誤。這些細節如果不是平時加以實踐並注意,在真正被問到時還真有點蒙 - -

以下是我對父類子類之間類型轉換,以及動態鏈接等問題的總結。

強制類型轉換規則(個人總結):

1)在同一個繼承樹上的類都可以相互進行強制類型轉換,這些轉換在編譯是都可以通過,但是在運行時,部分情況會報ClassCastException異常(規則第五條後續講解)。比如:A extends B, B extends C; 則A B C 三個類的對象都可以相互強轉。

2)不在同一個繼承樹上的類型不可以進行強制類型轉換(編譯不會通過)。

3)兩個子類不可以進行強制類型轉換。

4)一個子類的對象可以強制轉換成父類的對象。

5)一個父類的對象在強制轉換成子類對象編譯可以通過,但是運行時會報ClassCastException異常。

注意:一個對象進行強制類型轉換之後,對象的類型就發生了改變,當使用這個對象調用屬性和方法時,調用的是轉換之後類的屬性和方法。(注意動態鏈接問題,後文介紹)

從內存角度理解強制轉換:

假設現在有一個父類father,他裏面的變量需要佔用1M的內存。這個father類有一個子類Son,需要佔用0.5M的內存。

結合實例來分析強制類型轉換:

Father f = new Father(); //系統將爲其分配1M的內存空間。


Son s = new Son();//系統將爲其分配1.5M的內存空間。因爲子類會有一個隱藏的super指向父類實例,所以在實例 化子類對象之前,會先去實例化一個父類對象。也就是會先執行父類的構造函數。也是由於對象s中包含了父類的實例,所以子類對象s纔可以調用父類father的方法。


Son s1 = s; //  s1指向s的1.5M內存


Father f1 = (Father)s; //這是f1將指向對象s那1.5M內存中的屬於父類實例的1M內存,所以f1這個對象只能調用父 類的方法和屬性(存在1M內存中的),而不能調用子類的方法(存在0.5M內存中)


Son s2 = (Son) f;//編譯通過,運行時報ClassCastException異常。因爲f中只有1M的內存,而子類的引用s2必須有 1.5M的內存才能運行,所以在運行時,會報類型轉換的異常。


Son s3 = (Son)f1;//這個語句可以正常運行。因爲f1是有子類對象s轉換而來的,所以她是具有1.5M內存的。只不 過f1指向的只有1M內存,但是既然他具備1.5M的內存,s3自然會指向1.5M的內存,所以這局運行時正常。


什麼是動態鏈接?

前提:父類引用指向了子類對象。Father f = new Son();

當父類引用f調用一個方法時,比如f.foo();

若 foo()這個方法在子類被重寫了,調用子類的foo();

若foo()這個方法在子類沒有被重寫。調用父類的foo();

以上兩點就是java語言的動態鏈接。這個特點也體現了Java語言的多態性。

注意:只有方法纔會被重寫,屬性不可以重寫。所以動態鏈接這個性質只是針對方法而言。f.name 一定指的是父類的name屬性





















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