對類和物件的理解,是理解面對物件的第一步,
目錄
- 類的物件的概念
- 類的實體化
- 類的組成
- 欄位
- 方法
- 與類相關的關鍵字
- 靜態修飾static
- this關鍵字和static關鍵字
- 訪問修飾限定符
- 訪問修飾限定符修飾類成員時
- 拓展:當訪問修飾限定符修飾類時
- 物件的初始化
- 欄位的初始值
- 構造方法
- 默認構造方法
- 構造方法的方法名和回傳值
- 在構造方法里呼叫構造方法
類的物件的概念
類和物件的關系:簡單來說,類就是一個物件的圖紙,而物件就是類的實體,一個類可以創建很多物件,就像一份建筑圖紙可以建很多座房子那樣,
深入:之前我的博客如何深入理解你的第一個Java程式里有提到類的概念,那篇文章提到,類的本質是抽象,而抽象的最大特征就是沒有物體,也就是說,任何沒有物體的事物,理論上都可以作為一個類,也許你覺得這用的定義有點抽象,這樣的定義是為了考慮不同的情況,因為在實際的編程程序中,你總會設計一些類時,不會創建這個類所對應的物件,此時為了邏輯自洽,你大可把類理解為一種沒有物體的事物,或許有實體,或許沒有,

類的實體化
類的實體化,即以某個類為模板創建該類的物件,語法為
new Dog();
其中new是實體化的關鍵字,表示要新建一個物件,Dog是要實體化的類,后面加一個括號表示呼叫與Dog類同名的構造方法,這個陳述句將會回傳一個Dog類的物件,一般會使用Dog的參考型別進行接收,
Dog dog = new Dog();
這里dog是Dog類的參考型別,通過dog變數可以向一個dog物件發送訊息,
你可以向dog物件發送訊息以呼叫dog物件的屬性或方法,
若你沒有定義一個參考變數接受該物件的參考,即此時你沒有對該物件的參考進行“命名”,這種定義物件的方式也叫做匿名物件,由于你沒有存盤實體化回傳的參考,你將無法再通過參考找到這個物件,這意味著你只能使用這個物件一次,當你只使用一次物件時,可以考慮定義一個匿名物件,
類的組成
類的基本組成為欄位和方法,都可以統稱為類的成員,
欄位
欄位,也可以叫做屬性或者成員變數,
欄位即屬性或者引數,用于描述目前物件的狀態,可以是任何資料型別,基本資料型別,參考資料型別均可,
定義方式:在方法的外部,類的內部直接定義,
呼叫方式:物件參考.欄位名
方法
也可以叫做函式,
方法即行為,用于描述目前物件的行為,最基本的組成結構為回傳值,引數和方法名和引數串列,方法體,一般的方法的方法名不可以與類名雷同(構造方法除外),方法體用于說明方法的具體實作,
定義方式:在類的內部單獨定義
呼叫方式:物件參考.方法名(方法引數)
與類相關的關鍵字
靜態修飾static
static基本語法:可以修飾類中的欄位、方法,被static修飾后的類成員將不依賴于具體的物件,而依賴于類本身,
staitc的內部實作:從記憶體的角度看,被static修飾的欄位和所有的方法(不管有沒有static修飾,都以位元組碼的形式)被存放在方法區中,存在方法區中意味著有且只有一份,不依賴于具體的物件(new出來物件都存在堆里,允許存在多份),這意味著static修飾的欄位和所有方法被所有物件所共用,或者說只依賴于類,
靜態欄位和方法的呼叫方式:類名.靜態欄位或靜態方法(也可以使用具體的實體來呼叫靜態欄位和方法,但并不建議)
易錯點:允許使用static修飾區域變數嗎?
答:不允許,Java并沒有定義static修飾區域變數的語法,也就是說被static修飾的變數還是會放在方法區里,但是Java又定義區域變數是存放在堆疊上的,因此這個變數的存盤位置就出現了矛盾,
this關鍵字和static關鍵字
this關鍵字的含義是:當前物件的參考,
this有以下三種用法:
1this() 呼叫當前的構造方法,只能放在構造方法中,且必須是第一行,構造,(構造方法在后面會介紹)
2this.欄位 表示訪問當前物件的欄位
3this.方法 表示訪問當前物件的方法
this存在的意義為了防止當前物件的欄位名和其他臨時變數發生沖突或者其他需要利用到當前物件參考的情況,
this的內部實作:this一般用于實體方法或構造方法中,從內部實作來看,Java在呼叫一個非靜態方法時,除了傳遞顯示宣告的引數外,還會隱式地傳遞當前物件的參考到該方法中,以便于后續的操作,
那么問題就出現了,你怎么呼叫當前物件的參考呢?怎樣才能避免當前物件的參考和其他的變數的命名沖突呢?于是Java提供了一個關鍵字this,用于表示當前物件的參考,
在你理解了this的內部實作之后,此時你可以進一步理解static關鍵字了,static修飾的方法,就是沒有this的方法,
訪問修飾限定符
訪問修飾限定符修飾類成員時
一般來說Java的訪問修飾限定符一般用在類的成員和類本身,這里先討論的是訪問修飾限定符對類成員的情況,
Java有四種訪問修飾限定符,分別是
- private:該成員只能在類的內部呼叫
- protected
- 默認(沒有訪問修飾限定符,表示包訪問權限)
- public:該成員在任何類中都能呼叫
其中protected和默認訪問權限需要包和繼承的知識,這里先不進行討論,
以下是幾個關于訪問修飾限定符語法的常見問題、
public訪問修飾限定符放在哪里?對誰起作用?
答:放在你要進行訪問權限控制的類成員或類的正前方,僅對緊跟著訪問修飾限定符的事物有訪問控制效果,
為什么要有訪問修飾限定符?
答:這是一個非常重要的問題,為了制定類的創建者和使用者的界線,制定這個界線有以下好處:
1.降低類使用者的使用成本
舉個例子,當你使用洗衣機時,你無需知道洗衣機的內部作業原理,你只要會使用洗衣機的功能即可,這將降低使用洗衣機的成本,就算你要打開洗衣機研究內部的作業原理,頭疼的也會是洗衣機的制造者,因為當你打開內部結構時,你可能會損壞洗衣機的使用功能,
2.方便使用者的代碼重構
這也是最關鍵的一點,在類的創建者在對類進行維護時,不至于要讓到類的使用者大量修改代碼,
一般來說,類的創建者和使用者有一個約定,當一個類提供了公共的方法后,就不會輕易的修改這個公共方法的名字和實作的功能,類的創建者可以僅僅提供那些想要讓使用者使用的部分,而將具體的實作進行封裝,這樣在重構內部的實作時,就可以減小對類使用者的影響,
反過來講,若不存在訪問修飾限定,則會出現什么現象?類的創建者在重構類時將會處處受限,因為從類的創建者角度來看,由于類的內部是完全公開的,無法得知哪些成員被類的使用者呼叫了,因此也不知道自己可以修改哪些部分,哪些部分不能修改,很難不對類的使用者造成影響,
拓展:當訪問修飾限定符修飾類時
類的訪問修飾限定符只有兩種:public和包訪問權限,
類的包訪問權限:若你具有Java的包的知識,這里僅需要注意一點,沒有明確指定裝包的.java檔案,將會被放在當前路徑的默認包中,
public修飾類:
public修飾類時,有如下的限制:
- 一個.java檔案僅有一個public類
- .java檔案名必須與檔案里的public類名相同
- 特例:.java檔案里可以沒有public類,此時的.java檔案可以任意命名,但為了避免混淆,盡量不要亂命名,
此外,若你不想要任何人使用你的類,也就是想要實作一個類似private的類(注意,沒有protected和private類),可以使用private修飾類的構造方法,你可以定義一個靜態方法回傳一個該類物件的參考,
類的包訪問
物件的初始化
欄位的初始值
在Java中,若你想要使用變數,你必須初始化你的臨時變數,但卻不用初始化欄位也可以直接使用,這些欄位會用一個默認值,這是另很多人迷惑的點,
從記憶體的角度上來看,臨時變數和欄位本就不在同一個記憶體區域中,臨時變數存在堆疊上,欄位存在堆或方法區中(靜態欄位),欄位之所有有初始值是因為JVM在實體化一個物件時,會為物件開辟一塊確定大小的空間,并為這塊空間賦以對應的0值,以下是各種資料型別所對應的默認值也就是0值,
對于靜態欄位,是存放在方法區中的,在首次實體化物件或由此呼叫該類的任何靜態成員時,JVM就會為所有的靜態成員賦予默認值,
構造方法
new Dog();
在實體化時,要在類名后加一個括號,這有什么用意?若你知道物件的實體化程序,你就能理解為什么這么寫了,
物件的實體化程序:
- 為物件開辟空間,并賦予對應的0值(與欄位的初始化相匹配)
- 使用構造方法初始物件
構造方法的存在,正是為了保證物件的初始化,
默認構造方法
之前介紹了物件的實體化程序,有時你并沒有使用寫構造方法,但為什么也可以進行物件的實體化呢?因為在你沒有寫任何構造方法的時候,系統會為你提供一個默認的無參構造方法,注意:若你有提供構造方法,系統將不會再為你提供構造方法了,
構造方法的方法名和回傳值
class Dog {
String name;
public Dog(String name) {
this.name = name;
}
}
構造方法的方法名與類名相同,這是為了防止命名沖突,因為一個類的方法只有一個,此時定義類名就是構造方法名就可以保證構造方法的方法名是獨一無二的,
構造方法無回傳值,這是Java的基本語法,不必深究,
在構造方法里呼叫構造方法
你可以使用在構造方法中使用使用this();呼叫另一個構造方法,但請注意,只能在構造方法里用this呼叫另一個構造方法,且只能放在構造方法的第一行,一個構造方法只能呼叫其他的構造方法一次,在呼叫完其他的構造方法后,會繼續執行當前的構造方法,
疑問:允許嵌套呼叫其他構造方法嗎?即在一個構造方法里呼叫另一個構造,在另一個構造方法再呼叫其他的構造方法?
答:可以,只要保證this呼叫的構造方法的陳述句都放在第一行,且代碼不出現死回圈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/332386.html
標籤:java
上一篇:在VBA中將Excel文本轉為列,每行的分隔符數量可變?
下一篇:提取URL查詢字串陣列regex
