物件導向高階(一)
static
static是一個關鍵字,義為靜態,可以修飾成員變數和成員方法。
static修飾成員變數
成員變數的分類
- 類變數(靜態成員變數):有static修飾的成員變數,它們屬於類,在計算機裡只有一份,會被類的全部物件共享。
- 例項變數(物件成員變數):無static修飾的成員變數,屬於每個物件,每個物件都有自己的例項變數,只能用物件訪問。
static String name; //類變數
int age; //例項變數
成員變數的訪問
//類變數的訪問
類名.類變數 //推薦
物件名.類變數 //不推薦
//例項變數的訪問
對名.例項變數
類變數的應用場景
在開發中,如果某個資料只需要一份,且希望能夠被共享(訪問、修改),則該資料可以定義成類變數。
static修飾成員方法
- 類方法(靜態方法):有static修飾的成員方法,屬於類。類方法直接用類名呼叫即可,呼叫方便,也能節省記憶體。
- 例項方法(物件的方法):無static修飾的成員方法,屬於物件,只能用物件訪問。
成員方法的訪問
//類方法
類名.類方法 //推薦
物件名.類方法 //不推薦
//成員方法
物件名.例項變數
類方法的應用場景
類方法最常見的應用場景是做工具類。
工具類
- 工具類中的方法都是類方法,如java.lang.Math,每個方法都是用來完成一個功能的,工具類是給開發人員共同使用的。
- 工具類中的方法都是類方法,而不用例項方法。因為例項方法需要建立物件來呼叫,但此時物件只是為了呼叫方法,不需要例項化出物件,這樣會浪費記憶體。
- 工具類提高了程式碼的複用性,呼叫方便,提高了開發效率。
- 工具類不需要建立物件, 建議將工具類的構造器私有化。
補充:main方法
main方法是一種類方法,當程式Test啟動時,虛擬機器會執行Test.main()方法。而main方法的形參則是用來接收命令列輸入的。
static的注意事項
- 類方法中可以直接訪問類的成員,不可以直接訪問例項成員。
- 例項方法中既可以直接訪問類成員,也可以直接訪問例項成員。
- 例項方法中可以出現this關鍵字,類方法中不可以出現this關鍵字的。
程式碼塊
程式碼塊是類的5大成分之一(成員變數、構造器、方法、程式碼塊、內部類)。
程式碼塊的分類
- 靜態程式碼塊:
- 格式:static
- 特點:類載入時自動執行,由於類只會載入一次,所以靜態程式碼塊也只會執行一次。
- 作用:完成類的初始化,例如:對類變數的初始化賦值。
- 例項程式碼塊:
- 格式:
- 特點:每次建立物件時,執行例項程式碼塊,並在構造器前執行。
- 作用:和構造器一樣,都是用來完成物件的初始化的,例如:對例項變數進行初始化賦值、記錄物件建立的日誌、減少多個構造器中重複程式碼的編寫。
單例設計模式
設計模式
- 一個問題通常有n種解法,其中肯定有一種解法是最優的,這個最優的解法被人總結出來了,稱之為設計模式。
- 設計模式有20多種,對應20多種軟體開發中會遇到的問題。
單例設計模式的作用
確保一個類只有一個物件。
單例設計模式的實現方式
- 餓漢式單例:在獲取類的物件時,物件已經建立好了。
- 懶漢式單例:要用類的物件時才建立物件(延遲載入物件)。
- ...
餓漢式單例設計模式的寫法
- 把類的構造器私有。
- 定義一個類變數並賦值為自己的物件。
- 定義一個類方法,返回物件。
懶漢式單例設計模式的寫法
- 把類的構造器私有。
- 定義一個類變數用於儲存自己的物件。
- 提供一個類方法,保證返回的是同一個物件。
單例設計模式的應用場景
- 工作管理員物件、獲取執行時物件。
- 在這些業務場景下,使用單例模式,可以避免浪費記憶體。
繼承
Java中提供了一個關鍵字extends,用這個關鍵字,可以讓一個類和另一個類建立起父子關係。這個過程就叫繼承,繼承的類叫做子類(派生類),被繼承的類叫做父類(基類,超類)。
繼承的特點
-
子類能繼承父類的非私有成員(成員變數、成員方法)。
-
子類的物件是由子類和父類共同完成的。
繼承的執行原理
當一個子類物件被建立時,該子類的程式碼及其父類的程式碼會同時被載入到方法區。之後,被建立的子類物件中會儲存子類及其父類的成員變數。
繼承有什麼用
減少重複程式碼的編寫,提高程式碼的複用性。
繼承的應用場景
兩個類中存在大量的重複程式碼時,可以使這兩個類繼承同一個父類,並將重複程式碼放進父類裡。
許可權修飾符
許可權修飾符就是是用來限制類中的成員(成員變數、成員方法、構造器、程式碼塊…)能夠被訪問的範圍的關鍵字。
許可權修飾符的分類及作用
修飾符 | 本類裡 | 同一個包裡的類 | 子孫類 | 任意類 |
---|---|---|---|---|
private | 可以訪問 | 不能訪問 | 不能訪問 | 不能訪問 |
預設 | 可以訪問 | 可以訪問 | 不能訪問 | 不能訪問 |
protected | 可以訪問 | 可以訪問 | 可以訪問 | 不能訪問 |
public | 可以訪問 | 可以訪問 | 可以訪問 | 可以訪問 |
注意:許可權只看類和包,與是否是其物件無關。protected修飾的成員只能在其他包下的子類中訪問,不能由其他包下的子類的物件訪問
單繼承
Java是單繼承的,Java中的類不支援多繼承,但是支援多層繼承。
Object類
object類是java所有類的祖宗類。我們寫的任何一個類,其實都是object的子類或子孫類。
方法重寫
- 當子類覺得父類中的某個方法不好用,或者無法滿足自己的需求時,子類可以重寫一個方法名稱、引數列表一樣的方法,去覆蓋父類的這個方法,這就是方法重寫。
- 注意:重寫後,方法的訪問會遵循就近原則 。
方法重寫的注意事項
-
重寫小技巧:使用@Override註解,它可以指定java編譯器檢查我們方法重寫的格式是否正確,程式碼可讀性也會更好。
-
子類重寫父類方法時,訪問許可權必須大於或者等於父類該方法的許可權( public > protected > 預設 >private)。
-
重寫方法的返回值型別,必須與被重寫方法的返回值型別一樣,或者範圍更小。
-
私有方法、靜態方法不能被重寫。
-
方法重寫的原則:宣告不變,重新實現。
方法重寫在開發中的常見應用場景
-
當子類覺得父類的方法不好用,或者不滿足自己的需求時,就可以用方法重寫。如toString()方法。
-
IDEA可生成重寫toString()方法的骨架。
子類中訪問其他成員的特點
- 在子類方法中訪問其他成員(成員變數、成員方法)是依照就近原則的:
- 先子類區域性範圍找。
- 然後子類成員範圍找。
- 然後父類成員範圍找,如果父類範圍還沒有找到則報錯。
- 如果子父類中,出現了重名的成員,會優先使用子類的成員。如果此時一定要在子類中使用父類成員,則可以透過super關鍵字,指定訪問父類的成員,格式為:super.父類成員變數/父類成員方法。
子類構造器的特點
-
子類的全部構造器,都會先呼叫父類的構造器,再執行自己。
-
預設情況下,子類全部構造器的第一行程式碼都是 super()(寫不寫都有),它會呼叫父類的無引數構造器。
-
如果父類沒有無引數構造器,則我們必須在子類構造器的第一行手寫super(…),指定去呼叫父類的有引數構造器。
常見的應用場景
為父類這部分成員變數進行初始化賦值。
補充:this(...)呼叫兄弟構造器
任意類的構造器中,是可以透過this(…) 去呼叫該類的其他構造器
this(...)和super(…)使用時的注意事項:
this(…) 、super(…) 都必須放在構造器的第一行,因此,有了this(…)就不能寫super(…)了,反之亦然。
this和super詳情
-
this:代表本類物件的引用
-
super:代表父類儲存空間的標識。
this和super的作用
關鍵字 | 訪問成員變數 | 訪問成員方法 | 訪問構造方法 |
---|---|---|---|
this | this.成員變數訪問本類成員變數 | this.成員方法(…)訪問本類成員方法 | this(…)訪問本類構器 |
super | super.成員變數訪問父類成員變數 | super.成員方法(…)訪問父類成員方法 | super(…)訪問父類構造器 |