1. 程式人生 > 其它 >6、面向物件程式設計(中)

6、面向物件程式設計(中)

關鍵字:static(靜態)

作用範圍

可以用來修飾的結構:主要用來修飾類的內部結構

屬性、方法、程式碼塊、內部類

static修飾屬性:

靜態變數(或類變數)

靜態屬性 vs 非靜態屬性:

屬性,是否使用static修飾,又分為:靜態屬性 vs 非靜態屬性(例項變數)

  • 例項變數:我們建立了類的多個物件,每個物件都獨立的擁一套類中的非靜態屬性。當修改其中一個物件中的非靜態屬性時,不會導致其他物件中同樣的屬性值的修改。

  • 靜態變數:我們建立了類的多個物件,多個物件共享同一個靜態變數。當通過某一個物件修改靜態變數時,會導致其他物件呼叫此靜態變數時,是修改過了的。

static修飾屬性的其他說明:

① 靜態變數隨著類的載入而載入。可以通過"類.靜態變數"的方式進行呼叫

② 靜態變數的載入要早於物件的建立。

③ 由於類只會載入一次,則靜態變數在記憶體中也只會存在一份:存在方法區的靜態域中

記憶體解析:

static修飾方法:

① 隨著類的載入而載入,可以通過"類.靜態方法"的方式進行呼叫

② 靜態方法中,只能呼叫靜態的方法或屬性

 非靜態方法中,既可以呼叫非靜態的方法或屬性,也可以呼叫靜態的方法或屬性

static修飾程式碼塊:

靜態程式碼塊:

>內部可以輸出語句

>隨著類的載入而執行,而且只執行一次

>作用:初始化類的資訊

>如果一個類中定義了多個靜態程式碼塊,則按照宣告的先後順序執行

>靜態程式碼塊的執行要優先於非靜態程式碼塊的執行

>靜態程式碼塊內只能呼叫靜態的屬性、靜態的方法,不能呼叫非靜態的結構

非靜態程式碼塊:

>內部可以輸出語句

>隨著物件的建立而執行

>每建立一個物件,就執行一次非靜態程式碼塊

>作用:可以在建立物件時,對物件的屬性等進行初始化

>如果一個類中定義了多個非靜態程式碼塊,則按照宣告的先後順序執行

>非靜態程式碼塊內可以呼叫靜態的屬性、靜態的方法,或非靜態的屬性、非靜態的方法

static的注意點:

在靜態的方法內,不能使用this關鍵字、super關鍵字

什麼時候使用static

屬性:

  • 屬性是可以被多個物件所共享的,不會隨著物件的不同而不同的。

  • 類中的常量也常常宣告為static

方法:

  • 操作靜態屬性的方法,通常設定為static的

  • 工具類中的方法,習慣上宣告為static的。 比如:Math、Arrays、Collections

main方法

  1. 作為程式的入口出現

  2. main()方法也是一個普通的靜態方法

  3. main()方法可以作為我們與控制檯互動的方式。(之前:使用Scanner)

面向物件特徵二:繼承性

extends:延展、擴充套件

格式:

class A extends B{}

  • A:子類、派生類、subclass

  • B:父類、超類、基類、superclass

子類繼承父類以後有哪些不同?

  • 體現:一旦子類A繼承父類B以後,子類A中就獲取了父類B中宣告的所有的屬性和方法。

  • 特別的,父類中宣告為private的屬性或方法,子類繼承父類以後,仍然認為獲取了父類中私有的結構。只因為封裝性的影響,使得子類不能直接呼叫父類的結構而已。

  • 子類繼承父類以後,還可以宣告自己特有的屬性或方法:實現功能的拓展。

  • 子類和父類的關係,不同於子集和集合的關係。

Java中繼承性的說明

  1. 一個類可以被多個子類繼承。

  2. Java中類的單繼承性:一個類只能有一個父類

  3. 子父類是相對的概念。

  4. 子類直接繼承的父類,稱為:直接父類。間接繼承的父類稱為:間接父類

  5. 子類繼承父類以後,就獲取了直接父類以及所間接父類中宣告的屬性和方法

方法重寫:

override 或 overwrite

子類繼承父類以後,可以對父類中同名同參數的方法,進行覆蓋操作

重寫以後,當建立子類物件以後,通過子類物件呼叫子父類中的同名同參數的方法時,實際執行的是子類重寫父類的方法。

例如

class Circle{
	public double findArea(){}//求面積
}
class Cylinder extends Circle{
	public double findArea(){}//求表面積
}
**************************************
class Account{
	public boolean withdraw(double amt){}
}
class CheckAccount extends Account{
	public boolean withdraw(double amt){}
}

重寫的規則:

許可權修飾符  返回值型別  方法名(形參列表)  throws  異常的型別{

                  //方法體

}

約定俗稱:子類中的叫重寫的方法,父類中的叫被重寫的方法

① 子類重寫的方法的方法名和形參列表與父類被重寫的方法的方法名和形參列表相同

② 子類重寫的方法的許可權修飾符不小於父類被重寫的方法的許可權修飾符

  • 特殊情況:子類不能重寫父類中宣告為private、static、final的方法

③ 返回值型別:

  • 父類被重寫的方法的返回值型別是void,則子類重寫的方法的返回值型別只能是void

  • 父類被重寫的方法的返回值型別是A型別,則子類重寫的方法的返回值型別可以是A類或A類的子類

  • 父類被重寫的方法的返回值型別是基本資料型別(比如:double),則子類重寫的方法的返回值型別必須是相同的基本資料型別(必須也是double)

④ 子類重寫的方法丟擲的異常型別不大於父類被重寫的方法丟擲的異常型別

super關鍵字

super 關鍵字可以理解為:父類的

可以用來呼叫的結構:屬性、方法、構造器

super呼叫屬性、方法:

  • 我們可以在子類的方法或構造器中。通過使用"super.屬性"或"super.方法"的方式,顯式的呼叫父類中宣告的屬性或方法。但是,通常情況下,我們習慣省略"super."

  • 特殊情況:當子類和父類中定義了同名的屬性時,我們要想在子類中呼叫父類中宣告的屬性,則必須顯式的使用"super.屬性"的方式,表明呼叫的是父類中宣告的屬性。

  • 特殊情況:當子類重寫了父類中的方法以後,我們想在子類的方法中呼叫父類中被重寫的方法時,則必須顯式的使用"super.方法"的方式,表明呼叫的是父類中被重寫的方法。

super呼叫構造器:

  • 我們可以在子類的構造器中顯式的使用"super(形參列表)"的方式,呼叫父類中宣告的指定的構造器

  • "super(形參列表)"的使用,必須宣告在子類構造器的首行!

  • 我們在類的構造器中,針對於"this(形參列表)"或"super(形參列表)"只能二一,不能同時出現

  • 在構造器的首行,沒顯式的宣告"this(形參列表)"或"super(形參列表)",則預設呼叫的是父類中空參的構造器:super()

  • 在類的多個構造器中,至少一個類的構造器中使用了"super(形參列表)",呼叫父類中的構造器

類的初始化順序:

  1. 載入父類(給父類的靜態屬性開闢空間、賦預設值、賦初始值,執行靜態塊)

  2. 載入子類(給子類的靜態屬性開闢空間、賦預設值、賦初始值,執行靜態塊)

以下是在建立子類物件的時候才會發生:

  1. 對父類中定義的非靜態屬性分配空間,賦預設值,做初始化(執行父類中定義的初始化塊,執行父類的構造方法)

注意:預設執行的是父類的無引數的構造方法,如果在子類中使用super顯示的呼叫了父類的其他構造方法,無參的就不會再次被呼叫

  1. 對子類中定義的非靜態屬性進行初始化(執行子類中定義的初始化塊,執行子類中定義的構造方法,建立子類物件)

關鍵字:abstract(抽象的)

可以用來修飾:類、方法

不可以和private、static、final、一起使用,不可以修飾構造器

abstract修飾類:抽象類

  • 此類不能例項化

  • 抽象類中一定有構造器,便於子類例項化時呼叫(涉及:子類物件例項化的全過程)

  • 開發中,都會提供抽象類的子類,讓子類物件例項化,完成相關的操作
    --->抽象的使用前提:繼承性

abstract修飾方法:抽象方法

  • 抽象方法只方法的宣告,沒方法體

  • 包含抽象方法的類,一定是一個抽象類。反之,抽象類中可以沒有抽象方法的。

  • 若子類重寫了父類中的所的抽象方法後,此子類方可例項化

  • 若子類沒重寫父類中的所的抽象方法,則此子類也是一個抽象類,需要使用abstract修飾

面向物件特徵三:多型性

可以理解為一個事物的多種形態。

物件的多型性:父類的引用指向子類的物件(或子類的物件賦給父類的引用)

多型性的使用:虛擬方法呼叫

  • 有了物件的多型性以後,我們在編譯期,只能呼叫父類中宣告的方法,但在執行期,我們實際執行的是子類重寫父類的方法。

  • 總結:編譯,看左邊;執行,看右邊。

物件的多型性,只適用於方法,不適用於屬性(編譯和執行都看左邊)

向上轉型:

多型性

向下轉型:

為什麼使用向下轉型:

  • 有了物件的多型性以後,記憶體中實際上是載入了子類特有的屬性和方法的,但是由於變數宣告為父類型別,導致編譯時,只能呼叫父類中宣告的屬性和方法。子類特有的屬性和方法不能呼叫。如何才能呼叫子類特的屬性和方法?使用向下轉型。

如何實現向下轉型:

  • 使用強制型別轉換符:()

使用時的注意點:

  • 使用強轉時,可能出現ClassCastException的異常。

  • 為了避免在向下轉型時出現ClassCastException的異常,我們在向下轉型之前,先進行instanceof的判斷,一旦返回true,就進行向下轉型。如果返回false,不進行向下轉型。

instanceof 的使用:

  • a instanceof A :
    判斷物件a是否是類A的例項。如果是,返回true;如果不是,返回false。

  • 類B是類A的父類:a instanceof A返回true,a instanceof B也返回true