1. 程式人生 > >Java-面向物件基礎知識

Java-面向物件基礎知識

1. 方法、引數

  • 傳遞引數時通過值傳遞,就是傳遞實際引數的副本,並不會傳遞物件本身
  • 傳遞物件例項的形式的引數時,會將形參的引用指向實參所指向的堆記憶體,修改形參會影響到實參的值,但不會影響實參本身
  • 在傳遞引數的時候在最後一個形參型別後加…表示該形參可以接受多個引數值;作用和傳遞資料相同,但是隻能位於形參列表的最後且只能有一個
//foreach迴圈,引數個數可變,類似於陣列
public static void test(int a, String... books) {
        for (String book : books) {
            System.out
.println(book); } } public static void main(String[] args) { test(1, "第一個引數"); test(2, "第一個引數", "第二個引數"); }

2. 構造方法

  • 構造方法可以過載(overload),可以通過this()方法呼叫其他構造方法,具體呼叫那個構造方法根據引數自動選擇
  • 通過new建立子類例項時會先呼叫父類的構造方法,如果父類的構造方法呼叫了其他在子類中被重寫的方法,則會呼叫子類中被重寫的方法
  • 建立任何物件總是從該類所在繼承樹最頂層的構造器開始執行,然後依次向下執行,最後才執行本類的構造方法;
  • 如果某個父類通過this呼叫了同類中過載的構造器,就會依次執行此父類的多個構造器。
  • 沒有宣告時自動提供無參構造器,當寫了構造器之後不再提供

3. 繼承

  • 子類通過extends關鍵字繼承父類
  • 子類只能繼承一個父類,即每個類只能一有一個直接父類
  • 使用super關鍵字呼叫父類中被重寫(覆蓋override)的方法 super.method();
  • super不能出現在static修飾的方法中
  • 使用super()呼叫父類的構造方法
  • 子類例項化時先載入父類並呼叫父類的構造器,再呼叫子類的構造器

4. 多型

  • 用父類宣告物件,用子類例項化的物件,只能呼叫父類的變數,如果方法在子類中重寫,則呼叫子類的方法,如果沒有就呼叫父類的方法,無法呼叫子類新加的方法

5. 強制型別轉換

  • 父類物件賦給子類引用變數時需要進行強制型別轉換
  • 把子類物件賦給父類引用變數時,被稱為上轉型,這種轉型總是可以成功的
  • instanceof 前面的運算子通常是一個引用型別變數,後面的運算元通常是一個類,介面,用於判斷前面的物件是否是後面的類,或者其子類,實現類的例項,如果是返回true,不是返回false,如果前面和後面的引數沒有繼承關係則無法編譯

6. 初始化塊

  • 初始化塊先於構造方法執行,多個初始化塊根據定義順序執行
  • 初始化塊只有在建立Java物件時隱身執行
  • 靜態初始化塊總是先於普通初始化塊執行
  • 初始化塊執行時從其根父類的初始化塊開始執行知道執行該類的初始化塊

7. 抽象類

  • 抽象類不能用於建立是例項,只能當做父類被其他子類繼承
  • 抽象方法的類只能定義為抽象類,抽象類可以沒有抽象方法
  • 抽象方法沒有方法體
  • 抽象類不能例項化,但可以有構造器,用於子類例項化時呼叫
  • abstract不能修飾構造方法
  • abstract和static不能同時修飾某個方法
  • abstract不能修飾成員變數
  • abstract和static可以同時修飾內部類
  • private和abstract不能同時修飾方法

8. 介面

  • 一個介面可以 有多個直接父介面,但介面只能繼承介面不能繼承類
  • 介面中的預設方法必須用default修飾,該方法不能使用static修飾,預設方法總是使用public修飾,需要使用介面的實現類的例項來呼叫這些預設方法
  • 類方法必須使用static修飾,該方法不能使用default修飾
  • 介面的實現類可以不用重寫介面的類方法和預設方法
  • 一個類繼承父類並且實現介面時,implements部分必須放在extends部分之後
  • 一個類實現了一個或多個介面之後就必須完全實現這些接口裡所定義的全部抽象方法

9. 介面和抽象類

  • 共同點:
    • 都不能被例項化
    • 都位於繼承樹的頂端,用於被其他類實現和繼承
    • 都可以包含抽象方法,實現介面或繼承抽象類的普通子類都必須實現這些抽象方法
  • 不同點:
    • 接口裡只能包含抽象方法、靜態方法和預設方法,不能為普通方法提供實現;抽象類則可以包含普通方法
    • 接口裡只能定義靜態常量,不能定義普通成員變數;抽象類裡可以定義普通成員變數和靜態常量
    • 介面不包含構造器;抽象類可以包含構造器,用於子類呼叫構造器完成屬於抽象類的初始化操作
    • 介面不能包含初始化塊,抽象類可以

10. 內部類

  • 通過OutterClass.this.propName訪問外部類的例項變數,通過this.propName訪問非靜態內部類的例項變數
  • 訪問變數順序依次是區域性變數,內部類變數,外部類變數
  • 建立非靜態內部類物件: Out.In in = new Out().new In(); 建立靜態內部類物件: StaticOut.StaticIn in = new StaticOut.StaticIn();
  • 建立內部類物件時,靜態內部類只需要使用外部類即可呼叫構造器,而非靜態內部類必須使用外部類物件來呼叫構造器

11. 區域性內部類

  • 區域性內部類僅在該方法內部有效,不能在外部類的方法以外的地方使用,因此區域性內部類也不能使用訪問控制符和static修飾
  • 所欲區域性成員都不能使用訪問控制符修飾

12. 匿名內部類

  • 匿名內部類不能重複使用
  • 匿名抽象類不能是抽象類
  • 匿名內部類不能定義構造器,但可以定義初始化塊
  • 系統建立匿名內部類時會立即建立匿名內部類的物件
  • 定義匿名內部類無需class關鍵字
  • 匿名內部類必須實現他的抽象父類或者接口裡包含的所有抽象方法
  • 通過實現介面建立匿名內部類是,只有一個隱式的無參構造器,所以new介面後的括號裡不能傳入引數值
  • 通過實現抽象類建立匿名內部類可以呼叫含參的構造方法,可以重寫父類的普通方法

13. Lambda表示式

  • Lambda表示式支援將程式碼塊作為引數
  • Lambda表示式不需要指出重寫方法的名字,不需要給出重寫方法的返回值型別,只要給出重寫方法括號以及括號裡的形參列表即可
  • Lanmda表示式就相當於一個匿名方法
  • 形參列表允許省略形參型別
  • 如果程式碼塊僅包含一條語句,允許省略程式碼塊的花括號
  • 如果程式碼塊僅有一條return語句,可以省略return關鍵字
  • 如果表示式形參列表只有一個形參,可以省略圓括號
  • 匿名內部類和lambda表示式共同點:
    • Lambda表示式與匿名內部類都可以訪問區域性變數和外部類的成員變數
    • 都可以直接呼叫從介面中繼承的預設方法
  • 匿名內部類和lambda表示式不同點:
    • 匿名內部類可以可以為任意介面或抽象類甚至普通類建立例項,Lambda表示式只能為函式式介面建立例項
    • 匿名內部類實現的抽象方法的方法體允許呼叫介面中定義的預設方法,Lambda表示式不行

14. 列舉類

  • 列舉類構造器只能使用private修飾
  • 列舉類的所有例項必須在列舉類的第一行列出
  • 列舉類不能派生子類
  • 列舉類預設繼承java.lang.Enum

15. Main方法

  • main方法args引數由JVM賦值
  • JVM直接通過該類來呼叫main方法,所有使用static修飾