Java — 面向對象
一、類和對象
簡介:類是對事物的一種描述,對象則為具體存在的事物。
類的定義:
public class 類名 {
// 成員變數
訪問修飾符 數據類型 變數名;
…
// 成員方法
訪問修飾符 返回類型 方法名(參數列表) {
若干語句;
return 方法返回值;
}
...
}
創建對象:類名 對象名 = new 類名();
成員調用:對象名.成員變數;,對象名.成員方法(參數列表);
二、方法
定義:訪問修飾符 返回值類型 方法名(參數列表) { 方法邏輯; return 方法返回值 } 。
調用:方法名(參數列表);
分類:無參數無返回值、無參數有返回值、有參數無返回值、有參數有返回值。
傳值:
- 基本類型:調用方值的複製,雙方各自的後續修改互不影響。方法內部對參數變數做的任何操作都不會影響方法外部的變數。
- 引用類型:調用方的變數和接收方的參數變數,記憶體地址指向同一個對象。雙方任意一方修改該參數值都會影響對方。
- 可變參數:當方法的參數列表有兩個或多個參數時,可變參數需放在末尾。
進階:
- 類作為形參和返回值:方法的形參是類,需要該類的對象。方法的返回值是類,返回該類的對象;
- 抽象類作為形參和返回值:方法的形參是抽象類,需要該抽象類子類對象。方法的返回值是抽象類,返回該抽象類的子類對象;
- 介面作為形參和返回值:方法的形參是介面,需要該介面的實現類對象。方法的返回值是介面名,返回該類的實現類對象。
三、封裝
簡介:封裝是面向對象程式語言對客觀世界的模擬,客觀世界裡成員變數都隱藏在對象內部,外界無法直接操作。
原則:將類的某些資訊隱藏在類內部,不允許外部程式直接訪問,而是通過該類提供的方法來實現對隱藏資訊的操作和訪問。
實現:
- 使用 private 訪問修飾符將對象的屬性私有化;
- 創建公開的 get / set 方法用於對屬性的讀寫;
- 在 get / set 方法中對屬性的合法性進行判斷。
private 關鍵字:
- 是一個可以修飾成員資訊的許可權修飾符;
- 被其修飾的成員只能在本類中訪問,不能被其它類使用;
- 被其修飾的成員提供公共的 get / set 方法,供其它類使用。
this 關鍵字:
- 指向當前對象的引用(誰調用我就代表誰);
- 通過
this.成員變數 | 成員方法(參數列表) | (參數列表)來訪問本類的成員變數、方法,構造方法; - 使用時必須在方法體第一行,不能在靜態方法中使用。
構造方法:
- 是一種特殊的方法,用於創建對象並完成對象的初始化;
- 格式為
public class 類名 { 修飾符 類名(參數列表) }; - 沒有自定義構造方法,系統會提供一個默認的無參構造方法,若自定義了構造方法,系統不再提供默認的無參構造方法。
四、繼承
由來:多個類中存在相同屬性和行為時,將這些相同內容抽取到一個公共類中,則其它類中無需再定義這些屬性和行為,只需繼承公共類即可。
定義:就是子類繼承父類的屬性和行為,使得子類對象具有與父類對象相同的屬性和行為,且子類可直接訪問父類的非私有屬性和行為。
格式:public class 子類名 extends 父類名 {...} 。
好處:提高程式碼的復用性,類與類之間產生了關係,是多態的前提。
特點:只支援單繼承,不支援多繼承,但支援多層繼承。
方法重寫:
- 子類必須有和父類相同的方法名、參數列表和返回類型,且該父類方法沒有被 final 或 static 修飾;
- 子類的重寫方法其訪問修飾符的限定範圍應大於等於父類方法,即 public > protected > default ;
- 子類不能重寫父類構造方法,只能通過 super(參數列表) 調用。
訪問修飾符:
- public(公共的):同類、同包、不同包的子類、不同包的非子類,均可訪問;
- protected(受保護的):同類、同包、不同包的子類,均可訪問;
- default(默認的):同類、同包,均可訪問;
- private(私有的):同類,才可訪問。
super 關鍵字:
- 代表父類存儲空間的標識,可理解為父類對象引用;
- 子類通過
super.成員變數 | 成員方法(參數列表) | (參數列表)來訪問父類的成員變數、方法,構造方法; - 使用時必須在方法體第一行。
super 和 this 的區別:
- 父類空間優先於子類對象產生,在每次創建子類對象時,先初始化父類空間再創建其子類對象本身。
目的在於子類對象中包含了其對應的父類空間便可包含其父類成員。 super.成員變數 | 成員方法(參數列表) | (參數列表)訪問的是父類的成員變數、方法,構造方法;this.成員變數 | 成員方法(參數列表) | (參數列表)訪問的是本類的成員變數、方法,構造方法;- super 和 this 不能同時使用,只能存在一個,並且都在方法體第一行。
成員訪問特點:
- 變數:子類局部範圍找 > 子類成員範圍找 > 父類成員範圍找 > 若都沒有則報錯、不考慮父類的父類。
- 方法:子類成員範圍找 > 父類成員範圍找 > 若都沒有則報錯、不考慮父類的父類。
五、多態
簡介:同一對象在不同時刻表現出不同的形態。
特點:相同的消息給予不同的對象會引發不同的動態,也就是允許不同類的對象對同一消息做出不同的響應。
實現:滿足繼承(實現)關係、要有方法重寫、父類引用指向子類對象。
訪問:成員變數(編譯看左邊,執行看左邊),成員方法(編譯看左邊,執行看右邊)。
好處:定義方法時,使用父類型作為參數,將來調用時使用具體的子類型參與操作。
弊端:不能使用子類的特有方法。
轉型:
- 向上轉型:又稱自動轉型、隱式轉型,從子到父,子類對象賦值給父類對象,就是說父類引用指向子類實例;
格式:父類名 對象名 = new 子類名();,此時該對象不能調用子類的特有方法。 - 向下轉型:又稱強制轉型,從父到子,父類對象賦值給子類對象,就是說子類引用指向父類實例;
格式:子類名 對象名 = (子類名) 父類實例;,此時該對象可以調用子類的特有方法,解決了多態的弊端。 - instanceof:返回一個布爾值來確認某個對象,是否是某個特定類或該特定類子類的一個實例,就是說左邊的對象是不是右邊類的實例;
格式:對象名 instanceof 類型,類型可以為類或介面。
六、final
簡介:final 關鍵字是最終的意思,可以修飾類、成員方法、成員變數。
修飾類:
- 被 final 修飾的類叫做最終類,不能被其它類繼承;
- 類中的所有方法都被隱式設置為 final ,但類中成員變數可以被定義為 final 或非 final ;
- 格式:
public final class 類名 {...}。
修飾方法:
- 被 final 修飾的方法叫做最終方法,不能被子類重寫;
- 格式:
訪問修飾符 final 返回值類型 方法名(參數列表) {...}。
修飾變數:
- 被 final 修飾的變數叫做常量,名稱大寫;
- 成員變數具有默認值,被 final 修飾之後不再有默認值,需手動賦值;
- 局部變數一次賦值終生不變;
- 格式:
訪問修飾符 final 數據類型 變數名(大寫) = 手動賦值。
七、static
簡介:static 關鍵字是靜態的意思,訪問修飾成員方法、成員變數。
修飾方法:
- 被 static 修飾的方法叫做靜態方法,也稱為類方法,可通過
類名.方法名直接調用; - 靜態成員方法只能訪問靜態的成員變數和方法;
- 非靜態成員方法可以訪問非靜態的成員變數和方法,也可以訪問靜態成員變數和方法。
修飾變數:
- 靜態變數:被 static 修飾的成員變數叫做靜態變數,也稱為類變數,靜態變數屬於這個類,而不是屬於這個類的對象;
靜態變數通過類名.變數名直接調用。 - 實例變數:沒被 static 修飾的成員變數叫做實例變數,實例變數屬於這個類的實例對象;
實例變數必須先 new 一個對象之後,通過對象名.變數名調用。
八、抽象類
簡介:在做子類共同功能抽取時,有些方法在父類中並沒有具體的體現,此時就需要抽象類。
格式:public abstract class 類名 {...} 。
特點:
- 抽象類和抽象方法必須使用 abstract 關鍵字修飾;
- 抽象類中不一定有抽象方法,但有抽象方法的類一定是抽象類;
- 抽象方法不能實例化,要想實例化可參照多態的方式,通過子類對象實例化,這叫做抽象類多態;
- 抽象類的子類,要麼重寫抽象類中的所有抽象方法,要麼子類也是抽象類。
內部:
- 成員變數:既可以是變數也可以是常量;
- 成員方法:既可以是普通方法也可以是抽象方法;
- 構造方法:無參有參構造方法。
注意:
- 與 abstract 不能共存的關鍵字:final 、private 、static ;
- final:被 final 修飾的類不能有子類,而被 abstract 修飾的類一定是個父類;
- private:抽象類中私有的抽象方法,不被子類所知就無法重寫,而抽象方法必須被重寫。
- static:若 static 可以修飾抽象方法,則不用 new 對象,直接類名調用即可,此時抽象方法沒有意義。
九、介面
簡介:介面就是一種公共的規範標準,只要符合規範標準,大家都可以通用。Java 中的介面更多的體現在對行為的抽象。
格式:public interface 介面名 {...} 。
特點:
- 介面用 interface 關鍵字修飾;
- 類實現介面用 implements 表示,例:
public class 類名 implements 介面名 {...}; - 介面不能實例化,要想實例化可參照多態的方式,通過子類對象實例化,這叫做介面多態;
- 介面的子類要麼重寫介面中所有抽象方法,要麼子類也是抽象類。
內部:
- 成員變數:只能是常量,默認修飾符:public static final ;
- 成員方法:只能是抽象方法,默認修飾符:public abstract ;
- 構造方法:沒有,介面主要是擴展功能而沒有具體存在的。
抽象類與介面的區別:
- 成員區別:抽象類有變數、常量、構造方法、普通方法、抽象方法,介面只有常量、抽象方法。
- 關係區別:
- 類與類的關係:繼承關係,只能單繼承,支援多層繼承;
- 類與介面的關係:實現關係,可以單實現,也支援多實現,還可以繼承一個類的同時實現多個介面;
- 介面與介面的關係:繼承關係,可以單繼承,也支援多繼承。
- 設計理念:
- 抽象類:對類抽象,包括屬性和行為;
- 介面:對行為抽象,主要對行為。
新特性:JDK8 之前,介面只有常量以及抽象方法。JDK8 時,介面增加了默認方法和靜態方法。JDK9 時,介面增加了私有方法。
默認方法:
- 格式:
default 返回值類型 方法名(參數列表) {...}; - 注意:默認方法不是抽象方法,也可以重寫,重寫時去掉 default 關鍵字;
- 作用:對介面的升級不會影響到現有程式碼。
靜態方法:
- 格式:
static 返回值類型 方法名(參數列表) {...}; - 注意:靜態方法只能通過介面名調用,不能通過實現類名或對象名調用。
私有方法:
- 格式1:
private 返回值類型 方法名(參數列表) {...}; - 格式2:
private static 返回值類型 方法名(參數列表) {...}; - 注意:默認方法可以調用私有的靜態方法和非靜態方法,靜態方法只能調用私有的靜態方法;
- 作用:提取默認方法和靜態方法中相同的程式碼,提高程式碼的復用性。
十、內部類
簡介:就是在一個類中定義一個類,例:在類 A 的內部定義類 B,類 B 就是內部類。
格式:public class 類名 { 訪問修飾符 class 類名 } 。
特點:內部類可以直接訪問外部類的成員(包括私有),外部類要訪問內部類的成員必須創建對象。
分類:
- 成員內部類:在類的成員位置,外界訪問通過
外部類名.內部類名 對象名 = new 外部類名().new 內部類名();;
但一般都是私有化的,不會讓外界直接訪問,而是通過在外部類中定義一個方法,在該方法中實例化內部類,調用內部類方法;
最終外界通過外部類的這個方法達到訪問內部類的效果。 - 局部內部類:在類的方法體中,外界無法直接訪問,需在方法體中創建對象並使用,最終外界通過該方法達到訪問局部內部類的效果;
- 匿名內部類:局部內部類的簡寫形式,前提是繼承類或實現介面,格式:
new 類名() | 介面名() { 重寫方法 };
本質上是一個繼承了該類或實現了該介面的子類匿名對象,就是說該類沒有聲名對象名。
