1. 程式人生 > >黑馬程式設計師----Java基礎之面向物件(封裝 繼承 多型)

黑馬程式設計師----Java基礎之面向物件(封裝 繼承 多型)

------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ---------

封裝(Excapsulation)

封裝:是指隱藏物件的屬性和實現細節,僅對外提供公共的訪問方式

好處:

將變化隔離

便於使用

提高重用性

提高安全性

封裝原則

將不需要對外提供的內容都隱藏起來

把屬性都隱藏,提供公共方法對其訪問

這時就不得不介紹一個關鍵字:private

private:私有  許可權修飾符:  用於修飾類中的成員(成員變數,成員函式)

被私有修飾的成員只在本類中有效,被private修飾後,類以外即使建立了物件也不能直接訪問,所以就需要在本類中提供對應的訪問該成員的方式

注意:私有僅僅是封裝的一種表現形式

之所以對提供訪問方式,就是因為可以在訪問方式中加入邏輯判斷等語句.對訪問的資料進行操作.提高程式碼的健壯性

擴充套件小知識:

設計模式:解決某一類問題最行之有效的方法:

Java中有23中設計模式

現在就只說一種:單例設計模式

單例設計模式:解決一個類在記憶體只存在一個物件

要保證物件唯一

1.  為了避免其他程式過多建立該物件.先禁止其他程式建立該物件

2.  還為了讓其他程式可以訪問到該類物件,只好在本類中,自定義一個物件.

3.  為了方便其他程式對自定義物件的訪問,可以對外提供一些訪問方式

將上述三步用程式碼體現出來

1.  將建構函式私有化

2.  在類中建立一個本類物件

3.  提供一個方法可以獲取到該物件

單例設計模式的應用:保證學生物件的唯一性



單例設計模式的兩種表現形式

一種是餓漢式:先初始化物件

class Single
{

private Single(){}


private static Single s = new Single();


public static Single getSingle()
{
return s;
}
}

還有一種是餓漢式:   物件是方法呼叫時,才初始化,也叫做物件的延時載入

class Single
{
private Single(){}


private static Single s = null;


public static Single getSingle()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
{
s = new Single();
}
}
}

return s;
}
}

繼承

1.  提高了程式碼的複用性.

2.  讓類與類之間產生了關係.有了這個關係,才有了多型的特性

注意:千萬不要為了獲取其它類的功能,簡化程式碼而繼承

必須是類與類之間有所屬關係才可以繼承

JAVA語言中只支援單繼承,不支援多繼承

因為多繼承存在安全隱患:當多個父類中定義了相同功能,檔功能內容不同時,子類物件不確定要執行哪一個.但是Java保留這種機制,並用另一種體現形式來完成表示.多實現

Java支援多層繼承.也就是一個繼承體系

class A
{
}
class B extends A
{
}
class C extend B
{
}

如何使用一個繼承體系中的功能呢?

想要使用體系,先查閱體系父類的描述,因為父類中定義的是該體系中共性功能.

通過了解共性功能,就可以知道該體系的基本功能啦.那麼這個體系已經可以基本呼叫啦

那麼具體呼叫時,要建立子類的物件,為什麼呢?

一是因為有可能父類不能建立物件

二是建立子類物件可以使用更多的功能,包括基本的也包括特有的.

簡單一句話就是查閱父類功能,建立子類物件使用功能

子父類出現後,類中成員的特點

變數:如果子父類中出現了非私有的同名成員變數時,子類要訪問本類中的變數,用this,  子類要訪問父類中的成員變數,用super

super的使用和this的使用幾乎一致.

this代表的是本類物件的引用

super代表的是父類物件的引用

當子類中出現和父類一模一樣的函式是;

當系類物件呼叫該函式,會執行子類函式的內容,如同父類的函式被覆蓋一樣.

這種情況是函式的另一種特性:  重寫(覆蓋)

class A
{
void run(){}
}
class B extends A
{
void run(){}
}

當子類繼承父類,沿襲了父類的功能到子類中,但是子類雖具備該功能,但是功能的內容卻和父類不一致,這時沒有必要定義新功能,而是使用覆蓋,保留父類的功能定義,但改寫裡面的內容

覆蓋:

1.  子類覆蓋父類,必須保證子類許可權大於等於父類許可權,才可以覆蓋,否則編譯失敗

2.  靜態只能覆蓋靜態

注意:過載:只看同名函式的引數列表

重寫:子父類方法要一模一樣

子父類中的建構函式

在對子類物件進行初始化時,父類的建構函式也會執行,那是因為子類建構函式預設第一行有一條隱式的語句super();

super():會訪問父類中空引數的建構函式,而子類所有的建構函式預設的第一行都是super();

為什麼子類一定要訪問父類中的建構函式

因為父類中的資料子類可以直接獲取,所以子類物件在建立時,需要先檢視父類是如何對這些資料進行初始化的,所以子類在物件初始化時,要先訪問一下父類中的建構函式

如果要訪問父類中指定的建構函式,可以通過手動定義super語句的方式來指定

注意:super語句一定要定義在子類建構函式的第一行

關鍵字:final

final:最終.作為一個修飾符,可以修飾類, 函式, 變數

被final修飾的類不可以被繼承.為了避免被繼承,被子類複寫功能,可以在類名上加上final

被final修飾的方法不可以被複寫

被final修飾的變數是一個常量,只能賦值一次,既可以修飾成員變數,又可以修飾

當描述事物時,一些資料的出現值是固定的,那麼這時為了增強閱讀性,都給這些值起個名字,方便與閱讀,而這些個值不需要改變,所以加final修飾,作為常量:常量書寫規範是所有字母都大寫,如果有多個單詞,則單詞間用_(下劃線)連線

內部類定義在類中的區域性變數時,只能訪問該區域性被final修飾的區域性變數