1. 程式人生 > >Java是什麼及Java學習

Java是什麼及Java學習

希望可以幫到想學習Java語言的IT精英們

1.1 Java的歷史 8 1.2 Java平臺介紹 8 1.3 Java語言的特點 8 1.4 Java程式的執行機制 9 1.4.1 JVM與跨平臺 9 1.4.2 JVM、JRE、JDK 9 1.5 java開發環境安裝、配置 9 1.5.1 安裝JDK 9 1.5.2 配置環境變數 9 1.6 java開發流程 10 1.6.1 結構化程式設計與面向物件程式設計 10 1.6.2 編寫和執行Java程式的三個步驟 10 1.6.1 案例 10 1.7 常用命令 11 1.7.1 Dos命令 11 1.7.2 Java命令 11 第2單元 識別符號、關鍵字、資料型別 12 2.1 註釋 12 2.2 分隔符:; 空格 程式碼塊 12 2.3 識別符號 12 2.3.1 識別符號的概念 12 2.3.2 識別符號的語法要求 12 2.3.2 識別符號的命名規範 12 2.3.3 識別符號案例 13 2.4 Java的關鍵字 13 2.4.1 Java中的全部關鍵字 13 2.4.2 目前已經接觸到的關鍵字 13 2.5 基本資料型別 13 2.5.1 資料型別的分類 13 2.5.2 整型 14 2.5.3 浮點型 14 4.9e-324~1.8e+308 14 2.5.4 字元型 15 2.5.5 布林型 15 2.6 變數與常量 16 2.6.1 變數的宣告與賦值 16 2.6.2 常量的宣告與賦值 16 2.6.3 例項變數與區域性變數 16 2.6.4 變數案例 17 2.7 型別轉換 17 2.7.1 自動型別轉換 17 2.7.2 強制型別轉換 17 2.7.3 型別轉換案例 17 2.8 面向物件初步 18 2.8.1 瞭解類和物件 18 2.8.2 建立物件 18 2.9 原始型別和引用型別 18 第3單元 運算子&表示式&選擇結構 20 3.1 運算子 20 3.1.1 賦值運算子 20 3.1.2 算術運算子 20 3.1.3 關係運算符 21 3.1.4 邏輯運算子 21 3.1.5 位運算子 22 3.1.6 ?運算子 23 3.2 運算子的優先順序 23 3.3 流程控制-選擇結構 24 3.3.1 if-else 24 3.3.2 多分支語句switch 24 3.3.3 if-else與Switch的區別 25 第4單元 控制語句 26 4.1 while迴圈結構 26 4.2 do while迴圈結構 26 4.3 While和do while的區別 26 4.4 for迴圈結構 26 4.4.1 語法 26 4.4.2 巢狀的for迴圈 27 4.4.3 使用兩個變數控制迴圈 27 4.4.4 for迴圈例項 27 4.5 break和continue 28 第5單元 陣列 29 5.1 陣列的概念 29 5.2 陣列宣告 29 5.3 陣列建立與初始化 29 5.3.1 使用new建立陣列 29 5.3.2 建立陣列的三種方式 29 5.3.3 建立陣列需要注意的問題 29 5.3.4 動態初始化 30 5.4 陣列操作 30 5.5 陣列處理案例 30 5.6 陣列元素的型別 30 5.7 多維陣列 31 5.7.1 二維陣列的宣告、建立 31 5.7.2 單獨為第二維分配記憶體 31 5.7.3 為二維陣列使用初始化器 32 5.8 Arrays 32 第6單元 面向物件-類和物件 33 6.1 類與物件的概念 33 6.1.1 面向物件的概念 33 6.1.2 使用類和物件開發程式的基本步驟 33 6.1.3 類與物件 33 6.2 定義類 34 6.2.1 類的一般形式 34 6.2.2 類的屬性 34 6.2.2 類的方法 34 6.3 物件的宣告與建立 35 6.4 類練習 37 6.5 為引用變數變數賦值 37 6.6 構造器/構造方法 38 6.6.1 new運算子深入分析 38 6.6.2 構造方法的語法 38 6.7 this關鍵字 38 第7單元 面向物件-封裝 40 7.1 封裝的概念 40 7.2 訪問控制 40 7.2.1 包與訪問範圍 40 7.2.2 訪問修飾符與訪問範圍 41 7.3 方法深入分析 42 7.3.1 引數傳遞 42 7.3.2 return 42 7.3.3 方法呼叫 42 7.4 方法過載 42 7.4.1 方法過載基礎 42 7.4.2 過載構造方法 43 7.5 static關鍵字 43 7.5.1 靜態變數 43 7.5.2 靜態程式碼塊 44 7.5.3 靜態方法 44 7.5.4 關於static的幾點說明 45 第8單元 面向物件-繼承 46 8.1 繼承基礎 46 8.1.1 繼承的概念 46 8.1.2 繼承的語法 46 8.1.3 對繼承的說明 46 8.1.4 子類的構造方法 47 8.1.5 建立多級繼承層次 47 8.1.6 超類變數可以引用子類物件 47 8.1.7 物件的轉型 48 8.2 super關鍵字 48 8.2.1 使用super()呼叫父類的構造方法 48 8.2.2 使用super訪問父類中被子類隱藏的成員變數 49 8.4 object類 49 8.4.1 toString()方法 49 8.4.2 equals()方法與== 49 8.4 final 50 8.4.1 final修飾變數、方法、類 50 8.4.2 引用型別的常量 50 第9單元 面向物件—多型 50 9.1 多型的概念 50 9.2 方法重寫 50 9.2.1 方法重寫的規則 51 9.2.2 方法重寫與方法過載的區別 51 9.2 動態方法排程與執行時多型 51 9.2.1 動態方法排程 51 9.2.2 執行時多型 51 9.2.3 多型的兩種形式 52 9.3 多型例項 52 9.4 多型應用 52 9.4 抽象方法與抽象類 52 9.4.1 抽象方法 53 9.4.2 抽象類 53 第10單元 面向物件—介面 53 10.1 介面的概念與定義 53 10.2 介面中的屬性和方法 54 10.3 介面的實現 55 10.4 介面繼承 56 10.5 介面的例項 56 10.5.1 例項1 56 10.5.2 案例2 56 10.6 抽象類和介面的區別 57 第11單元 常用類 58 11.1 Object 58 11.1 Object類介紹 58 11.1 Object類的常用方法 58 11.2 String 58 11.2.1 String類介紹 58 11.2.2 String類的構造方法 59 11.2.3 字串比較 59 11.2.4 字串連線 60 11.2.5 字串查詢 60 11.2.6 字串修改 61 11.2.7 提取字元與子串 61 11.2.8 其他字串常用方法 62 11.3 StringBuffer和StringBuilder 62 11.3.1 StringBuffer與StringBuilder類介紹 62 11.3.2 StringBuffer類的構造方法 63 11.3.2 長度與容量的概念 63 11.3.3 StringBuffer類的常用方法 63 11.4 Math 65 11.4.1 Math介紹 65 11.4.2 Math類的常量 65 11.4.3 Math類的常用方法 65 11.5 Random 66 11.5.1 Random類介紹 66 11.5.2 常用方法 66 11.6 Date與Calendar 66 11.7.1 Date類 66 11.7.2 Calendar與GregorianCalendar類 67 11.7 包裝類 67 11.7.1 Character包裝器 68 11.7.2 Boolean包裝器 68 11.7.3 數值型別的包裝器類 68 11.7.1 自動裝箱與自動拆箱 69 11.7.2 數值與字串形式之間的轉換 69 11.7.3 字元分類 70 11.7.4 包裝器類中其他常用的常量和方法 70 第12單元 集合 70 12.1 集合概述 70 12.2 集合介面 71 12.2.1 Collection介面 71 12.2.2 List介面 72 12.2.3 Queue和Deque介面 73 12.2.4 Set介面 73 12.3 集合類 73 12.3.1 Arraylist類 74 12.3.2 LinkedList類 74 12.3.3 HashSet 74 12.3.4 LinkedHashSet類 75 12.3.4 TreeSet類 75 12.4 集合遍歷 75 12.4.1 Iterable介面 75 12.4.2 Iterator介面 76 12.4.3 ListIterator介面 76 12.4.1 使用迭代器 77 12.4.2 增強的for迴圈 77 12.5 Comparable和Comparator介面 77 12.5.1 Comparable介面 77 12.5.2 Comparator介面 78 12.6 Collections類與集合演算法 78 12.7 遺留的集合類和介面 78 12.7.1 Vector類 78 12.7.2 Hashtable類 79 第13單元 集合 79 13.1 支援對映的介面 79 13.2 對映類 79 13.2.1 HashMap 80 13.2.2 LinkedHashMap 80 13.2.3 TreeMap 80 13.3 對映的遍歷 81 第14單元 異常Exception 82 14.1 概念 82 14.2 異常處理基本流程 82 14.3 巢狀的try語句 84 14.4 異常型別 85 14.4.1 異常繼承體系 85 14.4.2 異常分類 85 14.4.3 常用異常 86 14.5 throw 87 14.6 throws 87 14.7 異常的傳播 87 14.8 自定義異常 88 第15單元 File-IO流 89 15.1 I/O的概念和java.io包 89 15.2 File類 89 15.2.1 建立File物件 89 15.2.2 File類的常用方法 89 15.3 流 90 15.3.1 流的分類 90 15.3.2 IO流結構圖 91 15.3.2 位元組流 91 15.3.3 字元流 93 15.4 快取流 94 15.4.1 快取的位元組流 94 15.4.2 快取的字元流 94 15.5 序列化與反序列化 95 15.5.1 Serializable介面 95 15.5.2 ObjectOutput和ObjectInput介面 95 15.5.3 ObjectInputStream和ObjectOutputStream類 95 第16單元 反射&執行緒&網路程式設計 96 16.1 反射 96 16.1.1 反射的概念 96 16.1.2 類載入與Class物件 96 16.1.3 獲取類的相關資訊 96 16.1.4 使用反射生成並操作物件 97 16.2 執行緒(Thread) 97 16.2.1 執行緒的概念 97 16.2.2 建立執行緒 97 16.2.3 執行緒同步與執行緒安全 98 16.2.4 執行緒的狀態 98 16.3 網路程式設計 99 16.3.1 IP地址與埠號 99 16.3.2 套接字 99

第1單元 Java入門 1.1 Java的誕生與發展歷史 Java的出生地:SUN Microsystems Inc. SUN:Stanford University Network Java之父:James Gosling(詹姆斯·高斯林) 1995年釋出Java第一版 Java發展歷史中的幾個重要版本:  Java 1.2 從該版本開始,把Java分成Java SE、Java ME、Java EE三部分。  Java 5 2004年9月30日18:00PM,J2SE 1.5釋出,成為Java語言發展史上的又一里程碑。為了表示該版本的重要性,J2SE 1.5更名為Java SE 5.0  Java 6 Java的各種版本更名,以取消其中的數字"2":J2EE更名為Java EE,J2SE更名為Java SE,J2ME更名為Java ME。 2009年04月20日,甲骨文74億美元收購Sun。取得java的版權。 1.2 Java技術體系

Java技術分為三個體系:  Java SE(J2SE)(Platform Standard Edition,java平臺標準版)開發桌面應用程式  Java EE(J2EE)(Java 2 Platform,Enterprise Edition,java平臺企業版)開發面向Internet的應用程式  Java ME(J2ME)(Java 2 Platform Micro Edition,java平臺微型版)開發運行於智慧裝置的程式。 1.3 Java語言的特點 面向物件(OOP) 跨平臺 安全健壯 沒有指標操作 垃圾自動回收機制 多執行緒 分散式 1.4 Java程式的執行機制
1.4.1 JVM與跨平臺 Java程式不是直接在作業系統之上執行,而是運行於JVM(java虛擬機器)之上。

針對不同的作業系統開發相應的JVM,Java程式運行於不同的JVM之上,因此Java程式可以在不同修改的情況下運行於不同的作業系統之上,從而實現了所謂的跨平臺。 Java原始碼(.java檔案)經編譯器編譯成位元組碼(.class檔案),JVM本質上就是一個負責解釋執行Java位元組碼的程式。 JVM執行Java程式的過程:  載入.class檔案  管理並分配記憶體  執行垃圾收集 1.4.2 JVM、JRE、JDK JVM:Java虛擬機器 JRE:Java執行時環境(JVM+類庫) //後面編寫程式碼時在強調類庫 JDK:Java開發工具包(JRE+編譯工具) JDK的全稱:Java Development kit 提示: 執行Java程式只需要安裝JRE,開發Java程式則需要安裝JDK。 1.5 java開發環境安裝、配置 1.5.1 安裝JDK

1.5.2 配置環境變數 1.5.2.1 PATH 目的:在任意路徑下能夠直接執行相關命令。 原理:在命令列中執行某個命令時,首先在當前路徑下查詢,如果找不到則到PATH配置的各個路徑下查詢。 配置細節: JAVA_HOME:C:\Program Files\Java\jdk1.6.0 PATH:%JAVA_HOME%\bin; 或 C:\Program Files\Java\jdk1.6.0\bin; //bin = binary(二進位制) 環境變數之間使用;分割

1.5.2.2 CLASSPATH (1)目的:在任意路徑下能夠找到要執行的.class檔案。 (2)CLASSPATH: .; C:\Program Files\Java\jdk1.6.0\lib\dt.jar; //lib = library(庫) C:\Program Files\Java\jdk1.6.0\lib\tools.jar; 從其他目錄下找class檔案 (3)注意:Java1.4之後不需要配置上述CLASSPATH環境變數,預設從上述路徑下查詢.class檔案。 1.6 java開發流程 1.6.1 結構化程式設計與面向物件程式設計 結構化程式設計:函式 面向物件程式設計:類 java類的基本結構:變數 + 方法 1.6.2 編寫和執行Java程式的三個步驟  編寫原始碼,儲存到原始碼檔案中,例如 HelloWorld.java  編譯原始碼,例如javac HelloWorld.java  執行位元組碼,例如java HelloWorld 案例1.1 HelloWorld 1.6.3 原始檔與class檔案 在Java中原始檔的名稱必須是檔案中主類的名稱,副檔名必須為.java。原始檔中可以包含多個類,但是最多隻能有一個類使用public修飾,使用public修飾的類就是主類。在Java中,原始檔還被作為編譯單元,即一個原始檔就是一個編譯單元。 編譯器會為原始碼中的每個類生成一個.class檔案,.class檔案的名稱是類的名稱,副檔名為.class。 1.6.4 main()方法 方法名:只能是main,不能是Main等形式。 修飾符:public static void 三個缺一不可,多一個不行 引數: 1、引數型別為字串陣列 2、引數名稱只要符合Java中識別符號命名要求即可 3、引數宣告的兩種方式:String[] args, 或 String args[] 案例1.2 列印輸出 1、列印:個人資訊 姓名:xxx 年齡:xx 性別:x

2、列印一首古詩

1.7 常用命令 1.7.1 Dos命令 命 令 功 能 碟符: 轉換到指定分割槽 cd 目錄 進入指定的目錄 dir 檢視當前路徑下的目錄和檔案 cd… 進入上一級目錄,…表示上一級目錄 cls 清屏 1.7.2 Java命令 javac //後跟檔名稱,需要包含副檔名.java javac -d //指明存放類檔案的位置 java //後跟類名 javadoc //生成註釋文件

第2單元 識別符號、關鍵字、資料型別 2.1 註釋 註釋的三種形式:單行註釋、多行註釋、文件註釋 文件註釋(documentation comment)以“/**”開始,以“*/”結束。使用文件註釋可以將關於程式的資訊嵌入到程式自身中。 javadoc命令可以文件註釋中的內容提取出來,將其放入到一個HTML檔案中。文件註釋方便了程式的文件化。

2.2 分隔符、程式碼塊 每行功能程式碼以;作為結束符號 空格沒有實際意義,可以利用空格無意義,將程式碼合理縮排,易讀 {}包含的程式碼稱之為程式碼塊, 例如類if(){}、方法{}、類{}等等

2.3 識別符號 2.3.1 識別符號的概念 Java中類、方法和變數的名稱,稱之為識別符號。 2.3.2 識別符號的語法要求 (1)以字母、數字、_或$組成 (2)不能以數字開頭 (3)不能使用java的關鍵字和保留字 注意: 1、識別符號的長度沒有限制 2、Java是大小寫敏感的,所有識別符號區分大小寫

2.3.2 識別符號的命名規範(駝峰) Java中的識別符號通常是由多個英文單詞構造,每個單詞除了首字母外其他字母小寫。 2.3.2.1 大駝峰 第一個單詞的首字母大寫。以大寫字母開頭,用於類名、介面名 class Accoun {…} //類名 class HelloWorld{…} //類名 interface AccountBase {…} //介面名 2.3.2.2 小駝峰 第一個單詞的首字母是小寫,其他單詞的首字母大寫。以小寫字母或單詞開頭,用於變數名、方法名 String studentName; //變數名 String getStudentName() {…} //方法名 2.3.2.3 常量命令規範 常量是使用final修飾的儲存單元。(最終的) 全部為大寫字母表示 final public int DAYS_WEEK = 7; final public double PI = 3.1415926; 2.3.3 識別符號案例 演示識別符號的要求、規範、常量的定義 abc a+b my_city KaTeX parse error: Expected 'EOF', got '&' at position 44: …e _come my&̲bb 2name p… $a 2.4 Java的關鍵字 2.4.1 Java中的全部關鍵字 目前定義了50個關鍵字 abstract continue for new switch assert default goto package synchronized boolean do if private this break double implements protected throw byte else import public throws case enum instanceof return transient catch extends int short try char final interface static void class finally long strictfp volatile const float native super while Java保留了const和goto關鍵字,但是沒有使用。Java還保留了下面這些關鍵字:true、false和null。這些關鍵字是Java定義的數值。 2.4.2 目前已經接觸到的關鍵字 public static void class 2.5 基本資料型別 2.5.1 資料型別的分類

注意:基本資料型別也可以分成兩大類:數值型、布林型 2.5.2 整型 Java不支援無符號的、只是正值的整數。 2.5.2.1 型別、寬度、範圍 名 稱 寬 度 範 圍 long 64/8 -9 223 372 036 854 775 808至9 223 372 036 854 775 807 int 32/4 -2 147 483 648至2 147 483 647 大約21億 short 16/2 -32 768至32 767 byte 8/1 -128至127 2.5.2.2 字面值 (1)整數字面值預設是int型別 (2)將字面值賦給byte或short變數時,如果字面值位於目標型別的範圍之內,就不產生錯誤。 (3)大寫或小寫的L明確地標識其型別為long (3)在字面值可以包含下劃線,例如1_000_000_000 (4)十進位制、八進位制(0)、十六進位制(0X/0x)、二進位制(0B/0b) 案例2.1 整型案例 2.5.3 浮點型 浮點數,也稱為實數(real number),當計算需要小數精度的表示式時使用。 2.5.3.1 型別、寬度、範圍 名稱 寬度(位) 大致範圍 double(雙精度) 64/8 4.9e-324~1.8e+308 float (單精度) 32/4 1.4e-045~3.4e+038

2.5.3.2 浮點數字面值 (1)預設為double型別,為了指定float字面值,需要使用字尾F或f (2)科學計數法。例如6.022E23、314159E-5、2e+100 案例2.2 浮點型案例 2.5.4 字元型 2.5.4.1 char型別與字元編碼 (1)char是16位,Java在內部使用16位的整數表示字元(Unicode編碼),char型別的範圍0~65536。//全世界基本的語言符號基本都包含了 (2)char也可以用作整數型別,可以將整型字面值賦給char型別的變數,可以在char型別上執行算術運算。 (3)26個小寫字母、26個大寫字母、以及10個數字0-9,其編碼是連續的。 2.5.4.2 char型別字面值 (1)字元型字面值使用單引號中的字元表示,例如’a’。 (2)轉義字元 轉義序列 描 述 \ddd 八進位制字元(ddd) \uxxxx 十六進位制Unicode字元(xxxx) \’ 單引號 \” 雙引號 \ 反斜槓 \r 回車符 \n 新行符(也稱為換行符) \f 換頁符 \t 製表符 \b 回格符 字串型別: 字串型別是String,String是類,所以是引用型別。字串字面值是使用雙引號包圍起來的內容。 案例2.3 字元型案例 2.5.5 布林型 (1)boolean型別表示邏輯值,它只能是true或false。 (2)boolean型別的值與整數0和1沒有任何關係 案例2.4 boolean型別

2.6 變數與常量 2.6.1 變數的宣告與賦值 說明:變量表示儲存單元,變數名就是儲存單元的名稱,變數初始化之後就可以通過變數名訪問儲存單元。 1、變數宣告 int i; String str; //還沒有分配儲存空間 2、初始化(賦初值) i=10; str=”abc”; //初始化之後就分配了儲存空間 3、宣告並賦值 int i = 10; String str=”abc”; //宣告的同時進行初始化 注意:變數在使用之前必須先初始化(賦初值)。 2.6.2 常量的宣告與賦值 宣告常量需要使用final關鍵字,如,final double PI = 3.1415926。 常量通常在宣告時賦值,並且賦值之後其值不能改變 常量識別符號通常全部為大寫。 案例 2.5 常量案例 2.6.3 例項變數與區域性變數 根據變數宣告的位置,變數可以分為例項變數和區域性變數。 2.6.3.1 例項變數及作用範圍 在類的{}內直接定義的變數,稱為例項變數或成員變數。 作用範圍:整個類中都可以使用 例項變數在建立物件時會自動初始化,並有初始值(預設值) byte/short/int:0 long:0L float:0.0f double:0.0 boolean:false 引用型別:null 2.6.3.2 區域性變數及作用範圍 在方法中或程式碼塊{}中定義的變數,稱之為區域性變數。 作用範圍:直接包含它的{}內有效 區域性變數不會自動初始化,沒有預設值,使用之前必須要初始化。 案例2.6 變數案例 2.7 型別轉換 當將一種型別的變數或字面值賦給另外一種型別的變數時,就會發生型別轉換。 Java中型別轉換分自動型別轉換和強制型別轉換。 總結:對於數值型別,如果目標型別的範圍包含了原型別的範圍,則可以自動轉換,否則就需要強制轉換。 2.7.1 自動型別轉換 型別相容、小型別轉換為大型別 byte–>int short—>int int—>long long—>float float—>double String—>Object (子類—>父類) 2.7.2 強制型別轉換 大型別轉換為小型別 int–>byte int—>short long—>int float—>long double—>float Object—>String 案例2.7 型別轉換案例 2.8 面向物件初步(瞭解) 2.8.1 瞭解類和物件

2.8.2 建立物件

2.9 原始型別和引用型別(瞭解) 原始型別變數的賦值 int x = 10; int y = x; (將x的值10賦給y, x和y沒有任何關聯關係,改變值互不影響)

引用型別變數的賦值 Teacher teacher = new Teacher(“John Smith”, 30, 10000); or Teacher teacher1, teacher2; teacher1= new Teacher(“John Smith”, 30, 10000); teacher2 = teacher1;

teacher2=teacher1; 將teacher1的引用的地址值賦給teacher2,這樣兩個引用指向同一個堆記憶體地址,所以任何一個修改屬性,另一個也變化。

第3單元 運算子&表示式&選擇結構 3.1 運算子 可以將大部分Java運算子劃分為四組:算術運算子、位運算子、關係運算符以及邏輯運算子。 3.1.1 賦值運算子 賦值運算子有一個有趣的特性:它允許建立賦值鏈。例如,分析下面的程式碼段: int x, y, z; x = y = z = 100; // set x, y, and z to 100 3.1.2 算術運算子 算術運算子用於數學表示式,其使用方法與在代數中的使用方法相同。 運算子 結 果

  • 加法(也是一元加號)
  • 減法(也是一元負號)
  • 乘法 / 除法 % 求模

+= 加並賦值 -= 減並賦值 *= 乘並賦值 /= 除並賦值 %= 求模並賦值

++ 自增 – 自減

需要注意的地方: (1)當將除法運算子用於整數型別時,其結果不會包含小數部分。 (2)求模運算子%,返回除法操作的餘數。它既可以用於浮點數也可以用於整數。可以用於判斷一個整數是否是奇數、偶數、是否是某個數的倍數。 案例3.1 基本算數運算子演示 名稱:BasicMathDemo 演示算術運算,特別注意是整除,演示除0效果

案例3.2 求模運算子案例1 專案名稱:ModulusDemo 演示求模運算子的運算規則和應用: 判斷一個數是奇數還是偶數 判斷一個數是否是5的倍數…

案例3.3 求模運算子案例2 名稱:GetDigital 輸入一個三位數,分別獲取個、十、百位上的數字。123

3.1.2.1 算術與賦值複合運算子 int a = 1; a += 2; //相當於a = a+2; (1)對於所有的二元算術運算,都有相應的複合賦值運算子。 (2)複合賦值運算子的效率更高。所以在專業的Java程式中,會經常看到複合賦值運算子。 案例3.4 複合運算子案例: 名稱:OpEqualsDemo 演示覆合運算子的規則。

3.1.2.2 自增與自減 (1)自增運算子將其運算元加1。自減運算子將其運算元減1。 (2)自增與自減分字首形式與字尾形式。++、– 字首形式: int i = 10; int a = ++ i; //等同於 i++; int a = i; 所以a=11, i= 11 字尾形式: int j = 10; int b = j++; //等同於 int b = j; j++; 所以b=10,j = 11 案例3.5 自增與自減運算子案例 名稱:IncDecDemo 重點演示字首與字尾形式的區別。

3.1.2.3 表示式 (1)表示式的概念:由運算元與運算子組成 j++; a+b; (2)表示式的求值:表示式是有值的,需要注意表示式值的型別 (3)表示式中的型別提升規則: 表示式的型別會自動提升為所有運算元的最大型別。 對於運算元全為非long型別整數的表示式,其型別會自動提升為int。 案例3.6 表示式求值案例 名稱:ExpressionDemo 演示型別自動提升

3.1.3 關係運算符 關係運算符也稱為比較運算子 運算子 結 果 == 等於 != 不等於

大於 < 小於 = 大於等於 <= 小於等於 (1)關係運算的結果為boolean型數值。 (2)關係運算符最常用於if語句和各種迴圈語句中的控制表示式。 案例3.7 關係運算符應用演示 CompareOperatorDemo 判斷一個字元是否是小寫字母、大寫字母、數字 3.1.4 邏輯運算子 布林邏輯運算子,只能操作boolean型運算元。 運算子 結 果 && 邏輯與(短路形式) || 邏輯或(短路形式) ^ 邏輯異或 ! 邏輯一元非 & 邏輯與 | 邏輯或 布林邏輯運算規則: 運算元 邏輯運算及結果 A B A || B A && B !A A ^ B false false false false true false true false true false false true false true true false true true true true true true false false 運算規則說明: 對於||,只要有一個運算元為true,則結果為true; 對於&&,只要有一個運算元為false,則結果為false。 對於^,兩個運算元不同,則結果為true,否則結果為false。

注意:&&和||, 這兩個運算子是所謂短路形式的邏輯運算子。假如單獨根據左運算元就能確定表示式的結果,那麼就不會計算右運算元的值。

案例3.8 邏輯運算案例 BoolLogicDemo 演示邏輯運算子的運算子規則

示例3.9 短路邏輯案例 演示短路邏輯表示式的求值過程 int a = 5; int b = 6; if(a < b || ++a == b) //通過第一部分就能確定最終結果的話,第二部分就不會執行 { System.out.println(a); } //分別使用 | 和 || 測試效果(輸出a的值)

3.1.5 位運算子(瞭解) 3.1.5.1 左移與右移 (1)左移<<:低位補0,左移動1位,相當於乘以2 (2)右移>>:高位補符號位,右移1位,相當於除以2 (3)無符號右移>>>:高位補0 3.1.5.2 位邏輯運算子 運算子 結 果 ~ 按位一元取反 & 按位與 | 按位或 ^ 按位異或 運算規則: 運算元 位運算及結果 A B A | B A & B A ^ B ~A 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0

注意: &和|,如果運算元為boolean型別,則為邏輯運算子,如果運算元為整數則為位運算子。通常將&和|作為位運算子。 3.1.5.3 位運算子與賦值運算子的結合 例如:a >>= 4; 相當於a = a >> 4; 示例3.10 位運算案例 演示<<、>>以及>>> 演示位邏輯運算 3.1.6 ?運算子 運算規則 expression1 ? expression2 : expression3 expression1可以是任何結果為boolean型數值的表示式。如果expression1為true,則對expression2進行求值;否則對expression3進行求值。“?”運算的結果是對其進行求值的表示式。expression2和expression3都需要返回相同(或相容)的型別,並且不能為void。 示例3.11 條件運算子示例 (1)使用?運算子解決除0問題 ratio = denom == 0 ? 0 : num / denom; //優美地解決了除0問題 (2)使用?運算子獲取絕對值 int i=-10; int k = i < 0 ? -i : i; //k為i的絕對值

3.2 運算子的優先順序 最高 ++(字尾) --(字尾) ++(字首) --(字首) ~ ! +(一元) -(一元) (型別匹配)

  • / %

<< = < <= instanceof == != & ^ | && || ?: = op= 最低 大概順序:算術運算子>移位運算子>關係運算符>邏輯運算子>賦值運算子 圓括號會提升其內部運算元的優先順序。為了得到所期望的結果,這通常是必需的。圓括號(不管是否冗餘)不會降低程式的效能。所以,為了減少模糊性而新增圓括號,不會對程式造成負面影響。 3.3 流程控制-選擇結構 選擇結構是通過分支語句實現的,分支語句有兩種。 3.3.1 if-else 1、if語句的三種形式

注意: else 不能單獨使用,要和if配對使用 if else 都可以後面不跟{},但是隻能控制下面的一行程式碼

if-else案例 (1)輸入兩個數,輸出較大的數(if-else) (2)使用Scanner獲取輸入成績分值,輸出對應的成績等級(if-else if-else) 3.3.2 多分支語句switch 3.3.2.1 switch語句的結構 switch (expression) { case value1: // statement sequence break; case value2: // statement sequence break; … case valueN : // statement sequence break; default: // default statement sequence }

3.3.2.2 switch語句需要注意的問題 (1)switch(expression)中expression的結果必須是byte,short,char,int中的一種。 新增:列舉型別、String (2)在同一個switch語句中,兩個case常量不允許具有相同的值 (3)每個case語句中需要加上break;語句。如果遺漏了break,則會繼續進入到下一個case。 (4)可以省略default語句。 (5)default語句通常放在末尾,可以放在開始,中間或者末尾位置。 3.3.2.3 switch案例 輸入1-7之間的數字表示一週的中的第幾天,輸出對應的星期幾。 3.3.3 if-else與Switch的區別 (1)switch語句只能進行相等性測試,這一點與if語句不同,if語句可以對任何型別的布林表示式進行求值。即,switch只查看錶達式的值是否和某個case常量相匹配。 (2)相對於一系列巢狀的if語句,switch語句通常效率更高。

第4單元 控制語句 選擇語句(分支語句)、迭代語句(迴圈語句)、跳轉語句 4.1 while迴圈結構 while(condition) { // body of loop } 一般在迴圈體內控制迴圈的結束條件:讓迴圈條件為false或break 4.2 do while迴圈結構 do { // body of loop } while (condition); 至少執行一次迴圈。 示例: 分別使用while和do-while迴圈計算1-100的和 //改進第3單元中判斷成績等級的例子,如果輸入的數值為負數,則退出程式 4.3 While和do while的區別 do while先執行 後判斷 所以它至少執行一次 while先判斷條件 再執行 有可能一次也不執行 所有的迴圈,都可能出現死迴圈 4.4 for迴圈結構 4.4.1 語法 for(initialization; condition; iteration) { // body } 四個部分:初始化部分A、迴圈條件B、迴圈體D、迭代部分C

A只執行一次。 執行B判斷真假,如果真T,執行D,然後再執行C變數變化 演示案例: 使用for迴圈計算1-100的和 4.4.2 巢狀的for迴圈 迴圈是可以巢狀的,包括while和do-while迴圈 4.4.3 使用兩個變數控制迴圈 案例:輸入兩個數,查詢兩個數的中間數 for(int i=0, j=10; i<j; i++,j–){ //輸出i和j的值 }

練習總結: 學生基本語法可以掌握,稍有邏輯不會,建議多做稍有邏輯練習題 例如: i%2==0 知道是2的整倍數的判斷 基本語法沒問題 判斷一個數字i 能否被2 到(i-1)任意一個整除,就不會了。

4.5 break和continue break:終止直接包含的迴圈體,結束(本層)迴圈 continue:終止本次迴圈,直接執行迴圈的下一次 案例: 列印1-20之間的偶數,如果大於10則終止迴圈(break) 列印1-20之間的偶數,如果等於10則終止本次迴圈(continue)

第5單元 陣列 5.1 陣列的概念 一個具有固定大小,可以容納相同型別資料的集合. 陣列元素的型別:可以是基本型別,也可以是引用型別 陣列可以認為是Java中最簡單的複合型別。 陣列的宣告和使用,在語法上與C語言類似,但是在內部實現機制上有本質的區別。 5.2 陣列宣告 兩種方式:強烈建議採用第一種方式 int[] nums; 或 int nums[]; 5.3 陣列建立與初始化 5.3.1 使用new建立陣列 int[] nums; //宣告陣列,並沒有建立陣列,沒有開闢堆記憶體。 nums = new int[5]; //建立陣列,必須設定長度 開闢堆記憶體 new:用於分配記憶體的特殊運算子。通過new分配的陣列,其元素會被自動初始化為0(對於數值型別)、false(對於boolean型別)或null(對於引用型別)。

說明:獲得一個數據需要兩個步驟,第一步是宣告,第二步是建立陣列物件。 一個數組就是一個物件。陣列是動態建立的,所有物件都是動態建立的。 5.3.2 建立陣列的三種方式 int[] nums = new int[5]; //初始化為預設值 int[] nums = {1,2,3,4,5}; //初始化為{}中指定的值,靜態初始化 int[] nums = new int[] {1,2,3,4,5};//初始化為{}中指定的值,靜態初始化 5.3.3 建立陣列需要注意的問題 1、建立陣列時必須知道陣列的長度,否則new不知道要開闢多大的記憶體 2、第二種方式建立陣列,必須在宣告陣列的同時建立陣列 3、建立陣列之後,陣列的長度不能再改變。 說明: 陣列的初始化分為靜態初始化和動態初始化,靜態初始化在初始化時由程式設計師顯示指定每個陣列元素的初始值,由系統決定陣列長度。 5.4 陣列操作 1、通過下標訪問陣列元素 為指定的陣列元素賦值、使用陣列元素。如果陣列下標越界,會丟擲異常。 2、通過迴圈處理陣列(列印輸出所有陣列元素) 陣列與迴圈是分不開的 3、可以使用length屬性獲取陣列的長度,從而可以避免陣列越界。

示例5.1 建立陣列、靜態初始化、遍歷輸出陣列元素

示例5.2 隨機數生成 使用Math類的random方法,動態初始化

5.5 陣列排序 5.5.1 排序(冒泡) 5.5.2 Arrays.sort()

5.6 陣列元素的型別 陣列元素的型別不僅可以為基本型別,也可以為引用型別。 演示案例: 字串陣列 定義一個Student類,定義一個Student類的陣列,使用初始化器建立陣列物件,通過迴圈對陣列進行處理。 5.7 多維陣列 5.7.1 二維陣列的宣告、建立 在Java中,多維陣列(multidimensional array)實際上是陣列的陣列。 下面聲明瞭一個名為twoD的二維陣列: 本質上,Java中只有一維陣列。 int[][] twoD = new int[4][5];

int[] 表示int型別的陣列,即陣列元素為int型別 int[][] 表示int[]型別的陣列,即陣列元素為int[]型別 5.7.2 單獨為第二維分配記憶體 當為多維陣列分配記憶體時,可以只為第一(最左邊的)維指定記憶體,之後再單獨為餘下的維分配記憶體。 int twoD[][] = new int[4][]; twoD[0] = new int[5]; twoD[1] = new int[5]; twoD[2] = new int[5]; twoD[3] = new int[5]; 對於這種情況,第一維的長度必須指定。 int twoD[] = new int[][]; //錯誤

第二維的長度可以不同: int twoD[][] = new int[4][]; twoD[0] = new int[1]; //twoD[0],本質是一維陣列 twoD[1] = new int[2]; twoD[2] = new int[3]; twoD[3] = new int[4];

5.7.3 為二維陣列使用初始化器 int[][] i= new int[3][]; int[] a1 ={1,2,3}; int[] a2 ={4,-5,6,9,0,8}; int[] a3 ={7,8};

下面這行程式碼 String[][] s=new String[10][]; A s 是一10行10列的陣列。 B s 是一包含10個一維陣列的二維陣列。 C s中每個元素都為null。 D 該行程式碼非法。

特別注意: 二維陣列,建立陣列是,[][] 第一個必須指明長度 宣告的有效方式: int[][ ] ia1 = new int[2][3]; int[][ ] ia2 = new int[2][]; ia2[0] = new int[2], ia2[1] = new int[3]; Teacher[][] ta; ta = new Teacher[2][]; ta[0] = new Teacher[3]; ta[1] = new Teacher[4];

無效的宣告方式 int[][ ] ia1 = new int[][3]; Teacher[][] ta = new Teacher[][5]; 5.8 Arrays 陣列操作的工具類 使用Arrays類對陣列進行排序,查詢元素 Arrays.sort(XXX);

第6單元 面向物件-類和物件 6.1 類與物件的概念 6.1.1 面向物件的概念 面向物件程式設計:OOP(Object-Oriented Programming) 6.1.2 使用類和物件開發程式的基本步驟 對於面向物件程式設計,主要工作就是編寫類。面向物件開發的步驟:  開發類,類 = 屬性(成員變數) + 方法  通過new關鍵字建立物件  使用類中的屬性和方法:物件.屬性名 物件.方法名() 6.1.3 類與物件 (1)類是一種邏輯結構,對具有公共屬性特徵和行為(功能)的一個群體進行描述。例如可以定義Student類描述學生的公共屬性和行為,定義一個Teacher類,描述老師的公共屬性和行為。 (2)定義了類之後,就可以根據類建立(new)出一個例項。比如學生張三,老師王老師。 通俗地說: 類定義了一種新的資料型別。物件就是根據類定義的變數。可以將類看做是複合型別。 類是物件的模板(template),物件是類的例項(instance)。因為物件是類的例項,所以經常會看到交換使用“物件”和“例項”這兩個詞。

教學需要注意的問題: 開始時不要講理論,提示一下後就直接編寫類,宣告並建立物件。然後結合具體的程式,介紹上面的概念。

6.2 定義類 程式 = 資料 + 演算法 類 = 屬性 + 方法 6.2.1 類的一般形式 class 類名 { //類名通常以大寫字母開始 型別 變數1; 型別 變數2; …

型別 方法名(引數列表) { // 方法體 } … }

在類中定義的變數和方法都稱為類的成員。所以變數又稱為成員變數,方法又稱為成員方法。 6.2.2 類的屬性 類的成員變數又稱為類的屬性。 public class Student { /**

  • 屬性 成員變數
  • 類的{}內直接宣告(定義)的變數 叫 成員變數/例項變數 */ String name; int age; double score; } 屬性屬於類的某個具體物件。類的每個例項(即,類的每個物件)都包含這些變數的副本,因此在類中定義的變數又被稱為例項變數。 6.2.2 類的方法 方法是物件行為特徵的抽象,類具有的共性的功能操作,稱之為方法。方法是個“黑匣子”,完成某個特定的應用程式功能。 方法的基本語法: 修飾符 返回型別 方法名(形參列表){ //功能程式碼 } 形參可以為空,可以有多個,形參的型別可以是基本型別也可以是引用型別。 public class Student { String name; int age; double score;

void study(){ // }

void show(){ // } } 注意: 方法中定義變數稱為區域性變數。 如果沒有返回值,則方法的返回型別必須為void 當方法有具體的返回型別時,則必須使用return語句返回一種值。

方法深入分析:

6.3 物件的宣告與建立 Student stu1; //宣告物件的引用 sut1 = new Student(); //建立物件

public static void main(String[] args) {

Student stu1 = new Student(); stu1.name = “張三”; //訪問物件的屬性 stu1.age = 20; stu1.score=95.5; stu1.show(); //方法呼叫

Student stu2 = new Student(); stu2.name = “李四”; //訪問物件的屬性 stu2.age = 22; stu2.score=98; stu2.show(); //方法呼叫

Student stu3 = stu2; sut2.show(); }

提示:如何使用物件的成員變數和方法

注意: 屬性屬於類的具體物件,不同物件的屬性值通常是不同的。 雖然方法也是通過物件呼叫的,但是各物件共享相同的方法。

教學需要注意的問題: 帶著學生多定義幾個簡單的類,讓學生自己也多定義幾個類。 逐步增加類的複雜程度

6.4 類練習 Teacher類 定義Teacher,屬性:姓名,年齡,工資 方法:Teach(); Show(); Box類 屬性:長、寬、高 方法:計算體積 Dog類: 屬性:name color、age 方法:eat() Cat類: 屬性:name color、age 方法:eat() Triangle類:底、高、計算面積 Reatangle類:長length、寬width,計算面積area Circle類:半徑,計算面積 測試類:Engineer類 6.5 為引用變數變數賦值 //Box b1 = new Box(); //建立物件,讓b1指向(引用)所建立的物件 Box b2 = b1;

注意:b1和b2引用同一個物件。 物件引用與物件的關係: (1)物件引用,有時也稱為物件引用變數,或稱為引用變數。 (2)物件引用與物件在物理上是兩個不同的東西。 (3)對於上圖,我們通常說b1引用(有時也稱為指向)圖中的那個Box物件。 (4)物件只能通過物件引用來操作。有時直接使用物件引用代指物件,例如對於上面的例子,有時會直接將b1引用的物件稱為“物件b1”或“”b1物件。 (5)將一個物件引用賦值給另一個物件引用,則兩個引用變數指向同一個物件。 (6)對引用變數進行相等性比較,例如b1b2,是比較兩個引用變數是否引用同一個物件,所以b1b2的結果為true。對物件引用進行相等性比較,有時也直接稱為物件的相等性比較。 注意:基本變數與引用變數的區別 基本型別的變數位於棧記憶體中,引用變數所所引用的變數位於堆記憶體中。 7.3 方法深入分析 方法可以看做是獨立的功能模組,供呼叫模組呼叫,功能模組要有輸入、輸出,對於方法而言輸入就是方法的引數,輸出就是方法的返回值。呼叫者通過引數將需要輸入的資料傳遞給方法,方法通過返回值將輸出返回給呼叫者。 7.3.1 方法定義 1、方法定義包括:訪問修飾符、返回型別、方法名、形參 2、方法必須有返回型別(構造方法除外),可以省略訪問修飾符 3、可以有引數,也可以沒有引數 7.3.1 方法呼叫 1、實參與形參的概念 2、方法呼叫的執行過程 7.3.2 引數傳遞 方法呼叫中發生的資料傳送是單向的。即只能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參。因此在函式呼叫過程中,形參的值發生改變,而實參中的值不會變化。 引數傳遞: 值傳遞:Swap(int a, int b)方法 引用傳遞(物件作為引數,本質上是引用變數作為引數) 7.3.3 return (1)return語句用於明確地從一個方法返回。即,return語句導致程式的執行控制轉移回到方法的呼叫者。 (2)如果return之後還有程式碼也不會執行。 (3)如果方法的返回型別為void,可以使用return跳出函式,但是不能使用return返回資料。 (4)可以返回物件。 7.3.4 方法呼叫 因為封裝,不能直接訪問其他物件的成員變數,通常是呼叫其他物件的方法。方法呼叫有兩種情況: 呼叫相同類中的方法:可以直接呼叫。(本質上是使用this關鍵字呼叫) 呼叫其他類中的方法:物件.方法名 6.6 構造器/構造方法 6.6.1 構造方法的語法 構造方法的作用:開闢記憶體空間、建立例項、初始化屬性值。 構造方法的特點: (1)方法名與類名相同 (2)不能宣告返回型別 (3)不能使用return語句 (4)通常為public 注意: (1)如果沒有明確提供構造方法,則系統會提供一個預設的構造方法,預設構造方法(也稱為預設構造方法)沒有引數。 (2)如果我們提供了一個構造方法,則系統不再提供無引數的預設構造方法。 (3)如果我們提供了一個有引數的構造方法,同時又需要無參構造方法的話,則必須同時提供一個無引數的構造方法。 6.6.2 new運算子深入分析 new運算子實際是就是呼叫構造方法。當進入到構造方法內部時,實際上物件已經建立完畢,可以在構造方法中為各成員變數賦值。

6.7 this關鍵字 在類的內部,可以在任何方法中使用this引用當前物件。 使用this關鍵字解決在例項變數和區域性變數之間可能發生的任何名稱衝突。 區域性變數,包括方法的形參,可以和類的例項變數重名。當局部變數和例項變數具有相同的名稱時,區域性變數隱藏了例項變數。

第7單元 面向物件-封裝 7.1 封裝的概念 封裝是面向物件的三大特徵之一。 面向物件的三大特徵是:封裝、繼承、多型。 類 = 屬性 + 方法,類是對屬性和方法的封裝。類封裝了類的成員。 結合Student類,介紹後續內容: 如果在類的外部可以隨意訪問類的成員,那將屬性和方法放到類中就沒有意義了。因此Java允許在類中通過訪問修飾符控制類成員的訪問許可權。之前已經接觸過public訪問修飾符。

7.2 訪問控制 在完整學習訪問控制之前,先熟悉一下包的概念。 7.2.1 包與訪問範圍 (1)包的概念 類通常位於某個包中,包(packages)是多個類的容器。它們用於保持類的名稱空間相互隔離。因此包是一種名稱機制。 例如,Java類庫中的類,分別包含在不同的包中:java.lang;java.util。例如String類位於java.util包中。 (2)定義包 package pack1 (3)層次化的包 package www.bawie.java1502c (4)包與目錄結構 位於包中的類,在檔案系統中也必須有與包名層次相同的目錄結構。 需要指出的是,包名與檔案目錄結構一致是針對.class檔案而言的,對於原始碼檔案沒有這一要求,但是通常也將原始碼檔案放到與包名一致的目錄結構中。並且建議將原始檔與類檔案分開存放。 (5)匯入包 類的全名為:包名.類名。例如在www.bawie包中定義的Student類,其全面為www.bawie.Student。 當在不同的包中使用某個類時,需要使用類的全名,如果包名很長的話,使用類的全名不是很方便,這時可以通過匯入包來避免使用類的全名。 匯入包的目的:減少輸入 匯入包的兩種方式 import java.util.Scanner; import java.util.*; 包既是一種命名機制,也是一種可見性控制機制。可以在包中定義該包外部的程式碼不能訪問的類成員。 7.2.2 訪問修飾符與訪問範圍 類是對類成員(屬性和方法)的封裝,可以通過不同的訪問修飾符控制類成員的可見範圍,即控制類的成員在多大的範圍是可見的。

類成員的訪問範圍劃分為四個:本類、本包、子類、全域性(所有包) 為類的成員指定不同的修飾符,就是控制成員的在什麼樣的範圍內是可見的,即在什麼樣的範圍是能夠訪問的。 private 預設 protected public 同一個類中 是 是 是 是 相同包中的其他類 否 是 是 是 子類(不同包、相同包) 否 否 是 是 全域性(所有包) 否 否 否 是 訪問範圍: 本類 < 本包 < 子類 全域性(所有包) 訪問修飾符:private < 預設(default) < protected < public 封裝的通常做法: (1)將類的屬性的訪問許可權設定為private,提供訪問許可權為public的set和get方法。在有些情況下不提供set和get方法,有時只提供其中的一個。 (2)提供合理的構造方法,即開發相應引數的構造方法,方便例項化物件。 (3)類的全部或部分方法的訪問許可權為public,類的公有方法是類對外開放的介面,供外部程式碼使用類的功能。類的私有方法通常是輔助方法實現部分功能,供類的公有方法呼叫。

封裝案例: 在p1包中定義Student類 在p1包中定義StudentTest類,使用Student類,訪問該類中的成員變數和方法。 將StudentTest類的定義放入到p2包中,再次訪問類中的成員變數和方法。 封裝案例:堆疊類 讓學生體會封裝的原理。 7.4 方法過載 7.4.1 方法過載基礎 直接切入主題: 在類中可以定義名稱相同的方法:只要形參列表不同即可。 特點: 1、方法名相同 2、形參列表不同:形參的型別、形參的個數 注意的地方: 1、返回值在區分過載方法時不起作用。修飾符也不起作用 2、當呼叫過載方法時,Java使用引數的型別和/或數量確定實際呼叫哪個版本。 方法過載案例: Calculator類,新增add()方法,計算兩個數的和。int float double 7.4.2 過載構造方法 Box(double length, double width, double height) Box(double dim) Box(Box box) Box() 特別說明: 在某個構造方法中可以使用this()呼叫過載的構造方法: public Box(double dim){ this(dim, dim, dim) } 7.5 static關鍵字 在正常情況下,只有通過組合類的物件才能訪問該類的成員。有時可能希望定義能夠獨立於類的所有物件進行使用的成員。為了建立這種成員,需要在成員宣告的前面使用關鍵字static。例如Math類中的方法,就是靜態方法。 方法和變數都可以宣告為靜態的。main()方法是最常見的靜態成員的例子。main()方法被宣告為靜態的,因為需要在建立所有物件之前呼叫該方法。 7.5.1 靜態變數 案例:(演示靜態變數的訪問方式、不同例項共享相同的值) Math中的成員變數PI就是靜態變數。 public class StaticM{ //例項變數 private int i;

//靜態變數 static int si;

public static showStatic(){}; } 特別注意: (1)被宣告為靜態的變數本質上是全域性變數,類的所有例項共享相同的靜態變數。因此,通過一個物件修改靜態變數的值後,通過該類的其他物件訪問到的靜態變數是修改後的值。 (2)訪問靜態變數的方式: 類名.變數名(推薦) 物件.變數名(不推薦) (3)初始化時機 靜態變數:當類被虛擬機器載入,靜態變數就初始化,既不需要建立類的物件就可以使用靜態變數。 例項變數:建立類的物件時初始化 7.5.2 靜態程式碼塊 靜態程式碼塊,只執行一次,而且是類載入時就執行 作用:一般完成靜態變數初始化賦值或完成整個系統只執行一次的任務 7.5.3 靜態方法 最典型的靜態方法是main()方法; 靜態的方法有幾個限制:  它們只能直接呼叫其他靜態方法。  它們只能直接訪問靜態資料  它們不能以任何方式引用this或super關鍵字。(super是與繼承相關的關鍵字,將在下一章介紹。) 案例: 改寫前面的Calculator類,使用靜態方法實現兩個數量相加的功能。 main方法、math類中提供的許多方法都是靜態方法 7.5.4 關於static的幾點說明 1、static的本質作用是區分成員屬於類還是屬於例項。 2、通常把使用static修飾的變數和方法稱為類變數和類方法,有時也稱為靜態變數和靜態方法,把不使用static修飾的變數和方法稱為例項變數和例項方法。 3、對於使用static修飾的成員,既可以通過類來呼叫也可以通過類的例項呼叫,但是建議使用類呼叫靜態成員。對於例項變數和例項方法,則只能通過類的例項呼叫。

第8單元 面向物件-繼承 8.1 繼承基礎 繼承是面向物件的基本特徵之一。 8.1.1 繼承的概念 使用繼承可以為一系列相關物件定義共同特徵的一般類,然後其他類(更特殊的類)可以繼承這個一般類,每個進行繼承的類都可以新增其特有的內容。 被繼承的類稱為超類(super class)/父類,繼承的類稱為派生類/子類(subclass)。 一旦建立了一個定義一系列物件共同特徵的超類,就可以使用該超類建立任意數量的更特殊的子類。 8.1.2 繼承的語法 繼承使用關鍵字extends(擴充套件)實現。 public class A extends SuperA{ } 子類可以從父類繼承屬性和部分方法,自己再增加新的屬性和方法。通過繼承可以重用父類的方法和屬性,減少程式碼重複編寫,便於維護、程式碼擴充套件。 繼承案例: 案例1 父類:Person:name age sex sleep() 子類:Student:grade score study() 子類:Teacher:college course teach() 案例2: 父類:Animal:name color age eat(); “動物吃東西!” 子類:Dog:layal watch(); “忠誠地看家護院” 子類:Cat:wakan CatchMouse(); “聰明地捉老鼠” 案例3: 父類:Box:length width height volume() 子類:WeightBox:weight 子類:ColorBox:color 8.1.3 對繼承的說明 (1)子類不能從父類繼承的資源:私有方法、構造方法、如果子類與父類在不同包中,子類不能繼承父類中那些具有預設訪問許可權的方法。即不能繼承那些不能訪問的方法。在子類中不能訪問到的那些方法,無法繼承的。 理論上子類會繼承父類的全部成員變數,但是子類不能訪問父類的私有成員變數,如果子類與父類在不同包中,子類也不能訪問父類中具有預設訪問許可權的成員變數。 (2)java類繼承只允許單繼承(只能有一個超類);java中介面允許多繼承。 (3)子類中可以定義與父類中同名的成員變數,這時子類的成員變數會隱藏/覆蓋父類中的同名成員變數。 (4)子類中也可以定義與父類中同名的成員方法,這時子類中的方法重寫了父類中的同名方法。 8.1.4 子類的構造方法 (1)構造方法的呼叫順序 在類繼承層次中按照繼承的順序從超類到子類呼叫建構函式。 (2)在子類的構造方法中,一定會首先呼叫父類的構造方法。super(); (3)子類的每個構造方法都會隱式的呼叫父類的無引數構造方法,如果想呼叫父類的其他構造方法,必須使用super(引數列表)來顯式呼叫。 說明:編寫類時,通常需要提供無引數構造方法。 (4)如果父類沒有無參的構造方法,或者想呼叫父類的有參構造方法,則在子類的構造方法中必須顯式使用super(xxx)呼叫父類有參構造方法。這時super(xxx)必須是子類中的第一條語句。 (5)通常的做法: 在父類中定義有引數的構造方法,負責初始化父類的成員變數。 在子類的構造方法中,先呼叫父類的構造方法完成從父類繼承來的那些成員變數,然後初始化子類中特有的成員變數。 注意: 如果父類中定義了一個有引數的構造方法,系統就不會再為父類提供預設的構造方法。這時,在子類的構造方法中,必須使用super(xxx)顯示呼叫父類的有參構造方法。 8.1.5 建立多級繼承層次 public GrandFather( ){ } public Father( ) extends GrandFather{ } public Son( ) extends Father{ } 案例:BawieStudent繼承自Student類

8.1.6 方法重寫介紹 當子類從父類中繼承來的方法不能滿足需要時,子類可以重寫該方法,重寫方法要求方法名與引數列表都相同。 案例: 重寫Student、Teacher類中的sleep()、show() 重寫Dog、Cat類中的eat()、show() 重寫WeightBox、ColorBox類中的Show() 8.1.6 超類引用變數可以引用子類物件 SuperA sa; //宣告超類的變數 A a = new A(); //建立子類物件 sa = a; //將子類物件賦給引用物件 sa = new A(); //建立一個新的子類物件,賦給超類引用變數 可以將子類的物件賦給父類的引用變數,但是這時使用父類的引用變數只能訪問父類中定義的那些成員變數。換句話說,可以訪問哪些成員是由引用變數的型別決定的,而不是由所引用的物件型別決定的。 動態方法排程介紹: 案例演示:

8.1.7 物件的轉型 Animal a = new Dog(); //小轉大 可以自動進行 a.layal; //語法錯誤,這時通過a只能使用父類中定義的成員變數。編譯時就確定 a.eat(); //

Animal a = new Dog(); d = (Dog)a; //正確 大轉小, 需要強制轉換

Dog d = new Animal(); //錯誤 Dog d = (Dog)new Animal(); //語法沒錯,可以編譯,但執行時會丟擲異常

Cat c = new Cat(); d = (Dog)c; //不正確

子類物件 賦給 父類引用 可以,自動轉換 父類引用 賦給 子類引用 需要強轉 ,前提:父類引用確實指向了正確的子類物件

8.2 super關鍵字 關鍵字super用於呼叫/訪問從父類中繼承來的例項變數和方法。 super有兩種一般用法。第一種用於呼叫超類的構造方法。第二種用於訪問超類中被子類的某個成員隱藏的成員。 8.2.1 使用super()呼叫父類的構造方法  在子類中使用super()呼叫父類的構造方法,必須是第一條語句  在本類中可以使用this()呼叫過載的構造方法,也必須是第一條語句  在子類的構造方法中this()和super()不能同時使用 8.2.2 使用super訪問父類中被子類隱藏的成員變數 父類的屬性被子類繼承,如果子類又添加了名稱相同的屬性,則子類有兩個相同名稱的屬性,如果父型別物件呼叫屬性,就是父類的,如果是子型別物件呼叫就是子類的屬性。 一個子類需要引用它的直接超類,都可以使用關鍵字super。 案例: 8.3 Object 8.3.1 Object類介紹 所有其他類都是Object的子類。也就是說,Object是所有其他類的超類。這意味著Object型別的引用變數可以引用任何其他類的物件。此外,因為陣列也是作為類實現的,所以Object型別的變數也可以引用任何陣列。 Object類定義了下面列出的方法,這意味著所有物件都可以使用這些方法。 方 法 用 途 Object clone() 建立一個和將要複製的物件完全相同的新物件。 boolean equals(Object object) 確定一個物件是否和另外一個物件相等 void finalize() 在回收不再使用的物件前呼叫 Class<?> getClass() 在執行時獲取物件的類 int hashCode() 返回與呼叫物件相關聯的雜湊值 void notify() 恢復執行在呼叫物件上等待的某個執行緒 void notifyAll() 恢復執行在呼叫物件上等待的所有執行緒 String toString() 返回一個描述物件的字串 void wait() void wait(long milliseconds) void wait (ling milliseconds, int nanoseconds) 等待另一個執行緒的執行

8.3.2 物件相等性比較 Object類中的equals()方法實現等價於“==”運算子,比較相等,如果實現物件的內容相等比較,自己的類必須重寫equals方法。 例如:String類對equals()方法進行了重寫,重寫後的equals方法比較兩個兩個字串的內容是否相同。 8.3.3 Object類的常用方法  equals(Object obj)方法 比較物件相等 Object類的實現是 等價於 == 相等的含義:兩個引用是否指向同一個物件。 自己的類要比較物件相等,重寫equals()方法 案例:重寫Box類的equals()方法  toString()方法 直接列印物件時,預設呼叫物件的toString()方法 Object類的toString方法輸出格式: getClass().getName() + ‘@’ + Integer.toHexString(hashCode()) 自己的類要重寫toString() 案例:重寫Box類的toString()方法。  protected Object clone() 克隆物件的方法 被克隆的物件的類必須實現Cloneable介面  finalize()方法 //終結方法 當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。  HashCode()方法 返回該物件的雜湊碼值 當我們重寫equals()方法,判斷兩個物件相等時,最好也同時重寫hascode()方法,讓相同物件的雜湊碼值也相同 8.4 final 8.4.1 final修飾變數、方法、類  如果final修飾變數,變數就是常量,常量不可修改,定義時必須初始化  如果final修飾方法,方法就不能被子類重寫  如果final修飾類,類就不能再被擴充套件,不能再有子類。Java類庫中的String、Math就是final類。 8.4.2 引用型別的常量 如果常量是基本資料型別,不可以再修改。 如果常量是引用型別,不能再將其他物件賦給該引用,但可以使用該引用改變物件內部的屬性。 例如 final Student s = new Student(“zhangsan”,20); s = new Student(“李四”,20); //錯誤 s.setName(“李四”); //可以 正確 第9單元 面向物件—多型 9.1 多型的概念 同一個方法名稱,執行不同的操作。方法過載就是一種多型的一種形式。 9.2 方法重寫 當子類從父類中繼承來的方法不能滿足需要時,子類可以重寫該方法,重寫方法要求方法名與引數列表都相同。 因此如果子類中的方法與父類中的方法同名、並且引數型別也相同,那麼子類中的方法就重寫了父類中的同名方法。 為什麼不直接定義另外一個方法?因為重寫方法可以實現執行時多型的效果。 注意:重寫只針對方法,屬性沒有重寫概念 9.2.1 方法重寫的規則 兩同:方法名相同、引數列表相同 兩小:返回值型別更小(子類)或相等、丟擲的異常類更小或相等 一大:訪問許可權更大或相等 案例複習: Student、Teacher重寫Person中的sleep()、show()方法 Dog、Cat重寫Animal中的eat()、show()方法 WeightBox、ColorBox重寫Box中的show()方法 重寫Shape類中的area()方法 重寫fruit類中的show()方法 9.2.2 方法重寫與方法過載的區別 只有當兩個方法的名稱和型別簽名都相同時才會發生重寫。如果不是都相同,那麼這兩個方法就只是簡單的過載關係。

9.2 動態方法排程與執行時多型 9.2.1 動態方法排程 當通過父類引用呼叫重寫方法時,在執行時會呼叫子類中的重寫版本。 動態方法呼叫要以方法重寫為前提。 Animal a; a = new Dog(); a.eat(); //動態方法排程:在執行時根據超類引用指向的物件確定呼叫哪個方法 9.2.2 執行時多型 執行時多型的實現機理:動態方法排程 總結:方法重寫是前提、動態排程是手段、多型是最終的目的 執行時多型的優點:靈活 Animal a; a = new Dog(); a.eat(); a = new Cat(); a.eat(); //執行時多型:方法名相同,得到的結果不同 執行時多型的兩個要素: (1)在子類中重寫超類中的方法 (2)使用超類引用呼叫重寫方法。 在自己的類中定義的toString()方法就是重寫方法。 注意不要混淆: 使用超類引用呼叫成員變數時,呼叫的是超類的成員變數。 9.2.3 多型的兩種形式 執行時多型:動態方法排程實現 編譯時多型:過載方法,編譯時通過方法匹配實現的 9.3 多型例項 例項1:Animal、Dog、Cat類的eat()方法、show()方法 例項2:Person、Student、Teacher、Worker類的show()方法、eat、sleep 例項3:Fruit、Apple、Banana的Show()方法 例項4:Shape、Rectangle、Circle、Triangle類的area()、draw()方法 9.4 多型應用 案例1:Feeder類,餵養Dog、Cat 案例2:Manager類,管理Student、Teacher、Worker 案例3:Salesman類,賣水果 案例4:Engineer類,使用Shape類 9.4 抽象方法與抽象類 當編寫一個類時,常常會為該類定義一些方法,這些方法用以描述該類的行為,那些這些方法都有具體的方法體。但在某些情況下,某個父類只知道其子類應該包含哪些方法,但無法準確地知道這些子類如何實現這些方法。例如Shape類的area()方法,因為Shape類的不同子類對面積的計算方法不同,即Shape類無法準確地知道其子類計算面積的方法,因此area()方法只能留給子類實現。 在某些情況下會希望定義這樣一種超類,在該超類中定義了一些子類應該包含的方法,但是在超類中不能給出這些方法的有意義的實現。例如,Animal類的eat()方法、Shape類的area()方法,無法給出有實際意義的實現,對於這類方法可以宣告為抽象方法。 問題: 既然父類中不能給出抽象方法的實現,為什麼還要在父類中新增這些方法呢? 9.4.1 抽象方法 抽象方法是使用abstract修飾的方法。將一個方法宣告為抽象方法,從而要求子類必須重新該方法。 注意:  抽象方法沒有方法實現,即沒有方法體{},只有定義。  類中如果有抽象方法,該類必須是抽象類,必須使用abstract  對於抽象方法,abstract不能與private、static同時使用。為父類新增抽象方法,然後讓子類實現,一個主要目的就是實現多型的效果,而實現多型效果需要兩個前提:一是子類重寫父類中的方法,二是使用父類引用呼叫子類重寫後的方法,根據父類實際指向的物件呼叫相應的重寫方法。如果將抽象方法宣告為private,則子類中就無法重寫該抽象方法;如果方法為static方法,則該方法屬於類,而不屬於某個物件,從而也就無法根據實際的指向的物件呼叫想用的方法。 9.4.2 抽象類 類定