Java — 物件導向

北涯發表於2022-05-07

一、類和物件

簡介:類是對事物的一種描述,物件則為具體存在的事物。

類的定義:

public class 類名 {
    // 成員變數
    訪問修飾符 資料型別 變數名;
    …
    // 成員方法
    訪問修飾符 返回型別 方法名(引數列表) { 
        若干語句; 
        return 方法返回值; 
    }
    ...
}

建立物件:類名 物件名 = new 類名();

成員呼叫:物件名.成員變數;物件名.成員方法(引數列表);

二、方法

定義:訪問修飾符 返回值型別 方法名(引數列表) { 方法邏輯; return 方法返回值 }

呼叫:方法名(引數列表);

分類:無引數無返回值、無引數有返回值、有引數無返回值、有引數有返回值。

傳值:

  1. 基本型別:呼叫方值的複製,雙方各自的後續修改互不影響。方法內部對引數變數做的任何操作都不會影響方法外部的變數。
  2. 引用型別:呼叫方的變數和接收方的引數變數,記憶體地址指向同一個物件。雙方任意一方修改該引數值都會影響對方。
  3. 可變引數:當方法的引數列表有兩個或多個引數時,可變引數需放在末尾。

進階:

  1. 類作為形參和返回值:方法的形參是類,需要該類的物件。方法的返回值是類,返回該類的物件;
  2. 抽象類作為形參和返回值:方法的形參是抽象類,需要該抽象類子類物件。方法的返回值是抽象類,返回該抽象類的子類物件;
  3. 介面作為形參和返回值:方法的形參是介面,需要該介面的實現類物件。方法的返回值是介面名,返回該類的實現類物件。

三、封裝

簡介:封裝是物件導向程式語言對客觀世界的模擬,客觀世界裡成員變數都隱藏在物件內部,外界無法直接操作。

原則:將類的某些資訊隱藏在類內部,不允許外部程式直接訪問,而是通過該類提供的方法來實現對隱藏資訊的操作和訪問。

實現:

  1. 使用 private 訪問修飾符將物件的屬性私有化;
  2. 建立公開的 get / set 方法用於對屬性的讀寫;
  3. 在 get / set 方法中對屬性的合法性進行判斷。

private 關鍵字:

  1. 是一個可以修飾成員資訊的許可權修飾符;
  2. 被其修飾的成員只能在本類中訪問,不能被其它類使用;
  3. 被其修飾的成員提供公共的 get / set 方法,供其它類使用。

this 關鍵字:

  1. 指向當前物件的引用(誰呼叫我就代表誰);
  2. 通過 this.成員變數 | 成員方法(引數列表) | (引數列表) 來訪問本類的成員變數、方法,構造方法;
  3. 使用時必須在方法體第一行,不能在靜態方法中使用。

構造方法:

  1. 是一種特殊的方法,用於建立物件並完成物件的初始化;
  2. 格式為 public class 類名 { 修飾符 類名(引數列表) }
  3. 沒有自定義構造方法,系統會提供一個預設的無參構造方法,若自定義了構造方法,系統不再提供預設的無參構造方法。

四、繼承

由來:多個類中存在相同屬性和行為時,將這些相同內容抽取到一個公共類中,則其它類中無需再定義這些屬性和行為,只需繼承公共類即可。

定義:就是子類繼承父類的屬性和行為,使得子類物件具有與父類物件相同的屬性和行為,且子類可直接訪問父類的非私有屬性和行為。

格式:public class 子類名 extends 父類名 {...}

好處:提高程式碼的複用性,類與類之間產生了關係,是多型的前提。

特點:只支援單繼承,不支援多繼承,但支援多層繼承。

方法重寫:

  1. 子類必須有和父類相同的方法名、引數列表和返回型別,且該父類方法沒有被 final 或 static 修飾;
  2. 子類的重寫方法其訪問修飾符的限定範圍應大於等於父類方法,即 public > protected > default ;
  3. 子類不能重寫父類構造方法,只能通過 super(引數列表) 呼叫。

訪問修飾符:

  1. public(公共的):同類、同包、不同包的子類、不同包的非子類,均可訪問;
  2. protected(受保護的):同類、同包、不同包的子類,均可訪問;
  3. default(預設的):同類、同包,均可訪問;
  4. private(私有的):同類,才可訪問。

super 關鍵字:

  1. 代表父類儲存空間的標識,可理解為父類物件引用;
  2. 子類通過 super.成員變數 | 成員方法(引數列表) | (引數列表) 來訪問父類的成員變數、方法,構造方法;
  3. 使用時必須在方法體第一行。

super 和 this 的區別:

  1. 父類空間優先於子類物件產生,在每次建立子類物件時,先初始化父類空間再建立其子類物件本身。
    目的在於子類物件中包含了其對應的父類空間便可包含其父類成員。
  2. super.成員變數 | 成員方法(引數列表) | (引數列表) 訪問的是父類的成員變數、方法,構造方法;
  3. this.成員變數 | 成員方法(引數列表) | (引數列表) 訪問的是本類的成員變數、方法,構造方法;
  4. super 和 this 不能同時使用,只能存在一個,並且都在方法體第一行。

成員訪問特點:

  1. 變數:子類區域性範圍找 > 子類成員範圍找 > 父類成員範圍找 > 若都沒有則報錯、不考慮父類的父類。
  2. 方法:子類成員範圍找 > 父類成員範圍找 > 若都沒有則報錯、不考慮父類的父類。

五、多型

簡介:同一物件在不同時刻表現出不同的形態。

特點:相同的訊息給予不同的物件會引發不同的動態,也就是允許不同類的物件對同一訊息做出不同的響應。

實現:滿足繼承(實現)關係、要有方法重寫、父類引用指向子類物件。

訪問:成員變數(編譯看左邊,執行看左邊),成員方法(編譯看左邊,執行看右邊)。

好處:定義方法時,使用父型別作為引數,將來呼叫時使用具體的子型別參與操作。

弊端:不能使用子類的特有方法。

轉型:

  1. 向上轉型:又稱自動轉型、隱式轉型,從子到父,子類物件賦值給父類物件,就是說父類引用指向子類例項;
    格式:父類名 物件名 = new 子類名(); ,此時該物件不能呼叫子類的特有方法。
  2. 向下轉型:又稱強制轉型,從父到子,父類物件賦值給子類物件,就是說子類引用指向父類例項;
    格式:子類名 物件名 = (子類名) 父類例項; ,此時該物件可以呼叫子類的特有方法,解決了多型的弊端。
  3. instanceof:返回一個布林值來確認某個物件,是否是某個特定類或該特定類子類的一個例項,就是說左邊的物件是不是右邊類的例項;
    格式:物件名 instanceof 型別 ,型別可以為類或介面。

六、final

簡介:final 關鍵字是最終的意思,可以修飾類、成員方法、成員變數。

修飾類:

  1. 被 final 修飾的類叫做最終類,不能被其它類繼承;
  2. 類中的所有方法都被隱式設定為 final ,但類中成員變數可以被定義為 final 或非 final ;
  3. 格式:public final class 類名 {...}

修飾方法:

  1. 被 final 修飾的方法叫做最終方法,不能被子類重寫;
  2. 格式:訪問修飾符 final 返回值型別 方法名(引數列表) {...}

修飾變數:

  1. 被 final 修飾的變數叫做常量,名稱大寫;
  2. 成員變數具有預設值,被 final 修飾之後不再有預設值,需手動賦值;
  3. 區域性變數一次賦值終生不變;
  4. 格式:訪問修飾符 final 資料型別 變數名(大寫) = 手動賦值

七、static

簡介:static 關鍵字是靜態的意思,訪問修飾成員方法、成員變數。

修飾方法:

  1. 被 static 修飾的方法叫做靜態方法,也稱為類方法,可通過 類名.方法名 直接呼叫;
  2. 靜態成員方法只能訪問靜態的成員變數和方法;
  3. 非靜態成員方法可以訪問非靜態的成員變數和方法,也可以訪問靜態成員變數和方法。

修飾變數:

  1. 靜態變數:被 static 修飾的成員變數叫做靜態變數,也稱為類變數,靜態變數屬於這個類,而不是屬於這個類的物件;
    靜態變數通過 類名.變數名 直接呼叫。
  2. 例項變數:沒被 static 修飾的成員變數叫做例項變數,例項變數屬於這個類的例項物件;
    例項變數必須先 new 一個物件之後,通過 物件名.變數名 呼叫。

八、抽象類

簡介:在做子類共同功能抽取時,有些方法在父類中並沒有具體的體現,此時就需要抽象類。

格式:public abstract class 類名 {...}

特點:

  1. 抽象類和抽象方法必須使用 abstract 關鍵字修飾;
  2. 抽象類中不一定有抽象方法,但有抽象方法的類一定是抽象類;
  3. 抽象方法不能例項化,要想例項化可參照多型的方式,通過子類物件例項化,這叫做抽象類多型;
  4. 抽象類的子類,要麼重寫抽象類中的所有抽象方法,要麼子類也是抽象類。

內部:

  1. 成員變數:既可以是變數也可以是常量;
  2. 成員方法:既可以是普通方法也可以是抽象方法;
  3. 構造方法:無參有參構造方法。

注意:

  1. 與 abstract 不能共存的關鍵字:final 、private 、static ;
  2. final:被 final 修飾的類不能有子類,而被 abstract 修飾的類一定是個父類;
  3. private:抽象類中私有的抽象方法,不被子類所知就無法重寫,而抽象方法必須被重寫。
  4. static:若 static 可以修飾抽象方法,則不用 new 物件,直接類名呼叫即可,此時抽象方法沒有意義。

九、介面

簡介:介面就是一種公共的規範標準,只要符合規範標準,大家都可以通用。Java 中的介面更多的體現在對行為的抽象。

格式:public interface 介面名 {...}

特點:

  1. 介面用 interface 關鍵字修飾;
  2. 類實現介面用 implements 表示,例:public class 類名 implements 介面名 {...}
  3. 介面不能例項化,要想例項化可參照多型的方式,通過子類物件例項化,這叫做介面多型;
  4. 介面的子類要麼重寫介面中所有抽象方法,要麼子類也是抽象類。

內部:

  1. 成員變數:只能是常量,預設修飾符:public static final ;
  2. 成員方法:只能是抽象方法,預設修飾符:public abstract ;
  3. 構造方法:沒有,介面主要是擴充套件功能而沒有具體存在的。

抽象類與介面的區別:

  1. 成員區別:抽象類有變數、常量、構造方法、普通方法、抽象方法,介面只有常量、抽象方法。
  2. 關係區別:
    1. 類與類的關係:繼承關係,只能單繼承,支援多層繼承;
    2. 類與介面的關係:實現關係,可以單實現,也支援多實現,還可以繼承一個類的同時實現多個介面;
    3. 介面與介面的關係:繼承關係,可以單繼承,也支援多繼承。
  3. 設計理念:
    1. 抽象類:對類抽象,包括屬性和行為;
    2. 介面:對行為抽象,主要對行為。

新特性:JDK8 之前,介面只有常量以及抽象方法。JDK8 時,介面增加了預設方法和靜態方法。JDK9 時,介面增加了私有方法。

預設方法:

  1. 格式:default 返回值型別 方法名(引數列表) {...}
  2. 注意:預設方法不是抽象方法,也可以重寫,重寫時去掉 default 關鍵字;
  3. 作用:對介面的升級不會影響到現有程式碼。

靜態方法:

  1. 格式:static 返回值型別 方法名(引數列表) {...} ;
  2. 注意:靜態方法只能通過介面名呼叫,不能通過實現類名或物件名呼叫。

私有方法:

  1. 格式1:private 返回值型別 方法名(引數列表) {...}
  2. 格式2:private static 返回值型別 方法名(引數列表) {...}
  3. 注意:預設方法可以呼叫私有的靜態方法和非靜態方法,靜態方法只能呼叫私有的靜態方法;
  4. 作用:提取預設方法和靜態方法中相同的程式碼,提高程式碼的複用性。

十、內部類

簡介:就是在一個類中定義一個類,例:在類 A 的內部定義類 B,類 B 就是內部類。

格式:public class 類名 { 訪問修飾符 class 類名 }

特點:內部類可以直接訪問外部類的成員(包括私有),外部類要訪問內部類的成員必須建立物件。

分類:

  1. 成員內部類:在類的成員位置,外界訪問通過 外部類名.內部類名 物件名 = new 外部類名().new 內部類名();
    但一般都是私有化的,不會讓外界直接訪問,而是通過在外部類中定義一個方法,在該方法中例項化內部類,呼叫內部類方法;
    最終外界通過外部類的這個方法達到訪問內部類的效果。
  2. 區域性內部類:在類的方法體中,外界無法直接訪問,需在方法體中建立物件並使用,最終外界通過該方法達到訪問區域性內部類的效果;
  3. 匿名內部類:區域性內部類的簡寫形式,前提是繼承類或實現介面,格式:new 類名() | 介面名() { 重寫方法 }
    本質上是一個繼承了該類或實現了該介面的子類匿名物件,就是說該類沒有聲名物件名。

相關文章