Java基礎快速鞏固
目錄
9.覆寫(Override)與多態(polymorphic)
1.Java來源 介紹
Java版本
- Java SE:Java Standard Edition
- Java EE:Java Enterprise Edition
- Java ME:Java Micro Edition (使用較少)
關係圖如下:JavaEE是大哥
Java規範(確保Java跨平臺特性)
- JSR規範:Java Specification Request
- JCP組織:Java Community Process
Java框架佈局
2.Java變量類型(基本類型&引用類型)
基本類型:整型、浮點型、布爾型、字符型(Java使用unicode表示字符)
字符操作如下圖:
引用類型:包裝類(Integer、Double等)、String(注意String=""和String=null的區別)、自定義類型等
String操作如下圖:
注:
- 變量可重新賦值,等號是賦值符號,不是數學意義的符號
- 常量在初始化後不能再被賦值
- 使用常量方便來理解程序意圖
- 引用類型在使用的過程中要特別注意 (常常是比較隱含的問題)
整型
- byte:8位,1字節
- short:16位,2字節
- int:32位,4字節
- long:64位,8字節
整型的詳細信息見下圖:
基本類型運算注意事項
- 計算結果溢出不報錯——解決方案:使用更大的基本類型
- 計算結果不正確不報錯
實例如下圖:
總結
- 區分字符類型(基本類型)和字符串類型(引用類型)
- 基本類型的變量是“持有”某個數值
- 引用類型的變量是“指向”某個對象
- 引用類型的變量可以是null
- 區分空(null)和空字符串("")
3.位運算與邏輯運算
位運算 (注意有符號|無符號問題)
無符號右移>>,有符號右移>>> (有符號位移要保留符號位)
&、| 運算
異或運算
總結
- &&運算和||運算是短路運算,即第一個條件符合要求第二個條件不執行
- 布爾類型計算結果仍是布爾類型
- 三元運算符b?x:y 後面的類型必須相同
4.強制類型轉換(基本類型)
向下轉型
- 不需要強轉,Java會自動轉型提升
向上轉型
- 在運算過程中,計算結果爲較大型的類型需要強制轉換
- 可以強轉類型:變量、數值
- 強轉可能丟失精度
注:自動或強制類型轉換主要看是否會造成失真,if會就要強制;else就自動類型轉換
整數強制轉換注意事項
- 整型可以自動提升爲浮點型
- 浮點數強轉爲整型會直接丟掉小數位——>如果浮點數特別大,強制轉型會得到int的最大值
- 四捨五入的技巧(如下圖) +0.5再強轉int
浮點數強轉換注意事項(詳見下圖)
- 很多浮點數無法精確表示
- 計算有誤差
- 注意類型不自動提升的情況
總結
- 整數運算永遠精確
- 浮點數運算無法精確表示,運算結果可能失真
- 運算結果會自動提升
- 可以強制轉型,但可能丟失精度
- 選擇合適範圍的類型(int、long、double等)
5.數組
直接總結
- 數組是同一數據類型的集合
- 數組是引用類型
- 數組元素是值類型或引用類型
- 數組一旦創建大小不可變
- 可以通過索引訪問數組元素
- 索引超出範圍就報錯
6.面向對象
面向對象概述
面向對象編程:Object-Oriented Programming
對現實世界建立計算機模型的一種編程方法
class&instance
- class定義如何創建實例,class名字就是數據類型
- instance是根據class創建的對象實例, 可以創建多個instance,各個instance類型相同,但各自屬性可能不同
方法
- 方法可以讓外部代碼安全的訪問實例字段
- 方法是一組執行語句
- 方法內部遇到return時返回
- void表示不返回類型,注意和返回null的區別
- 外部代碼通過public方法操作實例
- 內部代碼可以調用private方法
重載方法
- 重載方法應該完成相同的功能,參考Java中String中的indexOf()方法
- 重載方法主要依靠參數類型和數量區分
- 不要去交換參數順序
- 重載方法返回值類型應該相同
super
- super關鍵字表示父類(超類)
- 構造方法的第一行語句必須調用super(),若沒有super()編譯器會自動生成super()
- 如果父類沒有默認構造方法,子類必須顯示調用super()
詳情見下圖:
7.可塑性(自定義類型)
向上可塑性(向上轉型)
向下可塑性(向下轉型)
- 可以對實例變量進行向下轉型(downcasting)
- 向下轉型把抽象的類型變成一個具體的類型
- 向下轉型很可能報錯:ClassCastException
- instanceof操作符可以判斷對象的類型
- 向下轉型前可以用instanceof判斷,避免異常。如下圖:
8.繼承和組合
- 繼承是is關係
- 組合是has關係
如下圖: Student不宜從Book繼承,Student可以持有一個Book實例——低耦合
總結
- 繼承是面向對象編程的一種代碼複用方式
- Java只允許單繼承
- protected允許子類訪問父類的字段和方法
- 子類的構造方法可以通過super()調用父類的構造方法
- 可以安全的向上轉型爲更加抽象的類型
- 可以強制向下轉型,最好藉助instanceof判斷,避免報錯
- 子類和父類的關係是is,has關係不能用繼承
9.覆寫(Override)與多態(polymorphic)
Override
- 子類覆寫父類的方法是覆寫
- 方法簽名如果不同就不是Override,而是創建一個新方法
- 加上@Override可以讓編譯器幫助檢查是否進行了正確的覆寫
- @Overrdie不是必須的
- 引用變量的聲明類型可能與其實際類型不符
- 實例對象的方法調用總是對應實際類型
- Java的實際方法調用是基於運行時實際類型的動態調用,詳情如下圖:
Object中的方法覆寫
- toString:把instance輸出爲String
- equals :判斷兩個instance是否邏輯相同
- hashCode:計算一個instance的哈希值
Super方法調用覆寫
- Super方法可以調用父類被覆寫的方法,如下圖:
final注意事項
- 用final修飾的方法不能被Override
- 用final修飾的類不能被繼承
- 用final修飾的字段在初始化後不能被修改
Polymorphic
- 多態是指針對某個類型的方法調用,其真正執行的方法取決於運行時實際類型的方法
- 對某個類型調用某個方法,執行的方法可能是某個子類的覆寫方法
- 利用多態,允許添加更多類型的子類實現功能擴展
總結
- 子類可以覆寫父類的方法(Override)
- 覆寫在子類中改變了父類方法的行爲
- 多態:Java的方法調用總是作用於對象的實際類型
- final修飾的方法可以阻止被覆寫
- final修飾的class可以阻止被繼承
- final修飾的field必須在創建對象時初始化
9.抽象類與接口
9.1 抽象
抽象方法&抽象類
如果一個class定義了方法,但沒有具體執行代碼,這個方法就是抽象方法:
- 抽象方法用abstract修飾
- 抽象方法沒有任何執行語句
- 因爲無法執行抽象方法,因此這個類也必須聲明爲抽象類(abstract class)
- 無法實例化一個抽象類
問:無法實例化一個抽象類有什麼用?
- 抽象類用於被繼承
- 抽象類強迫子類實現其定義的抽象方法(否則編譯錯誤)
- 抽象方法實際上相當於定義了“規範”
問:面向抽象編程的本質?
- 上層代碼只定義規範(abstract class)
- 不需要子類就可以實現業務邏輯(正常編譯)
- 具體的業務邏輯由不同的子類實現,調用者不必關心
抽象總結
- 抽象方法定義了子類必須實現的接口規範
- 定義了抽象方法的類就是抽象類
- 從抽象類繼承的子類必須實現抽象方法
- 如果不實現抽象方法,則該子類仍是一個抽象類
9.2 接口(Interface)
Interface概述
如果一個抽象類沒有字段,所有方法全部是抽象方法,就可以把該抽象類改寫爲接口:
- 使用interface聲明一個接口
- 接口定義的方法默認是public abstract(不需要寫)
- 一個interface可以繼承另一個interface,使用extends;相當於擴展了接口的方法
術語區分:
- Java的接口特指interface定義的接口,只定義方法簽名
- 編程接口泛指接口規範,如方法簽名、數據格式、網絡協議等
抽象類與接口比較
接口中定義default方法如下:
繼承設計
- 合理設計interface和abstract class的繼承關係
- 公共邏輯放在abstract class
- 接口層次代表抽象程度
如Java中的容器繼承結構如下:
接口總結
- 接口定義了純抽象規範
- 類可以實現多個接口
- 接口也是數據類型,使用於向上轉型和向下轉型
- 接口不能定義實例字段
- 接口可以定義default方法(JDK>=1.8)
10.靜態
靜態字段
- 所有實例共享一個靜態字段
- 不推薦用實例變量訪問靜態字段
- 推薦用類名訪問靜態字段
- 可以把靜態字段理解爲描述class本身的字段(非實例字段)
相關代碼如下:
靜態方法
- 靜態方法不能訪問this變量
- 靜態方法不能訪問實例字段
- 靜態方法可以訪問靜態字段
- 靜態方法經常用於工具類,如:
- Arrays.sort( )
- Math.random( )
- 靜態方法經常用於輔助方法
- Java程序的入口main()也是靜態方法
總結
- 靜態字段屬於所有實例“共享”的字段,實際上是屬於class的字段
- 調用靜態方法不需要實例,因此無法訪問this
- 靜態方法可以訪問靜態字段和靜態方法
- 靜態方法常用工具類和輔助方法
11.訪問權限
概述
- Java的類、接口、字段和方法都可以設置訪問權限
- 訪問權限是指在一個類的內部,能否引用另一個類以及訪問它的字段和方法
- 訪問勸降有public、protected、private、packeage四種
package
- JVM只看完整類名,只要包名不同類就不同,包可以是多層結構,沒有父子關係
- JVM加載class並執行代碼時,總是使用class的完整類名,編譯器編譯後的class文件中全部是完整類名
- 包作用域:位於同一個包的類,可以訪問沒有public、private修飾的class;可以訪問沒有public、protected、private修飾的的字段和方法。如下圖:
- 引用其他類的方法:使用完整類名;先import再使用類名;可以使用*(不推薦)
實踐注意事項
- 如果不確定是否需要public,就不聲明爲public,要儘可能少暴露對外方法
- 儘可能把局部變量的作用域縮小
- 儘可能延後聲明局部變量
final
- final與訪問權限不衝突
- 用final修飾class可以阻止被繼承
- 用final修飾method可以阻止被覆寫
- 用final修飾field可以阻止被重新賦值
- 用final修飾局部變量可以阻止被重新賦值
總結
- Java內建的訪問權限包括public、protected、private、package
- Java在方法內部定義的變量是局部變量
- 局部變量的作用域從變量聲明開始到一個塊結束
- final修飾符不是訪問權限
- 一個java文件只能包含一個public class,但可以包含多個非public class
11. 環境變量classpath
classpath概述
- classpath是一個環境變量
- classpath指示JVM如何搜索class
- classpath設置的搜索路徑與操作系統相關
classpath的設置方法
- 直接在系統環境中設置classpath環境變量(不推薦)
- 在啓動JVM時設置classpath變量(推薦) java -cp 設置環境變量 包名+類名 ,例如:java -cp C:\work com.sc.Hello
- 沒有設置環境變量,也沒有設置-cp參數,默認的classpath爲當前目錄
- 在Eclipse中運行的Java程序,Eclipse自動傳入的-cp參數是當前工程的bin目錄和引入的jar
12.jar包
jar包概述
- jar包是zip格式的壓縮文件,包含若干.class文件
- jar包相當於目錄
- classpath可以包含jar文件:c:\work\bin\all.jar
- 查找類會在相應的jar文件中搜索.class文件
jar包的創建方法
- 使用JDK自帶的jar命令,創建機制如下:
- JVM運行時會自動加載JDK自帶的class
- JDK自帶的class被打包在rt.jar
- 不需要在classpath中引用rt.jar
- 使用構建工具如Maven等
jar包的功能
- jar包可以包含一個特殊的/META-INF/MANIFEST.MF文件
- MANIFEST.MF是純文件,可以指定Main-Class和其他信息
- jar包可以包含其他jar包
jar包打包步驟如下
(1)創建java項目
(2)創建/META-INF/MANIFEST.MF文件 ——關於MANIFEST.MF文件的內容信息詳情請點擊查看
(3)在工程目錄下手動打包bin目錄下的所有文件
(4)DOS下運行
以上是Java的基礎知識彙總,持續關注還有進一步的java進階更新!點擊☞Java基礎工具類瞭解更多java基礎知識。
謝謝閱讀 ---知飛翀