基本概念
定義
- 對象:對象是類的一個實例,有狀態和行為。例如,一條狗是一個對象,它的狀態有:顏色、名字、品種;行為有:搖尾巴、叫、吃等。
- 類:類是一個模板,它描述一類對象的行為和狀態。
類型變量
- 局部變量:在方法、構造方法或者語句塊中定義的變量被稱為局部變量。變量聲明和初始化都是在方法中,方法結束后,變量就會自動銷毀。
- 成員變量:成員變量是定義在類中,方法體之外的變量。這種變量在創建對象的時候實例化。成員變量可以被類中方法、構造方法和特定類的語句塊訪問。
- 類變量:類變量也聲明在類中,方法體之外,但必須聲明為 static 類型。
成員變量和類變量的區別
由static修飾的變量稱為靜態變量,其實質上就是一個全局變量。如果某個內容是被所有對象所共享,那么該內容就應該用靜態修飾;沒有被靜態修飾的內容,其實是屬於對象的特殊描述。
不同的對象的實例變量將被分配不同的內存空間, 如果類中的成員變量有類變量,那么所有對象的這個類變量都分配給相同的一處內存,改變其中一個對象的這個類變量會影響其他對象的這個類變量,也就是說對象共享類變量。
區別:
1、兩個變量的生命周期不同
成員變量隨着對象的創建而存在,隨着對象的回收而釋放。
靜態變量隨着類的加載而存在,隨着類的消失而消失。
2、調用方式不同
成員變量只能被對象調用。
靜態變量可以被對象調用,還可以被類名調用。
3、別名不同
成員變量也稱為實例變量。
靜態變量也稱為類變量。
4、數據存儲位置不同
成員變量存儲在堆內存的對象中,所以也叫對象的特有數據。
靜態變量數據存儲在方法區(共享數據區)的靜態區,所以也叫對象的共享數據。
static
static 關鍵字,是一個修飾符,用於修飾成員(成員變量和成員函數)。
特點:
1、想要實現對象中的共性數據的對象共享。可以將這個數據進行靜態修飾。
2、被靜態修飾的成員,可以直接被類名所調用。也就是說,靜態的成員多了一種調用方式。類名.靜態方式。
3、靜態隨着類的加載而加載。而且優先於對象存在。
弊端:
1、有些數據是對象特有的數據,是不可以被靜態修飾的。
因為那樣的話,特有數據會變成對象的共享數據。這樣對事物的描述就出了問題。所以,在定義靜態時,必須要明確,這個數據是否是被對象所共享的。
2、靜態方法只能訪問靜態成員,不可以訪問非靜態成員。
因為靜態方法加載時,優先於對象存在,所以沒有辦法訪問對象中的成員。
3、靜態方法中不能使用this,super關鍵字。
因為this代表對象,而靜態在時,有可能沒有對象,所以this無法使用。
成員變量和局部變量區別
區別
1、聲明位置不同
成員變量也就是屬性,在類中聲明的。
局部變量,在方法中聲明或代碼塊中聲明。
2、初始值不同
成員變量如果沒有賦值則是有默認值的,數據類型不同則默認值不同。
局部變量是沒有默認值,也就是說必須先聲明,再賦值,最后才使用。
3、在一個類中,局部變量可以與成員變量同名,但是局部變量優先,如果非要訪問成員變量的屬性,則必須使用 this
this 代表當前這個對象,也就是當前誰調用這個方法則這個對象就是誰。
構造方法
1、構造方法的名字和類名相同,並且沒有返回值。
2、構造方法主要用於為類的對象定義初始化狀態。
3、我們不能直接調用構造方法,必須通過new關鍵字來自動調用,從而創建類的實例。
4、Java的類都要求有構造方法,如果沒有定義構造方法,Java編譯器會為我們提供一個缺省的構造方法,也就是不帶參數的構造方法。
5、如果定義了任何一個構造函數,就不會再自動構造,需要自己定義全部的構造函數。
new關鍵字的作用
1、為對象分配內存空間。
2、引起對象構造方法的調用。
3、為對象返回一個引用。
對象與引用區別
對象是具體的一個實例,如:new Student(); new 表示創建一個對象,並在堆內存中開辟一塊空間。
引用名稱是存放的對象的地址。
例如:
1 //一個帶顯式構造函數的類 2 Public class People{ 3 int age = 23; 4 Public void getAge(){ 5 System.out.print("the age is "+ age); 6 } 7 // 顯式聲明一個帶參數的構造函數,用於初始化年齡 8 Public People(int a){ 9 this.age = a; 10 } 11 } 12 13 //用這個類來實例化一個對象 14 People xiaoMing = new People(20); // 使用帶參數的構造函數來實例化對象 15 People xiaoMing2 = new People(); // ERROR:一旦顯示定義了一個構造函數,就不會再生成默認的構造函數 16 xiaoMing.getAge(); // 打印出來的年齡變為20
創建對象
對象是根據類創建的。在Java中,使用關鍵字 new 來創建一個新的對象。創建對象需要以下三步:
- 聲明:聲明一個對象,包括對象名稱和對象類型。
- 實例化:使用關鍵字 new 來創建一個對象。
- 初始化:使用 new 創建對象時,會調用構造方法初始化對象。
1 public class Student{ 2 public Student(String name){ 3 System.out.println("學生的名字是 : " + name ); 4 } 5 public static void main(String[] args){ 6 Student stu = new Student( "tom" ); 7 } 8 }
訪問實例變量和方法
通過已創建的對象來訪問成員變量和成員方法,如下所示:
1 /* 實例化對象 */ 2 Object referenceVariable = new Constructor(); 3 /* 訪問類中的變量 */ 4 referenceVariable.variableName; 5 /* 訪問類中的方法 */ 6 referenceVariable.methodName();
類的訪問權限
四種訪問修飾符
private
Java語言中對訪問權限限制的最窄的修飾符,一般稱之為“私有的”。被其修飾的屬性以及方法只能被該類的對象訪問,其子類不能訪問,更不能允許跨包訪問。
default
即不加任何訪問修飾符,通常稱為“默認訪問權限“或者“包訪問權限”。該模式下,只允許在同一個包中進行訪問。
protected
介於public 和 private 之間的一種訪問修飾符,一般稱之為“保護訪問權限”。被其修飾的屬性以及方法只能被類本身的方法及子類訪問,即使子類在不同的包中也可以訪問。
public
Java語言中訪問限制最寬的修飾符,一般稱之為“公共的”。被其修飾的類、屬性以及方法不僅可以跨類訪問,而且允許跨包訪問。
四種修飾符的訪問權限范圍:
這里需要注意的是,所謂的訪問,可以分為兩種不同方式:第一,通過對象實例訪問;第二,直接訪問。
比如說,某父類protected權限的成員,子類是可以直接訪問的,換一種說話是子類其實繼承了父類的除了private成員外的所有成員,包括protected成員,所以與其說是子類訪問了父類的protected成員,不如說子類訪問了自己的從父類繼承來的protected成員。另一方面,如果該子類與父類不在同一個包里,那么通過父類的對象實例是不能訪問父類的protected成員的。
例如:
新建個類,四個類的結構如下,Aclass 和Bclass 是同包的類,Cclass 和Dclass是同包的類,Cclass 繼承了Aclass。
Aclass類的定義如下,有四個成員變量,權限分別為private、default、protected、public。四個成員方法,權限分別為 private、default、protected、public。

1 package com.study.test1; 2 3 /** 4 * @description: none 5 * @author: luguilin 6 * @date: 2021-09-22 21:47 7 **/ 8 public class Aclass { 9 private int a1 = 10; 10 int a2 = 20; 11 protected int a3 = 30; 12 public int a4 = 40; 13 14 private void showA1() { 15 System.out.println(a1); 16 } 17 18 void showA2() { 19 System.out.println(a2); 20 } 21 22 protected void showA3() { 23 System.out.println(a3); 24 } 25 26 public void showA4() { 27 System.out.println(a4); 28 } 29 }
Bclass類定義如下,它和Aclass類同屬於 test1包 ,在里面定義了一個成員方法show(),該方法通過兩種方法對Aclass類的所有成員進行了訪問,第一方法通過實例化一個Aclass類對象aa對成員變量及方法進行訪問,第二種是直接訪問Aclass中的成員。通過IDE的自動檢測報錯,可以看出,Bclass類是不能直接訪問Aclass類的成員的,但通過對象的方法可以訪問default權限以下(default、protected、public)的成員。

1 package com.study.test1; 2 3 /** 4 * @description: none 5 * @author: luguilin 6 * @date: 2021-09-22 21:52 7 **/ 8 public class Bclass { 9 public void show(){ 10 // 方法 11 Aclass aa = new Aclass(); 12 // aa.showA1(); // 'showA1()' has private access in 'com.study.test1.Aclass' 13 aa.showA2(); 14 aa.showA3(); 15 aa.showA4(); 16 17 // showA1(); // showA1的修飾符是private同包的類不能訪問 18 // showA2(); // showA2的修飾符是default擁有同包訪問以上權限 19 // showA3(); // showA3的修飾符是protected擁有不同包子類以上訪問權限 20 // showA4(); // showA4的修飾符是public擁有公開訪問權限 21 22 //變量 23 // System.out.println(aa.a1); // 'a1' has private access in 'com.study.test1.Aclass' 24 System.out.println(aa.a2); 25 System.out.println(aa.a3); 26 System.out.println(aa.a4); 27 28 // System.out.println(a1); // a1 的修飾符是private同包的類不能訪問 29 // System.out.println(a2); // a2的修飾符是default擁有同包訪問權限 30 // System.out.println(a3); // a3 的修飾符是protected擁有不同包子類以上訪問權限 31 // System.out.println(a4); // a4 的修飾符是public擁有公開訪問權限 32 } 33 }
Cclass類定義如下,它和Aclass類屬於不同的包,但是Cclass繼承了Aclass ,在里面定義了一個成員方法show(),該方法同樣通過兩種方法對Aclass類的所有成員進行了訪問,第一方法通過實例化一個Aclass類對象aa對成員變量及方法進行訪問,第二種是直接訪問Aclass中的成員。通過IDE的自動檢測報錯,可以看出,Cclass類是可以直接訪問Aclass類權限為protected、public的成員(因為子類的緣故),但通過對象的方法只能訪問 public權限的成員(因為Cclass和Aclass不同包)。

1 package com.study.test2; 2 3 import com.study.test1.Aclass; 4 5 /** 6 * @description: none 7 * @author: luguilin 8 * @date: 2021-09-22 21:56 9 **/ 10 public class Cclass extends Aclass { 11 Cclass(){ 12 super(); 13 } 14 15 public void show(){ 16 Aclass aa = new Aclass(); 17 // 方法 18 // aa.showA1(); // 'showA1()' has private access in 'com.study.test1.Aclass' 19 // aa.showA2(); // 'showA2()' is not public in 'com.study.test1.Aclass'. Cannot be accessed from outside package 20 // aa.showA3(); // 'showA3()' has protected access in 'com.study.test1.Aclass' 21 aa.showA4(); 22 23 // showA1(); // showA1的修飾符是private,同包的類不能訪問 24 // showA2(); // showA2的修飾符是default。擁有同包訪問以上權限 25 showA3(); // showA3的修飾符是protected,擁有不同包子類以上訪問權限 26 showA4(); // showA4的修飾符是public,擁有公開訪問權限 27 28 29 // 變量 30 // System.out.println(aa.a1); //'a1' has private access in 'com.study.test1.Aclass' 31 // System.out.println(aa.a2); //'a2' is not public in 'com.study.test1.Aclass'. Cannot be accessed from outside package 32 // System.out.println(aa.a3); //'a3' has protected access in 'com.study.test1.Aclass' 33 System.out.println(aa.a4); 34 35 36 Cclass cc = new Cclass(); 37 // cc.showA1(); // 'showA1()' has private access in 'com.study.test1.Aclass' 38 // cc.showA2(); // 'showA2()\' is not public in \'com.study.test1.Aclass\'. Cannot be accessed from outside package' 39 cc.showA3(); 40 cc.showA4(); 41 42 // System.out.println(a1); // a1 的修飾符是private同包的類不能訪問 43 // System.out.println(a2); // a2的修飾符是default擁有同包訪問權限 44 // System.out.println(a3); // a3 的修飾符是protected擁有不同包子類以上訪問權限 45 System.out.println(a4); // a4 的修飾符是public 擁有公開訪問權限 46 47 48 // 通過子類訪問 49 // System.out.println(cc.a1); // 'a1' has private access in 'com.study.test1.Aclass' 50 // System.out.println(cc.a2); // 'a2' is not public in 'com.study.test1.Aclass'. Cannot be accessed from outside package 51 System.out.println(cc.a3); 52 System.out.println(cc.a3); 53 } 54 55 }
Dclass類定義如下,它是Aclass類不同包的一般類,在里面定義了一個成員方法show(),該方法同樣通過兩種方法對Aclass類的所有成員進行了訪問,第一方法通過實例化一個Aclass類對象aa對成員變量及方法進行訪問,第二種是直接訪問Aclass中的成員。通過IDE的自動檢測報錯,可以看出,Dclass類是不可以直接訪問Aclass類的成員(因為不是子類的緣故),但通過對象的方法只能訪問 public權限的成員(因為class和Aclass不同包)。

1 package com.study.test2; 2 3 import com.study.test1.Aclass; 4 5 /** 6 * @description: none 7 * @author: luguilin 8 * @date: 2021-09-22 22:01 9 **/ 10 public class Dclass { 11 public void show(){ 12 Aclass aa = new Aclass(); 13 // 方法 14 // aa.showA1(); // 'showA1()' has private access in 'com.study.test1.Aclass' 15 // aa.showA2(); // 'showA2()' is not public in 'com.study.test1.Aclass'. Cannot be accessed from outside package 16 // aa.showA3(); // 'showA3()' has protected access in 'com.study.test1.Aclass' 17 aa.showA4(); 18 19 // showA1(); // showA1的修飾符是private同包的類不能訪問 20 // showA2(); // showA2的修飾符是default擁有同包訪問以上權限 21 // showA3(); // showA3的修飾符是protected擁有不同包子類以上訪問權限 22 // showA4(); // showA4的修飾符是public擁有公開訪問權限 23 24 // 變量 25 // System.out.println(aa.a1); //'a1' has private access in 'com.study.test1.Aclass' 26 // System.out.println(aa.a2); //'a2' is not public in 'com.study.test1.Aclass'. Cannot be accessed from outside package 27 // System.out.println(aa.a3); //'a3' has protected access in 'com.study.test1.Aclass' 28 System.out.println(aa.a4); 29 30 // System.out.println(a1); // a1 的修飾符是private同包的類不能訪問 31 // System.out.println(a2); // a2的修飾符是default擁有同包訪問權限 32 // System.out.println(a3); // a3 的修飾符是protected擁有不同包子類以上訪問權限 33 // System.out.println(a4); // a4 的修飾符是public擁有公開訪問權限| 34 } 35 }