1. 程式人生 > >Java基礎——面向物件(二)繼承

Java基礎——面向物件(二)繼承

一、繼承概述

1.使用extends關鍵字

繼承後子類可以使用父類成員

2.繼承的好處

  • 提高程式碼的複用性
  • 讓類與類之間產生了關係,給第三個特徵多型提供了前提

3.Java中繼承的特點 

Java中支援單機城。不直接支援多繼承,但對C++中的多繼承機制進行改良。

思考:為什麼Java要對多繼承機制進行改良?

這個問題也就是多繼承機制有哪些缺點?簡單來看,繼承過程中產生的多個父類中如果具有相同的成員,會產生呼叫不確定性。因此在Java中是通過“多實現”的方式來體現,即多重繼承。

當要使用一個繼承體系時:

1.檢視該體系中的頂層類,瞭解該體系的基本功能。

2.建立體系中的最子類物件,完成功能的使用。

 二、定義繼承

1.什麼時候定義繼承?

當類與類之間存在著所屬關係的時候,就定義繼承。如果xxx是yyy中的一種->xxx extends yyy

2.子父類中成員變數的特點

aaa) 成員變數

  • 子類中有父類的相同名稱的變數,那麼直接呼叫時呼叫的是字類中的變數。當需要區分時,用super關鍵字區分父類。
  • 子類不能直接訪問父類中的私有內容(private所修飾),但可以通過get(); set();實現。 

super關鍵字:super.父類成員,用法和this很相像。

和this區別:

  • this代表一個本類物件的引用。
  • super代表一個父類空間。

bbb) 成員函式

當子父類中成員函式一模一樣時,會執行子類的函式。這種現象稱為覆蓋操作。這是函式在子父類中的特性。當然也可以super

覆蓋:

函式有兩個特性:

  1. 過載,同一個類中
  2. 覆蓋,自類中。覆蓋也稱重寫,覆寫,override。

覆蓋的注意事項:

  1. 子類方法覆蓋父類方法時,子類許可權必須大於等於父類許可權——許可權只能放大
  2. 靜態只能覆蓋靜態,或被靜態覆蓋——同非同靜

 

思考:什麼時候使用覆蓋操作?

當對一個類進行子類的擴充套件時,子類需要保留父類的功能宣告,但是要定義子類中該功能的特有內容時,就使用覆蓋操作完成。

ccc) 建構函式

在子類構造物件時,發現,訪問子類建構函式時,父類也運行了,為什麼?

在子類的建構函式中第一行有一個預設的隱式語句--->super(); 


3.子類的例項化過程:

自類中所有的建構函式預設都會訪問父類中的空引數建構函式。

為什麼子類例項化的時候要訪問父類中的建構函式呢?

  • 因為子類繼承了父類,獲取到了父類中的內容(屬性),所以在使用父類之前,要先看弗雷是如何對自己的內容進行初始化的。
  • 如果父類中沒有定義空引數建構函式,那麼子類建構函式必須用super明確要呼叫父類哪個建構函式。

注意:super語句必須要定義在子類建構函式的第一行。因為父類的初始化動作要先完成。但是,如果有了this()呼叫本類建構函式,預設的super就沒有了,但是一定有一處預設呼叫super()。

一個物件例項化過程:

Person p = new Person();

  1. JVM會讀取指定的路徑下的Person.class檔案,並載入進記憶體,並會先加在Person的父類(如果有直接父類的情況下)。
  2. 在堆記憶體中開闢空間,分配地址。
  3. 並在物件空間中,對物件中的屬性進行預設初始化。
  4. 呼叫對應的建構函式進行初始化。
  5. 在建構函式中,第一行會先呼叫父類中建構函式進行初始化。
  6. 父類初始化完畢後,再對子類的屬性進行顯示初始化。
  7. 在進行子類建構函式的特定初始化。
  8. 初始化完畢後,將地址賦值給引用變數

 三、final關鍵字

  1. final是一個修飾符,可以修飾類、方法、變數
  2. final修飾的類不可以被繼承。
  3. final修飾的方法不可以被覆蓋。
  4. final修飾的變數是一個常量,只能賦值一次。

思考:為什麼要用final修飾變數?

其實在程式中如果一個數據是固定的,那麼直接使用這個資料就可以了,但是這樣閱讀性差,所以給該資料起個名稱。而且這個變數名稱的值不能變化,所以加上final固定。

寫法規範:常量所有字母都大寫,多個單詞,中間用_連線。