java se
特點: 一次編譯,到處運作
解釋: java語言代碼編寫一次,代碼就可以在不同作業系統中運作,并且還能得到相同的運作結果
java語言的使用可以無視作業系統之間的差異性
jvm : java虛拟機,了解成一個軟體,模拟計算機實作過程, 一個虛拟機就像是一個小型的計算機,主要功能就是可以運作标準的java代碼, jvm虛拟機為java代碼營造出相同運作環境
簡介:
jvm (java virtual machine): java虛拟機,是運作所有java程式的假想計算機,是java程式的運作環境,是java 最具吸引力的特性之一.我們編寫的java代碼,都運作在 jvm 之上.
jre (java runtime environment): 是java程式的運作時環境,但是單獨的jvm虛拟機不能自己運作,需要支援jvm運作的功能代碼,jre包含 jvm 和運作時所需要的 核心類庫。
核心類庫:很多功能代碼, 代碼太多, 為了便于管理, 是以将代碼放置到一個庫中管理.
jre = jvm + jvm運作時需要的核心類庫功能;
runtime表示運作的概念
jdk (java development kit): 是java程式開發工具包,包含 jre 和開發人員使用的工具,例如 javac.exe(編譯器) 和 javadoc.exe(可以自動為java的代碼生成說明文檔)
jdk : 全稱java開發工具包, 主要功能就是可以進行java代碼的編譯(編寫), 還有運作
jdk = jre + 開發時需要工具包(核心類庫);
三個元件之間的關系
下載下傳官網:https://www.oracle.com/java/technologies/downloads/#java8-windows
當安裝jdk成功之後, jdk有bin檔案夾, 包含了所有的可以直接轉換成指令運作的應用程式, 未來java代碼編譯和運作,都需要從jdk的bin中找到指令, 執行代碼;
問題 : 目前, jdk的bin檔案夾路徑下的指令隻能在bin路徑下使用, 有很大的局限性, 真正環境應該是可以在裝置的任意路徑都可以使用的
如何解決問題, 可以配置環境變量.
實作bin目錄下的java相關指令可以在任意目錄下使用
注意事項:
整數類型中字面值常量的預設類型是int類型
long類型的變量在定義的時候,當字面值超過int範圍需要在字面值後加 l / l,建議 l
小數(浮點)類型
小數類型的字面值常量預設類型是 double類型
float 類型變量在定義的時候,需要在字面值後加 f / f,建議f
double 類型的變量在定義的時候,可以在字面值後加 d / d,也可以不加.
浮點型存儲的資料是不精确的資料,是以在運算過程中,其結果也有可能不精确.
字元類型
字元類型變量的指派方式:
(1) 通過 '' 形式指派
案例:
char c = 'a';
(2) 通過ascii碼表指派, 但是如果直接使用整數給char類型指派, 那麼整數範圍必須在0-65535之間, 因為人類的語言文字, 放在一起, 一共有65535個字元可以表示, 超出範圍,無法對應編碼表, 代碼報錯
char c = 65;
編碼表存在的解釋說明:
人類語言文字,需要被計算機識别, 而計算機底層全部都是二進制, 也就是數字; 是以需要将人類的語言文字與數字形成對應關系, 目的就是為了讓計算機以數字的形式将字元存儲下來, 于是最早期, 美國人形成了一張表, 簡稱ascii編碼表;
ascii編碼表中存儲了所有的字母大小寫, 英文符号以及數字與整數的對應關系
a : 0100 0001 // a在計算機中實際存儲的是二進制的0100 0001
注意 : 比較常見編碼需要記住:
常用的ascii碼表值
ascii編碼表:
中國有自己的編碼表, 相容了ascii, 同時咱們編碼表中, 包含所有中文文字
gbk : 中國标準資訊交換碼表
utf-8 : 國際标準碼表, 包含了各個國家語言文字
布爾類型
引用資料類型
string 類是字元串,在定義string類型的變量的時候,使用 "" 括起來表示字元串常量内容
舉例 : string str = “寫任意字元序列”;
(1) 轉換原因: java是強類型語言,資料類型之間不能随意轉換,但運算時資料類型不比對,是以需要轉換.
(2) 資料類型轉換分類:
a : 自動類型提升
b : 強制類型轉換
範圍小的資料類型可以直接轉換為範圍大的資料類型
舉例 : 50ml水杯, ---> 小資料類型
500ml水瓶---> 大資料類型
将水杯中水倒入到水瓶中, 可以, 容量完全符合
資料類型範圍大小排序:
boolean類型不參與大小排序
(1) 大範圍資料類型的變量/常量 指派 給一個小範圍資料類型的變量,需要進行強制轉換.
舉例 : 50ml水杯, ---> 小資料類型
(2) 格式:
目标資料類型 變量名 = (目标資料類型)原資料類型變量名或原常量值;
(3) 注意事項:
強制類型轉換可能會損失精度,得到錯誤的資料.
小數類型強制轉換為整數類型時,直接舍去小數部分,隻保留整數部分.
(4) 常量優化機制: 在編譯時,整數常量的計算會直接算出結果,并且會自動判斷該結果是否在該資料類型取值範圍内
1.元的概念: 可以操作的資料或者表達式.
2.三元運算符: 别名三目運算符,同時可以操作三個資料或者表達式的運算符.
3.格式: (典型的兩種情況選擇其中一種)
表達式1 ? 表達式2 : 表達式3;
4.說明:
1)表達式1必須是boolean類型的表達式,計算結果隻能是true、或者false
2)表達式2和表達式3可以是任意類型的表達式
5.運算流程:
1)計算表達式1的值,要麼為true,要麼為false
2)如果表達式1計算結果為true,就選擇表達式2作為三元表達式的計算結果
3)如果表達式1計算結果為false,就選擇表達式3作為三元表達式的計算結果
<<:左移
空位補0,被移除的高位丢棄
>>:右移
被移位的二進制最高位是0,右移後,空缺位補0;最高位是1,高位補1。
>>>:無符号右移
被移位二進制最高位無論是0或者是1,空缺位都用0補。
位運算符的小技巧:
1、判斷奇偶性
按位與: &1(0000 0001) 等于 0 為偶數, 等于 1 為奇數,因為偶數末位一定為0,其他位都是在 &0 結果都是0
2、判斷是否是2的幂次方
return num & (num -1)== 0
比如4 100 & 011 = 0,是2的幂次方
3、按位或: x | 0 等于 x
将兩個值(x,y)拼在一起作為新的值z
z = x << 32 | y
說明:上面的前提是z的類型是64位,這樣z的前32位代表的是x,後32位代表的y。想要再通過z擷取x,則
x = z >> 32
4、按位與: x & 1 等于 x
5、常用操作
& = 取交集
| = 取并集,比如 x | y = x 中再加 y
& ~x : 将x去掉(跟x的反取交集,相當于去掉x)
流程控制 : 代碼的執行順序, 分為三大類: 順序結構, 分支結構, 循環結構
分支結構: 當代碼執行到某種情況下, 接下來可以有多種選擇, 挑選最符合當下場景的其中一種邏輯運作, 多選一, 實作,主要就是if語句, switch語句
1.方法定義注意事項:
1)方法不能嵌套定義,每一個方法都是獨立的
2)方法的先後沒有差別,都是平級關系
3)方法可以嵌套調用,甚至可以自己調用自己
棧記憶體概念:
jvm虛拟機運作代碼: jvm虛拟機就是運作java代碼的容器,jvm本身就是個軟體,運作時就需要在記憶體中開辟空間,jvm将其占有的記憶體空間劃分成5塊空間區域,其中一塊空間,稱為棧記憶體
棧記憶體: 代碼中的方法運作, 需要在棧記憶體中開辟空間運作; 方法調用時進入棧記憶體中開辟空間, 方法運作完畢, 出棧記憶體, 占有空間釋放(方法彈棧死亡)
方法的重載: overload,超載單詞
方法重載的概念記住 : 有時筆試題中, 會出現 “什麼是overload(重載), 什麼是override(重寫)”
在同一個類中,方法名相同,參數清單不同,與傳回值類型無關的多個方法,稱為重載
數組含義: 集中存儲相同類型資料的容器
數組特點:
1)存儲資料長度固定的容器, 數組是一個定長容器, 當定義一個數組時, 必須指定數組的長度(可以存儲的資料的個數)
2)存儲資料的資料類型要一緻
索引通路數組中的元素:
數組名[索引] = 數值; //為數組中的元素指派
變量 = 數組名[索引]; //擷取出數組中的元素
當定義出一個數組時, jvm虛拟機會預設為數組中的每一個元素進行預設的賦初值動作, 根據不同數組中存儲的資料類型不同, 初值也不同
整數 : 0
浮點類型 : 0.0
char類型 : ‘ ’
boolean類型 : false
引用資料類型 : null, null表示引用資料類型為空
1.含義: 在建立數組時,直接将元素确定的定義方式
2.格式:
資料類型[] 數組名 = new 資料類型[]{元素1, 元素2, ..., 元素n};
注意事項:
1)在第二個方括号中,不能寫數組元素個數
2)元素值的羅列,元素和元素之間,使用逗号分隔
3)羅列出來的元素值,資料類型必須和聲明數組時資料類型一緻
3.簡化格式:
資料類型[] 數組名 = {元素1, 元素2, ..., 元素n};
注意事項: 不能分成兩行寫
1.異常(exception): 表示在java代碼編譯和運作過程中,出現了不正确的,不正常的,不符合實際場景的情況,統稱為異常
2.數組中常見的異常有兩種:
a: 數組索引越界異常
b: 空指針異常
數組索引越界異常
1.索引越界異常:
arrayindexoutofboundsexception
數組 索引 超出 邊界 異常
2.發生索引越界異常原因:
使用的索引在數組中不存在
3.代碼分析:
觀察一下代碼,運作後會出現什麼結果
public static void main(string[] args) {
int[] arr = {1,2,3};
system.out.println(arr[3]);
}
建立數組,指派3個元素,數組的索引就是0,1,2,沒有3索引,是以我們不能通路數組中不存在的索引,程式運作後,将會抛出 arrayindexoutofboundsexception 數組越界異常.在開發中,數組的越界異常是不能出現的,一旦出現了,就必須要修改我們編寫的代碼.
4.越界異常避免方案
不要通路不存在的索引,使用索引時,驗證索引在"0--數組長度-1"範圍
5.數組的長度屬性: 每個數組都具有長度,java中賦予了數組一個屬性,用于擷取數組的長度,語句為:數組名.length
空指針異常
1.空指針異常
nullpointerexception
空 指針 異常
2.發生空指針異常原因:
當引用資料類型值設定為null(前提),證明這個變量引用沒有指向任何堆記憶體位址,但仍然想通過這個變量引用通路堆記憶體中資料,就會報出空指針異常
注: null,即為空,用于表示在棧記憶體的引用中,不記錄任何堆記憶體的位址
觀察一下代碼,運作後會出現什麼結果
int[] arr = {1,2,3};
arr = null;
system.out.println(arr[0]);
}
arr = null這行代碼,意味着變量arr将不會再儲存數組的記憶體位址,也就不允許再操作數組了,是以運作的時候會抛出nullpointerexception 空指針異常.在開發中,數組的越界異常是不能出現的,一旦出現了,就必須要修改我們編寫的代碼.
jvm的記憶體劃分:
數組在記憶體中的存儲
一個數組的記憶體圖
數組引用的輸出的結果是位址,是數組在記憶體中的位址.new出來的内容,都是在堆記憶體中存儲的,而方法中的變量arr儲存的是數組的位址.
兩個數組的記憶體圖
引用資料類型每次new,都在記憶體中開辟新的空間位址.
多個引用指向同一個數組空間
任意一個引用修改了數組中的内容,其他引用通路到的就是修改後的資料.
周遊數組元素
數組獲最值
數組元素交換
數組的反轉
冒泡排序
面向對象概述:
面向過程 : 有一個需求實作,思想, 我怎麼去實作, 強調的是做事的步驟,需要自己一步一步的去操作實作。
面向對象的對象泛指現實中一切事物,每種事物都具備自己的屬性和行為。面向對象思想就是在計算機程式設計過程中,參照現實中事物,将事物的屬性特征、行為特征抽象出來,描述成計算機事件的設計思想。
面向對象差別于面向過程思想,有一個需求實作思想, 誰來幫我實作, 強調的是通過調用對象的行為來實作功能,而不是自己一步一步的去操作實作。
面向過程是面向對象的基礎, 面向對象基于面向過程實作的, 但是代碼思想層面上, 面向對象時更進階的設計思想
面向對象的特征:
1、封裝
2、繼承
3、多态
類的概述
類是一組相關屬性和行為的集合
屬性 : 一個事物的特征(成員變量或者全局變量)
行為 : 一個事物可以做功能(方法)
對象的概述
java是一類事物的具體展現。
對象是類的一個執行個體,必然具備該類事物的屬性和行為。
類與對象的關系
類是對一類事物的描述,是抽象的。
對象是一類事物的執行個體,是具體的。
類是對象的模闆,對象是類的實體。
類中的内容:
屬性:
對事物特征的描述展現 java代碼中使用變量展現 被稱之為成員變量。
【和以前定義變量幾乎是一樣的。隻不過位置發生了改變。在類中,方法外。】
行為:
對事物功能【能幹什麼】的描述 java代碼中使用方法展現 被稱之為成員方法。
【和以前定義方法幾乎是一樣的。隻不過把static去掉,static的作用在後面課程中再詳細講解】
對象的使用
建立對象: 類名 對象名 = new 類名(); // 類本身就是一種引用資料類型
成員的使用:
擷取成員變量值:
變量 = 對象名.成員變量;
修改成員變量值:
對象名.成員變量 = 新值;
通路成員方法:
對象名.成員方法(實參);
成員變量的預設值
一個對象建立的記憶體圖
兩個對象的記憶體圖
兩個對象引用指向同一個記憶體空間
匿名對象的使用
概述 : 沒有名字的對象
格式 : new 類名(實參);
特點 : 隻能使用一次
使用場景: 如果某個成員或方法隻使用一次, 就可以使用匿名對象
優勢: 在記憶體中存在時間短, 相對節省記憶體
成員變量和局部變量的差別
定義位置不同
成員變量: 類中方法外
局部變量:方法中
記憶體位置不同
成員變量:堆空間
局部變量:棧空間
生命周期不同
成員變量:随着類對象的建立而建立,随着對象的消失而消失
局部變量:随着所在方法的執行而建立,随着方法的執行完畢而消失
預設值不同
成員變量:有預設值
局部變量:沒有預設值
封裝的原則:
将屬性隐藏起來
使用時對外提供公共的通路方式
封裝的好處:
隐藏了事物的實作細節
提高了代碼的複用性
提高了代碼的安全性
private : 是一個關鍵字, 是私有的的意思, 是一個修飾符
修飾内容:
修飾成員變量(最常用)
修飾成員方法
修飾構造方法
修飾内部類
修飾效果:
隻能在本類中使用,其他所有外類不能直接使用private修飾的成員
getter方法和setter方法是對屬性封裝後對外提供的統一通路屬性的通路方式
作用:
getxxx():擷取封裝屬性的值
setxxx(參數清單):修改封裝屬性的值
注意:xxx代表的是封裝屬性的名稱,首字母大寫
把封裝後對相關操作的修改操作稱之為封裝的優化
變量的通路原則
總體原則:就近通路原則
就近通路:
當在通路某個變量名稱的時候,會先尋找最近的該變量名稱的定義,如果尋找到了,就使用該變量,如果沒有找到,才到更遠的位置尋找該變量名稱的定義。
比如:
this關鍵字含義:代表所在類的目前對象的引用(位址值),即對象自己的引用。
this關鍵字作用:
當成員變量和局部變量重名, 帶有this關鍵字的變量表示成員變量的使用
開發中, setter方法中局部變量和成員變量同名指派失敗的問題就可以使用this關鍵字來解決
哪個對象調用了帶有this關鍵字的方法, this關鍵字就表示哪個對象本身
cat c = new cat();
類名 對象名 = new 類名(); // 對象建立過程中, 最後的小括号就表示構造方法調用
構造方法概述: 當一個對象被建立時候,構造方法用來初始化該對象,給對象的成員變量賦初始值。構造方法有自己獨有的方法格式。
解釋 : 建立對象,構造方法必須調用,既然必須要調用構造,就要讓這個構造方法發揮最大價值, 是以可以在建立對象的同時, 就給對象中成員變量進行指派
構造方法分類: 有參構造, 無參構造
構造方法定義格式:
構造方法特點:
方法名必須和類名一緻
沒有傳回值類型,連void都不寫
不需要傳回值類型
預設被jvm調用使用, 構造方法調用時機:
在建立對象同時, 被jvm虛拟機主動調用,并且建立一次對象, 構造方法隻調用一次, 因為構造方法無法手動通過對象名調用
注意事項:
如果你不提供構造方法,系統會給出無參數構造方法。
如果你提供了構造方法,系統将不再提供無參數構造方法。
構造方法是可以重載的,既可以定義參數,也可以不定義參數。
如果代碼中即定義了空參數構造, 也同時定義了有參數構造, 那麼建立對象時, 可以從多個構造中選擇其中任意一個調用即可
如果代碼中定義有參數構造, 請一定要加上空參數; 代碼中必須要有一個空參數構造,面向對象中的很多使用, 都是空參數構造的調用. 或者自己不定義構造, 使用系統預設生成的空參構造就可以
方法重載 : 定義在同一個類中, 方法名字相同, 參數清單不同的多個方法之間, 稱為方法重載, 與方法是否有傳回值無關
javabean是java語言編寫類的一種标準規範。符合javabean 的類,要求
類必須是具體的和公共的
所有屬性使用private修飾
提供用來操作成員變量的set 和get 方法
并且具有無參數的構造方法(建議有)
靜态就是 static , 主要用來修飾java的變量和方法的關鍵字。
沒有靜态與有靜态的場景對比:
a : 沒有靜态
如果某個類型的所有對象,都具有一個相同的屬性值,那麼這個屬性值就沒有必要在所有對象中,都存儲一份。還有壞處:浪費記憶體空間;維護難度大,一旦需要修改,就得修改所有的對象。
b: 有靜态
如果某個類型的所有對象,都具有一個相同的屬性值,那麼就在這個屬性的定義上,加一個static靜态關鍵字。讓該變量存儲在方法區位元組碼的靜态區中,避免了所有對象都存儲相同資料的問題,節省了記憶體空間,将來維護容易(隻需要修改一次)
沒有靜态記憶體圖:
有靜态的記憶體圖:
靜态變量屬于類, 不屬于對象
加載時機:
随着類.class檔案的加載而加載
靜态變量随着類的加載進方法區,就直接在靜态區給開辟了存儲靜态變量的記憶體空間
靜态變量優先于對象而存在
靜态變量被所有該類對象所共享
調用方式:
類名調用 或者 建立對象調用
擴充 : 類型中的靜态成員變量, 或者是靜态方法, 都可以直接使用類名調用, 而不需要建立對象
總結: 靜态方法不能直接通路非靜态資源(變量,方法,this關鍵字)
1、靜态方法:在方法聲明上,加上了static關鍵字的方法,就是靜态方法
2、靜态方法不能通路非靜态的變量
原因:
靜态方法可以在沒有建立對象的時候調用,而非靜态的變量隻有在對象建立之後才存在。如果靜态方法可以通路非靜态的變量,那麼就相當于在對象建立之前,就通路了對象建立之後的資料。明顯不合理。
3、靜态方法不能通路非靜态的方法
靜态方法可以在沒有建立對象的時候調用;非靜态的方法可以通路非靜态的變量。如果靜态方法可以通路非靜态的方法,就相當于靜态方法間接的通路了非靜态的變量,和第2點沖突。
4、靜态方法中不能存在this關鍵字
this關鍵字表示本類目前對象。靜态方法可以在對象建立之前調用。如果靜态方法可以通路this關鍵 字,相當于在建立對象之前,就使用了對象本身---沖突
概念上,所屬不同:
非靜态變量屬于對象
靜态變量屬于類,類變量
記憶體空間不同,存儲位置不同
非靜态變量屬于對象,是以存儲在堆記憶體中
靜态變量屬于類,存儲在方法區的靜态區中
記憶體時間不同,生命周期不同
非靜态變量屬于對象,是以生命周期和對象相同,随着對象的建立而存在,随着對象的消失而消失
靜态變量屬于類,是以生命周期和類相同,随着類的加載而存在,随着類的消失(記憶體管理)而消失
通路方式不同
非靜态變量隻能使用對象名通路
靜态變量既可以使用對象通路,也可以通過類名通路:
類名.靜态變量名 或者 對象名.靜态變量
類名.靜态方法名()
繼承的優勢:
能提高代碼的複用性
提高代碼的可維護性
為多态提供了前提
繼承中弊端:
繼承讓類與類之間産生了關系,類的耦合性增強了(關聯程度太高),當父類發生變化時子類實作也不得不跟着變化,削弱了子類的獨立性
實際java開發中:
高内聚 : 類中功能進行盡量多
低耦合 : 少與外類發生密切關聯
1、私有的成員不能被繼承
父類中有一些私有成員,不能在子類中直接使用
其實在子類對象中,仍然包含了父類中定義的私有成員變量
隻不過在子類中,不能直接通路父類中定義的私有成員變量
2、父類中的構造方法,不能繼承
原因:
父類的構造方法需要和父類的類名一緻、子類的構造方法需要和子類類名一緻,父類和子類的類名不一樣。是以無法繼承,名稱有沖突。
父類的構造方法用于給父類的成員變量指派,子類的構造方法用于給子類的成員變量指派,子類的成員變量較多,使用父類的構造方法無法将子類中所有的成員變量都進行指派,是以不繼承父類的構造方法
解決:
1、java支援單繼承,不支援多繼承,java支援多層繼承
2、原因:
子類可以繼承并且使用父類中的所有非私有的成員變量
父類中定義了成員變量,子類中沒有定義,那麼子類可以直接使用父類中非私有成員
父類中沒有定義成員變量,子類中定義了,子類可以自己調用自己的變量,父類不能調用子類特有變量
總結: 子類可以自己和父類的成員變量,父類隻能使用自己的成員變量
父類中定義了變量,子類中重新定義了這個變量,在子類中調用的就是子類的變量
原因: 變量的通路就近原則
方法内部,自己定義了變量,使用方法内部變量
方法内部沒有定義,找目前類中成員變量
類中成員變量也沒有定義,找父類中的成員變量
父類中沒有定義變量,再繼續找父類的父類,直到找到最後(object類,所有類的直接或者間接的父類,object是一個最頂層的類,也沒有找到,才報錯
如果子父類中成員變量重複定義, 想調用父類成員變量, 那麼使用關鍵字 super
super : 關鍵字, 表示目前類型父類引用(super使用于子類類型中)
使用 : super.父類成員變量名;
注意 : super關鍵字第一種使用場景, 區分子類和父類重名成員, 帶有super.成員表示父類成員使用
1、this和super:
this表示本類目前對象的引用
super表示本類目前對象父類的引用
2、繼承關系的記憶體了解:
如果zi類類型需要進入到記憶體中使用, zi類對應的父類fu.class位元組碼檔案先進入到方法區中, 然後zi.class位元組碼檔案才進入到方法區中
建立子類類型對象, 在堆記憶體中開辟了空間之後, fu類中的成員先進入到記憶體中, 由jvm虛拟機先為父類中成員進行指派
子類成員後進入到堆記憶體中
使用成員, 優先使用子類中定義成員, 如果子類中沒有對應成員或者使用super關鍵字, 調用父類中繼承到成員使用
總結 : 父類優先于子類進入到記憶體中, 父類先為子類将可繼承資料準備好, 自己進入到記憶體中才能繼承使用
父類中私有方法不能被子類繼承使用
子類中定義的和父類中繼承到方法不同, 子類可以調用自己特有方法功能, 可以調用從父類繼承來的功能
當子類需要父類的功能,而功能主體子類有自己特有内容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的内容, 子類重寫是為了讓方法越來越好
重寫override注意事項:
重寫需要與父類原方法 傳回值類型, 方法名 ,參數清單相同
私有方法不能被重寫(父類私有成員子類是不能繼承的)
子類方法通路權限不能更低(public > 預設 > 私有)
在子類重寫方法上, 通常使用注解 @override, 辨別和驗證方法是重寫方法
子類重寫了從父類繼承來的方法功能, 子類重寫方法優先調用和運作
如果子類父類中有相同方法定義, 使用super關鍵字,區分子父類中重名方法功能
super.父類方法名(需要實際參數);
注意 : 重寫的方法本身還是屬于父類,隻是在子類中重新實作了這個方法的内容。
筆試題:
什麼overload(重載)? 什麼override(重寫)?
重載 : 定義在同一個類中, 方法名相同,參數清單不同, 與方法傳回值類型無關的多個方法之間, 稱為重載
重寫 : 在子父類關系中, 子類重寫從父類繼承來的方法功能, 要求方法參數清單, 傳回值類型, 方法名與父類方法一緻, 方法内容可以修改
重寫注意事項:
私有方法不能重寫
重寫後方法的權限大于等于父類原有權限
重寫方法通常使用@override注解進行辨別
父類中構造無法被子類繼承, 但是子類構造方法中可以調用父類構造; 在子父類繼承關系中, 父類優先于子類進入到記憶體, 父類中資料優先于子類進行初始化(指派)
如果子類構造方法中, 沒有手動調用任何構造(本類, 父類),系統會預設在子類構造方法第一行調用super(); 目的是為了讓父類中成員優先于子類進入記憶體中指派
super() : 表示調用父類空參數構造方法
如果子類構造方法中, 手動調用本類或者父類構造, 那麼系統不會再預設調用任何過構造, 一律以手動調用構造為準
super() : 父類構造調用. 必須寫在構造方法第一位置上, 直接保證父類構造優先于子類進入記憶體運作
1、含義:
this關鍵字表示本類目前對象的引用
super關鍵字表示本類目前對象的父類的引用
2、super和this都可以通路成員變量
super隻能通路父類中定義的成員變量
this既可以通路子類中定義的成員變量,也可以通路父類中定義的成員變量
3、super和this都可以通路成員方法
super隻能通路父類中定義的成員方法
this不僅可以通路子類中定義的成員方法,也可以通路父類中定義的成員方法
4、super和this都可以通路構造方法:this語句和super語句
實際代碼中this和super的使用:
this : 目前類型對象的使用
可以區分成員變量與局部變量的重名問題, 帶有this關鍵字的變量表示成員變量的使用
super : 目前類型對象的父類引用
子父類定義重名成員變量, super.成員變量表示父類成員的使用
子父類定義重名成員方法(子類重寫), super.方法() 父類中的方法功能
子類構造方法第一行, 一定要調用父類構造, 為了保證父類成員優先于子類進入到記憶體中 super(父類構造實際參數);
1、使用大括号包起來的一段代碼。放在不同的位置,有不同的名稱,有不同的作用,有不同的執行時機。
2、分類:
局部代碼塊
構造代碼塊
靜态代碼塊
同步代碼塊(多線程)
1、格式:使用大括号包起來的一段代碼
2、位置:方法中
3、作用:
限定變量的生命周期
在局部代碼塊中【聲明】的變量,隻能在局部代碼塊的範圍内使用,一旦出了局部代碼塊的大括号,變量就不能繼續使用了。
某個變量一旦不能使用了,就會被回收,節省記憶體空間
4、注意事項:
如果是在局部代碼塊中聲明了變量,會減少變量的聲明周期,出了局部代碼塊就無法繼續使用局部代碼塊中聲明的變量。
如果是在局部代碼塊中修改了局部代碼塊外聲明的變量,局部代碼塊結束之後,并不會消除局部代碼塊對這個變量的修改。
2、位置:類中方法外
用于給成員變量初始化指派
4、構造代碼塊的執行說明:
1、在建立對象的時候執行,由jvm預設調用
2、在構造方法執行之前,執行
3、任意一個構造方法執行之前,都會執行一次構造代碼塊的内容
4、如果每個構造方法都會執行的内容,提取到構造代碼塊中
1、格式:
用于給靜态的成員變量初始化指派
用于執行那些隻需要執行一次的代碼,例如驅動加載等
4、執行特點:
1、随着類的加載而執行
2、類隻加載一次,是以靜态代碼塊隻執行一次
3、執行的時機最早:早于所有的對象相關内容
封裝 : 隐藏事物實作細節, 多外提供公共通路方式, 方法, private關鍵字, 提高代碼安全性, 提高代碼的複用性
繼承 : 類與類之間發生子父類繼承關系, extends關鍵字, 子類可以直接繼承使用父類中的成員(私有,構造除外), 提高代碼的複用性, 可維護性, 為多态提供了前提條件; 弊端: 類與類之間的耦合度過高
多态 : 事物的多種形态, 要求有繼承關系(或實作關系), 子類重寫父類中方法, 父類的引用指向之類的對象; 多态的表達式中, 對于方法調用, 編譯看左, 運作看右; 多态好處就是可以極大提高代碼的擴充性
多态概述
事物的多種表現形态就是多态;
java中的多态就了解為對象的不同資料類型的展現也就是子類對象充當父類類型對象
多态的發生前提:
必須要有繼承或實作關系
有方法的重寫
父類引用指向子類的對象
格式:
父類類型 變量名 = new 子類名(實參);
原則:
編譯看左邊,運作看左邊
1、編譯的時候,要看【=】左邊的引用所屬的類型中,是否有該變量的定義,如果有,就編譯成功,如果沒有,就編譯失敗
2、運作的時候,也是使用等号左邊類型中的變量
person p = new teacher();
當有了一個多态的表達式, 需要通過變量p調用成員變量
編譯代碼時(寫代碼時), 檢查, 等号左邊的person類中,是否定義了該成員變量, 如果沒有定義代碼報錯
當person類中定義了該成員, 實際調用成員變量時, 調用的仍然還是等号左邊的person類型中的成員變量
編譯看左,運作看右
編譯的時候,要看【=】左邊的引用所屬的類型中,是否有該方法的定義,如果有,就編譯成功,如果沒有,就編譯失敗。
運作的時候,要看【=】右邊的對象所屬的類型中,是如何實作這個方法的。最終運作的是子類重寫過的方法實作。
1、向上轉型:
使用子類的引用指向子類的對象(正常情況)
多态中,使用父類的引用指向子類的對象(向上轉型)
person p = new teacher();// 向上轉型
本質:縮小了對象本身的通路範圍,減少了通路的權限(隻能通路父類中定義的内容)
2、向下轉型:
類比性記憶 : 子類想成年輕人, 年齡小; 父類想成老年人, 年齡大; 向下就是老年人, 回複成年輕人, 年齡向下
概念:
讓指向子類對象的父類引用,【恢複】成子類的引用
格式:
子類類型 引用名稱 = (子類類型)父類類型的引用;
本質:
【恢複】子類類型原本就有的通路範圍
3、缺陷: 向下轉型的時候有可能轉為其他子類的類型,編譯不會報錯但是運作時會發生類型轉換異常
4、解決方案:
轉之前判斷一下要轉換的類型是不是多态對象之前的類型。使用一個關鍵字 instanceof 來判斷向下轉換類型是不是自己的類型
多态對象 instanceof 指定的資料類型 , 傳回值為布爾類型的資料
提高了代碼的可擴充性(靈活性)
在方法的參數清單中,形式參數是父類類型的引用,将來調用方法的時候,父類類型的任意子類對象,都可以作為方法的實際參數。
1、抽象:抽取像的、相同的、相似的内容出來
2、抽象方法:java中隻有方法聲明沒有方法實作并且被關鍵字abstract修飾的方法就是抽象方法
3、格式:
修飾符 abstract 傳回值類型 方法名(參數清單);
4、注意:
抽象方法隻能定義在抽象類中和接口中
1、抽象類: 可以定義抽象方法的類,就是抽象類。
2、java中被關鍵字abstract修飾的類就是抽象類
3、定義格式:
1、抽象類和抽象方法都需要使用abstract關鍵字修飾
抽象類:abstract class {}
抽象方法:public abstract void test();
2、抽象類和抽象方法的關系:
抽象方法所在的類必須是抽象類
抽象類中未必一定都定義抽象方法,抽象類中未必存在抽象方法
3、抽象類的執行個體化(抽象類如何建立對象)
抽象類不能直接執行個體化
定義抽象類的子類,由子類建立對象,調用方法
注意 : 抽象類存在意義就是為了有子類繼承, 重寫抽象方法
4、抽象類子類的前途
在子類中,将父類所有的抽象方法全部重寫(實作),子類就成了一個普通類,就可以建立對象
在子類中,沒有将父類中所有的抽象方法全部實作,子類就還是一個抽象類,還需要使用abstract關鍵字修飾子類。
普通類中可以定義成員 + 抽象方法 = 抽象類中成員
1、成員變量:可以定義變量,也可以定義常量,但是不能被抽象
2、構造方法:有
雖然本類無法建立對象,但是抽象類一定有子類,子類會通路父類的抽象方法。
是否有構造方法,不取決于是否可以建立對象,而是取決于是否可以定義成員變量。如果可以定義成員變量,那麼就需要初始化成員變量,就是構造方法來完成的。
3、成員方法:
既可以是抽象方法:強制子類重寫
也可以是非抽象方法:用于給子類繼承,提高代碼的複用性
接口是java用來描述多種不同規則的集合體;
規則在java中就是抽象方法,接口就是存放了不同的抽象方法的集合體
java中使用關鍵字interface表示,接口和類同級别的
好處:
一旦将命名規則定義出來,【方法的調用】和【方法的實作】就分離開了,可以提升開發效率,降低代碼的耦合性
抽象類 : 畢竟是個類, 類與類之間單繼承關系, 一個子類隻能有一個直接父類, 類與類之間有很大的耦合度
接口 : 不是類, 類與接口之間的關系, 可以多個對應關系, 一個類可以同時實作多個接口, 接口中全是抽象方法, 是以方法的規則, 都必須要實作類重寫, 是以接口與實作類之間的耦合度, 降低
修飾符 interface 接口名 {接口的内容}
接口的源檔案也是.java檔案,照樣參與編譯,編譯後的檔案依然是位元組碼檔案【.class】
内容:
屬性:接口中的成員變量, 實際是成員常量,預設被 public static final修飾
注意:使用接口名通路即可
方法:jdk1.8之前:隻有抽象方法, 預設被public abstract 修飾
沒有構造方法 不能直接建立對象的
功能必須需要類來實作之後被類的對象調用使用
概述: 接口書寫好之後裡面的規則要想被使用,需要類來重寫,一個類又需要這個接口的功能,要類和接口發生關系,就使類擁有接口中的規則功能。
類去重寫接口規則的過程就叫做實作接口
類實作接口:
使用關鍵字implements連接配接類和接口
接口的實作類前途:
是一個抽象類,該類沒有實作接口中的所有抽象方法
是一個普通類,該類實作了接口中的所有抽象方法
單實作:
一個類實作了一個接口的實作方式
多實作:
一個類同時實作多個不同接口的實作方式就是多實作
1、類與類
繼承的關系,使用extends關鍵字
可以單繼承、不可以多繼承、可以多層繼承
2、類與接口:
實作關系,使用implements關鍵字
java中有單實作和多實作
多實作沒有安全隐患:即使兩個接口中有一樣的方法聲明,但是在類中也隻有一個實作
注意 : 父優先
3、接口與接口:
繼承關系,使用extends
可以單繼承、也可以多繼承、可以多層繼承
多繼承的格式:
4、類和接口的差別(設計差別):
抽象類:定義物體本身具有的固有屬性和行為
接口:定義物體通過學習、訓練而擴充出來的行為
定義在一個類中的另一個類就叫做内部類
舉例:在一個類a的内部定義一個類b,類b就被稱為内部類
分類: 根據定義的位置不一樣以及是否有名分為了不同的内部類,具體分類如下:
成員内部類
局部内部類
匿名内部類
通路特點:
内部類可以直接通路外部類的成員,包括私有成員
外部類要通路内部類的成員,必須建立對象
定義位置: 在類中方法外,跟成員變量是一個位置
外界建立成員内部類格式
成員内部類的推薦使用方案
案例: 定義一個身體body類, body類中定義一個heart心髒内部類, 測試内部類的使用
定義位置: 局部内部類是定義在方法中的類
通路方式:
-局部内部類,外界是無法直接使用,需要在方法内部建立對象并使用
-該類可以直接通路外部類的成員,也可以通路方法内的局部變量
概述: 想要使用一個類的子類或接口實作類對象的時候,匿名内部類就是其中的一種擷取子類對象或實作類對象的方式,他是一個固定的文法格式。
匿名内部類的使用前提:
存在一個類或者接口,這裡的類可以是具體類也可以是抽象類
匿名内部類的格式
舉例:
匿名内部類的本質
本質:是一個類的子類對象或者一個接口的實作類對象
匿名内部類的使用:
匿名内部類可以通過多态的形式接受
匿名内部類作為對象直接使用(隻能使用一次)
當發現某個方法需要接口或抽象類的子類對象,我們就可以傳遞一個匿名内部類過去,來簡化傳統的代碼
1、final是一個關鍵字 含義:最終的,最後的,表示不能再改變的。
2、final關鍵字:可以修飾類、方法、變量
3、修飾類:
表示一個最終類,表示不能有子類,【不能被其他類繼承】
一旦一個類型不能被繼承,那麼其中所有的方法都不能被重寫
不影響目前類的方法被調用
4、修飾方法:
表示一個最終方法,【該方法不能被重寫】
5、修飾變量:
表示一個最終變量,該【變量變成了常量】,就隻能指派一次
使用final修飾的變量, 不能進行二次指派, 值不能改變, 是以成為常量, 命名規範 : 所有單詞前大寫, 多個單詞之間使用_進行分隔了; 舉例 : school_name pi
定義常量的好處:見名知意,容易了解;可維護性高
總結 :
final修飾的類不能有子類
final修飾的方法不能被重寫
final修飾的變量,稱為常量,其值不能修改
包的概述: 用來統一分類管理源代碼資源的特殊的檔案夾;這個檔案夾會參與編譯。
com.ujiuye.demo 下的 person類進行編譯的時候類所在的包參與編譯,編譯後
位元組碼檔案名:com.ujiuye.demo.person
位元組碼檔案中類名:com.ujiuye.demo.person【全限定類名】
統一管理代碼資源
保證代碼編譯後類名唯一
保證代碼運作的過程直接進入包找到對應的類
命名規則:
使用公司域名的反寫【保證每一個包路徑唯一】
全部小寫
包名和包名之間使用.隔開
包的聲明:
使用關鍵字 package + 包路徑【ide生成類的時候自動聲明】
導包:
同包下:不需要導包
不同包:需要導包【jdk的lang包除外】
使用 import + 包路徑
概述: 用來限定資源的使用範圍的修飾詞彙,就叫做權限(使用)修飾符,不同的符号有不同的限定範圍
分類: 從小到大權限羅列
private :私有的 限定範圍是:本類中使用, 通常修飾成員變量
預設的 :啥也不寫 限定範圍: 本類和本包(package)中使用
說明 : 定義類, 定義方法, 定義一個變量, 如果沒有使用任何權限修飾符, 那麼就使用預設權限, 切記, 什麼都不寫, 寫出來反而報錯
protected :受保護的 限定範圍: 本類和本包中使用, 可以外包的子類内部使(protected 受保護權限被外包子類繼承了, 那麼在外包子類中, 相當于private)
說明 : protected 隻能修飾方法和變量, 不能修飾類, protected 關鍵字也是封裝的一種展現形式
public :公共的 限定範圍:沒有範圍, 通常修飾類和方法