封裝的定義
- 封裝(Encapsulation):
是指隱藏對象的屬性和實現細節。僅對外提供公共訪問方式 - 好處:
將變化隔離
便於使用
提高重用性
提高安全性 - 代碼中體現:
函數本身就死最小的封裝體,其次到類、包、框架
private修飾符的出現,修飾類中的成員(成員變量、成員函數)將其變成私有,私有類只有在本類中有效。
構造函數
- 何爲構造函數:
函數名和類名一致
不用定義返回值類型(與void不同。)
不可以寫return語句
- 構造函數作用:
給對象進行初始化
- 什麼時候定義構造函數:
當分析事物時,該事物存在具備一些特性或者行爲,那麼將這些內容定義在構造函數中 - 與一般函數的區別:
-
在運行上有不同,構造函數在對象一建立就運行,給對象初始化。而一般方法是對象調用才執行,給對象添加對象具備的功能
-
調用次數上,一個對象建立,構造函數只運行一次。而一般方法可以被該對象調用多次。
注意:當一個類中沒有定義構造函數時,系統會默認給該類加入一個空參數的構造函數如:【Person(){}】
當在一個類中,自定義了構造函數後,默認的構造函數就沒有了。多個構造函數是以重載的形式存在的
構造代碼塊
定義對象共性初始化內容,不同對象的共性定義在構造代碼塊裏
- 作用:
給對象進行初始化(對象一建立就運行,而且優先於構造函數執行)
- 和構造函數的區別:
構造代碼塊是給所有對象進行統一初始化
而構造函數是給對應的對象初始化
- 語法
{
語句1
}
舉例
this關鍵字
-
作用:
- 區別成員變量和局部同名的時候用
- 構造函數間的調用(一般函數不能調用構造函數的)
-
解析
當定義類中的功能時,該函數內部要用到這個函數的對象時,這時用this來表示這個對象。但凡本類功能用到本類對象,都用this表示。比如:
class Person{
private String name;
private int age;
Person(int age){
this.age=age;
System.out.println("age="+age);
}
/*
*需求:給人定義一個用於比較年齡是否相同的功能,也就是是否是同齡人
*/
public boolean Compare(Person p){
return this.age==p.age;
}
}
public class PersonDemo2 {
public static void main(String[] args) {
Person p1=new Person(20);
Person p2=new Person(25);
boolean b = p1.Compare(p2);
System.out.println(b);
}
}
Person方法裏的this,當p1 和p2都分別創建對象時,this就分別代表p1 和p2。
Compare方法裏的this,當p1對象調用它時,this代表的就是p1
構造函數間調用只能用this語句
初始化動作先執行,再執行自己的初始化,this語句要放在構造函數的第一行,因爲構造函數只執行一次
爲什麼構造函數間需要相互調用,對外提供一個構造函數,但內部初始化方式可以通過調用不同私有化的構造方法進行初始化。
23行,表示對象調用了16行的構造函數對name再一次進行初始化,這也就是構造函數間調用。
Static關鍵字
- 用法:
是一個修飾符,用於修飾成員(成員變量和成員函數)
靜態所修飾的內容,被對象所共享。當成員被靜態修飾後,就多了一種調用方式,除了可以被對象調用外,還可以直接被類名調用 - 寫法:
類名.靜態成員
當多個對象當中,存在共同的數據。創建對象越多,共同的數據就越多,爲了不浪費內存,所以將共同的數據抽出,讓對象去訪問,比如相同國籍的學生。
static String country=“CN”
特有內容隨着對象存儲在堆內存中,像每個人的名字
- 方法區(共享區 數據區)
類中的方法、類中的共享數據存放這邊。 - 靜態的特點:
- 隨着類的加載而加載,也就是說靜態隨着類的消失而消失。說明他的生命週期最長。
- 優先於對象存在(靜態是先存在,對象是後存在的)
- 被所有對象所共享
- 可以直接被類名所調用
- 實例變量和類變量的區別:
String name;//成員變量,實例變量
static String country ="CN";//靜態的成員變量,類變量
1. 存放位置:
類變量隨着類的加載而加載,存放於方法中,
實例變量隨着對象的建立而存在堆內存中。
2. 生命週期:
類變量生命週期最長,隨着類的消失而消失
實例變量生命週期隨着對象消失而消失
- 靜態的使用注意事項:
- 靜態方法只能訪問靜態成員(方法和變量)
- 非靜態方法既可以訪問非靜態也可以訪問靜態成員
- 靜態方法中不可以定義this super關鍵字,因爲靜態優先於對象存在
- 主函數是靜態的。(主函數是一個特殊的函數,作爲程序入口,可以被jvm調用
- 靜態的好處:
- 對對象共享數據進行單獨空間存儲,節省內存空間,沒有必要每個對象都存一遍
- 可以直接被類名調用。
- 弊端:
- 生命週期過長,
2.訪問出現侷限性(靜態雖好,但是隻能訪問靜態)
- 什麼時候使用靜態?(因爲靜態修飾內容有成員變量和函數)
- 什麼時候定義靜態變量(類變量)呢?
當對象中出現共享數據時,該數據被靜態所修飾(值一樣)
對象中持有數據要定義成非靜態存在於堆內存中 - 什麼時候定義靜態函數呢?
當功能內容沒有訪問到非靜態數據(對象的特有數據),那麼該功能可以定義成靜態的。
靜態代碼塊
特點:隨着類的加載而執行,只執行一次
用處:用於給類進行初始化的,優先於主函數執行
語法:
static {
語句;
}
執行順序
new StaticCode(4);時,靜態優先於對象。所以會優先打印a
構造代碼快優先於構造函數。
所以打印出:a c9 d
class StaticCode{
int num =9;
StaticCode(){
System.out.println("b");//因爲沒有創建沒帶參數的對象,所以不會執行
}
static {
System.out.println("a");//靜態代碼塊給類初始化 num不能放這,因爲靜態不能寫this
}
{
System.out.println("c"+this.num);//構造代碼塊給對象初始化
}
StaticCode(int x) {
System.out.println("d");//構造函數給對應對象初始化,因爲創建了帶參數的對象
}
}
public class StaticCodeDemo {
public static void main(String[] args) {
new StaticCode(4);
System.out.println("over!");
}
}
對象初始化過程
對象創建過程:
第一步:new的時候將Person.class文件加載進內存。
第二步;靜態代碼塊執行(優先於對象) 因爲執行的時候name爲空,age爲0都是堆內存的初始值。
第三步:堆內存開闢空間,則有屬性(name age)
第四步:構造代碼塊的優先級比構造函數高,
默認初始化-》顯示初始化-》構造代碼塊初始化-》構造函數初始化
顯示初始化