20172311 2017-2018-2 《程序設計與數據結構》第七周學習總結
教材學習內容總結
本周主要學習了繼承的相關知識:
1.繼承在父類和子類之間建立了一種“是”關系,即子類是一種更具體的父類版本
2.繼承具有單向性
3.父類的私有方法或變量不能在子類中訪問
4.protected可見性提供了允許繼承的最大可能的封裝性。
5.使用super引用可以調用父類的構造方法,用super引用調用父類構造方法的操作只能在子類中執行,且必須在第一行執行,super引用也可以引用父類的其他變量和方法。
6.Java語言設計者明確決定不支持多繼承。可以依靠接口提供多繼承的最好特性而不增加歧義。
7.可以用final修飾符定義一個方法,子類將不能重寫final方法。這種技術用於保證子類必須使用的一個特定方法。
8.在類層次結構中,應當合理地將類的公共特征保持在盡可能高的類層次級上,從而最大化復用現有類的可能性,有助於軟件的維護。
9.繼承機制具有傳遞性。
10.所有的Java類都直接或間接地由Object類派生,Java程序的每一個類都繼承toString方法和equals方法。重寫Object類的toString方法和equals方法一般是為了滿足用戶自己的需求。
11.抽象類的引入。
12.類的繼承和接口的繼承不能重疊,即接口不能用於派生新類,類不能用於派生接口,僅當一個類設計為實現一個接口時,這個實現類和接口之間才有交互。
13.父類的私有成員也被子類繼承,雖然不能以成員名直接訪問,但是可以間接的訪問。
教材學習中的問題和解決過程
- 問題1:對課本中Java中依賴接口提供多繼承的最好特性理解模糊
- 問題1解決方案:通過查閱資料了解到繼承多個接口的大致方法為:
package com.lib.ThinkInJava.mutilExtends;
public interface Lethal {
void kill();
}
package com.lib.ThinkInJava.mutilExtends;
public interface Monster {
void destroy();
}
package com.lib.ThinkInJava.mutilExtends;
public interface Vampire extends Monster, Lethal {
void drinkBlood();
}
Vampire接口繼承了Monster,Lethal倆個接口,而且使用了關鍵字extends,這就是java中的多繼承。
參考資料:
java中的多繼承
java接口多繼承
-
問題2:對影子變量的概念理解模糊
-
問題2解決方案:查閱資料了解到:
1.在一個類中,子類中的成員變量如果和父類中的成員變量同名,那么即使他們類型不一樣,只要名字一樣。父類中的成員變量都會被隱藏。在子類中,父類的成員變量不能被簡單的用引用來訪問。而是,必須從父類的引用獲得父類被隱藏的成員變量,一般來說,我們不推薦隱藏成員變量,因為這樣會使代碼變得難以閱讀。其實,簡單來說,就是子類不會去重寫覆蓋父類的成員變量,所以成員變量的訪問不能像方法一樣使用多態去訪問。2.同名的實例方法被覆蓋 ,同名的靜態方法被隱藏 ,child類的getName實例方法覆蓋 了parent的getName實例方法,chind的getKind方法隱藏 了parent類的getKind方法
3.隱藏 和覆蓋 的區別在於,子類對象轉換成父類對象后,能夠訪問父類被隱藏 的變量和方法,而不能訪問父類被覆蓋 的方法
4.如果需要訪問父類被隱藏 的實例變量,加上super就好了,比如訪問父類的name,寫上super.name就好了
參考資料:
JAVA中方法和變量在繼承中的覆蓋和隱藏
-
問題3: 對課本上的抽象類概念理解模糊
-
問題3解決方案:通過查閱資料了解到該知識點與下一章的多態方面的知識聯系密切。
抽象類就是為了繼承而存在的,如果你定義了一個抽象類,卻不去繼承它,那么等於白白創建了這個抽象類,因為你不能用它來做任何事情。對於一個父類,如果它的某個方法在父類中實現出來沒有任何意義,必須根據子類的實際需求來進行不同的實現,那么就可以將這個方法聲明為abstract方法,此時這個類也就成為abstract類了。
抽象類和普通類的主要有三點區別:1)抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承,子類便無法實現該方法),缺省情況下默認為public。
2)抽象類不能用來創建對象;
3)如果一個類繼承於一個抽象類,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義為為abstract類。
參考資料:
深入理解Java的接口和抽象類
Java中的抽象類
代碼調試中的問題和解決過程
- 問題1:在做pp9.1項目時想直接引用父類Coin中的private變量face時失敗,截圖如下:
- 問題1解決方案:方法1:將變量修改為protected型變量,更好的理解了protected可見性提供了允許繼承的最大可能的封裝性。截圖如下:
方法2:間接引用Coin類中的private變量face(不需要將private改為protected),方法是在Coin類中定義獲得face的getFace()
方法 ,改過后的Coin類截圖如下:
- 問題2:編寫pp9.1項目時沒有正確理解題意,我理解的是MonetaryCoin類的構造函數中直接使用Coin類中的構造函數執行拋硬幣操作,如果是正面,面值就是1,反面就是0,而且要在MonetaryCoin類中定義一個方法獲得面值。后來在與同學們交流的過程中意識到題意是這樣的:我們可以通過MonetaryCoin類創建不同面值的對象,並且可以對這些對象使用Coin類中的
flip()
方法。
修改之前的MonetaryCoin類的截圖如下:
修改之前的測試代碼截圖如下:
修改之后的MonetaryCoin類的截圖如下:
修改之后的測試代碼截圖如下:
-
問題3:在實例化pp9.1項目中MonetaryCoin類時出現意料之外的錯誤,截圖如下:
-
問題3解決方案:仔細檢查之后發現開頭少了
public static void main(String[] args) {
,改過后的截圖如下:
代碼托管
上周考試錯題總結
-
錯題1
理解:在Java中,數組被實現為對象。 -
錯題2
理解:如果一個int數組作為參數傳遞給方法,int[] a
可為方法頭定義參數列表 -
錯題3
理解:語句保留了1000個引用變量的內存空間。注意,1000個BankAccount對象都沒有實例化。 -
錯題4
錯因:不熟悉數組的定義方法的細節 -
關於數組的一些知識:
int []a,b;
是聲明了a和b兩個整數型數組;int a,b[];
是聲明了一個整數型變量a和一個整數型數組b;int []a;
和int a[]
是等價的,都是聲明一個整型數組a。
int[]a =new int[10]
這條語句是對整數型數組a進行了實例化;給數組中每個索引處賦值叫做對數組進行初始化。 -
錯題5
理解: 直接將數組a變為數組b,也就是直接創造了一個新的數組,而不是復制。 -
錯題6
理解:C項的意思為:初始化列表有4個int值,初始化意味着賦值。 -
錯題7
理解:在java命令之后,在命令行輸入的任何內容都將被接受為命令行參數。Java主方法使用參數(String[]變量),以便用戶可以運行程序並提供“命令行”參數。由於參數是一個字符串數組,因此用戶不必提供任何參數。 -
錯題8
理解:只要只訪問ArrayList的元素,它的效率與數組的效率差不多。只有當一個人開始在ArrayList的前部分插入或移除元素時,它的效率才會惡化。ArrayList是作為數組實現的,只要其中一個只是訪問ArrayList的元素,效率與數組的效率是一樣的。但是,當對ArrayList的前部分進行插入或刪除時,就會發生大量的元素復制,從而降低其效率。
結對及互評
點評過的同學博客和代碼
- 本周結對學習情況
-
結對學習內容
這周依舊沒有一起討論什么問題......可能是時機未到吧!
- 上周博客互評情況
感悟
繼續堅持堅持堅持吧!
學習進度條
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一周 | 28/28 | 1/1 | 16/16 | |
第二周 | 710/738 | 1/2 | 20/36 | |
第三周 | 426/1164 | 1/3 | 16/52 | |
第四周 | 1068/2232 | 2/5 | 20/72 | |
第五周 | 604/2928 | 1/6 | 22/94 | |
第六周 | 609/3537 | 1/7 | 22/116 | |
第七周 | 599/4136 | 1/8 | 18/134 |
-
計划學習時間:20小時
-
實際學習時間:18小時
-
改進情況:堅持到底!