文章目錄
- 前言
- 一、類和物件的初步認識
- 1.1.類
- 1.2.物件
- 1.3.類和物件的關系
- 二、 類和類的實體化
- 三、static關鍵字
- 1.使用static定義屬性
- 2.使用static定義方法
- 四、 封裝
- 1.封裝的含義
- 2.private實作封裝
- 3.Setter和Getter方法
- 五、構造方法
- 六、this關鍵字
- 七、代碼塊
- 1.普通代碼塊
- 2.構造代碼塊
- 3.靜態代碼塊
- 總結
前言
類和物件是面向物件編程語言的重要概念,Java是一種面向物件的語言,所以要想熟練使用Java,就一定要掌握類和物件的使用,
一、類和物件的初步認識
1.1.類
【類的概念】
將具有相同屬性及相同行為的一組物件稱為類(class),
廣義地講,具有共同性質的事物的集合就稱為類,
在面對物件程式設計中,類是一個獨立的單位,它有一個類名,其內部包含成員變數,用于描述物件的屬性;還包括類的成員方法,用于描述物件的行為,
如下:
class Person{
String name;//變數
int age;//變數
void talk(){//操作資料的方法
System.out.println("我是:"+name+",今年:"+age+"歲");
}
}

1.2.物件
【概念】
物件(object)是類的實體化后的產物
一個物件由一組屬性和一系列對屬性進行操作的方法構成,
在Java中,一切皆為物件,
1.3.類和物件的關系
類是對某一類事物的描述,是抽象的、概念上的定義;
物件是實際存在在該類事物的個體,也可稱為實體,
舉個例子:
我們需要圖紙來造出椅子,這個圖紙就是“類”,而由圖紙設計出來的椅子就稱為“物件”,

類是物件的模板,物件是類的實體,一個類可以對應多個物件,
二、 類和類的實體化
宣告一個類就是創建一個新的資料型別,而類在 Java 中屬于參考型別, Java 使用關鍵字 class 來宣告類,我們來
看以下簡單的宣告一個類,
【基本語法】
// 創建類
[識別符號]class 類名稱{
field;//成員屬性
method;//成員方法
}
// 實體化物件
類名稱 <物件名> = new 類名稱();
識別符號可以是public、private、protected,class為定義類的關鍵字,{}中為類的主體,
類中的元素稱為:成員屬性,類中的函式稱為:成員方法,
類的定義:
class Person {
public int age;//成員屬性 實體變數
public String name;//定義人的姓名
public String sex;//性別
public void eat() {//成員方法
System.out.println("吃飯!");
}
public void sleep() {//成員方法
System.out.println("睡覺!");
}
}
【注意】這里在定義方法是沒有使用到static關鍵字,后面我們會詳細介紹static關鍵字,
類的實體化:
class Person {
public int age;//成員屬性 實體變數
public String name;
public String sex;
public void eat() {//成員方法
System.out.println("吃飯!");
}
public void sleep() {
System.out.println("睡覺!");
}
}
public class TestDemo{
public static void main(String[] args) {
Person person = new Person();//通過new實體化物件
person.eat();//成員方法呼叫需要通過物件的參考呼叫
person.sleep();
//產生物件 實體化物件
Person person2 = new Person();//可創建多個物件
Person person3 = new Person();
}
}
物件實體化的程序如下圖:

【結論】
- new 關鍵字用于創建一個物件的實體
- 使用 . 來訪問物件中的屬性和方法
- 同一個類可以創建對個實體
三、static關鍵字
1.使用static定義屬性
在程式中用static定義屬性的化,則此變數稱為靜態屬性,
那什么是靜態屬性?使用靜態屬性又有什么好處呢?
看下面代碼:
class Person{//定義Person類,有3個屬性,name,age,city
String name;
String city;
int age;
public Person(String name,String city,int age){//定義構造方法
this.name=name;
this.city=city;
this.age=age;
}
public String talk(){//定義talk方法
return "我是:"+this.name+",今年:"+this.age+"歲,來自:"+this.city;
}
}
public class TestDemo{
public static void main(String[] args) {
Person p1=new Person("張三","中國",25);//實體化Person物件
Person p2=new Person("李四","中國",25);
Person p3=new Person("王五","中國",25);
System.out.println(p1.talk());//呼叫talk()方法輸出資訊
System.out.println(p2.talk());
System.out.println(p3.talk());
}
}

觀察發現,所有的Person物件都有一個city屬性,而且所有屬性都相同,為中國,
如果我們程式中有100個Person物件,想要改變city屬性,是不是要呼叫100次,這就太麻煩了,
所以我們可以用static關鍵字來解決這個問題,用它來修飾類的屬性后,則此屬性就是共同屬性了,
修改如下:
class Person{//定義Person類,有3個屬性,name,age,city
String name;
static String city;//static修飾
int age;
public Person(String name,String city,int age){//定義構造方法
this.name=name;
this.city=city;
this.age=age;
}
public String talk(){//定義talk方法
return "我是:"+this.name+",今年:"+this.age+"歲,來自:"+this.city;
}
}
public class TestDemo{
public static void main(String[] args) {
Person p1=new Person("張三","中國",25);//實體化Person物件
Person p2=new Person("李四","中國",25);
Person p3=new Person("王五","中國",25);
System.out.println("修改前的資訊"+p1.talk());//呼叫talk()方法輸出資訊
System.out.println("修改前的資訊"+p2.talk());
System.out.println("修改前的資訊"+p3.talk());
System.out.println("=================================");
p1.city="美國";
System.out.println("修改后的資訊"+p1.talk());//呼叫talk()方法輸出資訊
System.out.println("修改后的資訊"+p2.talk());
System.out.println("修改后的資訊"+p3.talk());
}
}

【總結】
static修飾的屬性中,同一個類的不同實體共用同一個靜態屬性.
2.使用static定義方法
如果在任何方法上應用 static 關鍵字,此方法稱為靜態方法
- 靜態方法屬于類,而不屬于類的物件
- 可以直接呼叫靜態方法,而無需創建類的實體
- 靜態方法可以訪問靜態資料成員,并可以更改靜態資料成員的值,
例子如下:
class Person{//定義Person類,有3個屬性,name,age,city
String name;
static String city;//定義靜態屬性city
int age;
public Person(String name,String city,int age){//宣告一個構造方法
this.name=name;
this.city=city;
this.age=age;
}
public String talk(){//定義talk方法
return "我是:"+this.name+",今年:"+this.age+"歲,來自:"+this.city;
}
public static void setCity(String c){//宣告一個靜態方法
city.c;
}
}
public class TestDemo{
public static void main(String[] args) {
Person p1=new Person("張三","中國",25);//實體化Person物件
Person p2=new Person("李四","中國",25);
Person p3=new Person("王五","中國",25);
System.out.println("修改前的資訊"+p1.talk());//呼叫talk()方法輸出資訊
System.out.println("修改前的資訊"+p2.talk());
System.out.println("修改前的資訊"+p3.talk());
System.out.println("=================================");
p1.city="美國";
System.out.println("修改后的資訊"+p1.talk());//呼叫talk()方法輸出資訊
System.out.println("修改后的資訊"+p2.talk());
System.out.println("修改后的資訊"+p3.talk());
}
}
-
【注意】
- 靜態方法和實體無關, 而是和類相關. 因此這導致了兩個情況
- 靜態方法不能直接使用非靜態資料成員或呼叫非靜態方法(非靜態資料成員和方法都是和實體相關的)
- this和super兩個關鍵字不能在靜態背景關系中使用(this 是當前實體的參考, super是當前實體父類實體的參考, 也
是和當前實體相關).
此外:
- 我們曾經寫的方法為了簡單, 都統一加上了 static. 但實際上一個方法具體要不要帶 static, 都需要是情形而定.
- main 方法為 static 方法.
四、 封裝
1.封裝的含義
封裝是什么?
封裝是將描述某類事物的資料與處理這些資料的函式封裝在一起,形成一個整體,稱為類,
一旦設計好類,就可以實體化該類的物件,我們在形成一個物件的同時也界定了物件與外界的內外界限,
物件的屬性、行為等實作的細節則被分裝在物件的內部,外部使用者和其他物件只能經由原先規劃好的介面與物件互動,

封裝的本質就是讓類的呼叫者不必太多的了解類的實作者是如何實作類的, 只要知道如何使用類就行了.
這樣就降低了類使用者的學習和使用成本, 從而降低了復雜程度
2.private實作封裝
private/ public 這兩個關鍵字表示 “訪問權限控制” .
-
被 public 修飾的成員變數或者成員方法, 可以直接被類的呼叫者使用.
-
被 private 修飾的成員變數或者成員方法, 不能被類的呼叫者使用.
換句話說, 類的使用者根本不需要知道, 也不需要關注一個類都有哪些 private 的成員. 從而讓類呼叫者以更低的成本來使用類,
以一只貓的例子來舉例:
class Mycat{
public float weight; //通過public修飾符,開放MyCat的屬性給外界
Mycat(){}
}
class TestDemo{
public static void main(String[] args) {
Mycat aCat=new Mycat();
aCat.weight=-10.0f; //設定Mycat的屬性值
float tmp=aCat.weight;//獲取Mycat的屬性值
System.out.println("這只貓的體重是:"+tmp);
}
}


如果這里將類中的屬性用private封裝,就能避免這種錯誤的發生了,
修改如下:

這里有一個問題,如果我們非要給物件的屬性賦值呢?我們能不能做到,或者說有沒有什么方法讓我們達到這個目的?
這里就需要用到Setter和Getter方法了,
3.Setter和Getter方法
通常
- 對屬性設定的方法被命名為SetXxx(),其中Xxx為任何有意義的名稱,這類方法可統稱為Setter方法,
- 對取屬性值的方法被命名為GetYyy,其中Yyy為任何有意義的名稱,這類方法可統稱為Getter方法,
我們下面嘗試用這兩個方法修改貓的體重:
class Mycat{
private float weight; //通過private修飾符,開放MyCat的屬性給外界
public void SetWeight(float wt){
if(wt>0){
this.weight=wt;
}else {
System.out.println("weight設定非法(應該>0)");
weight=10.0f;
}
}
public float GetWeight(){
return weight;
}
}
class TestDemo{
public static void main(String[] args) {
Mycat aCat=new Mycat();
aCat.SetWeight(-10f); //設定Mycat的屬性值
float tmp=aCat.GetWeight();//獲取Mycat的屬性值
System.out.println("這只貓的體重是:"+tmp);
}
}

【注意】
- getName 即為 getter 方法, 表示獲取這個成員的值.
- setName 即為 setter 方法, 表示設定這個成員的值.
- 當set方法的形參名字和類中的成員屬性的名字一樣的時候,如果不使用this, 相當于自賦值. this 表示當前實體的參考
- 不是所有的欄位都一定要提供 setter / getter 方法, 而是要根據實際情況決定提供哪種方法
- 在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在 VSCode 中可以使用滑鼠右鍵選單 -> 源代碼操作 中自動生成 setter / getter 方法.
五、構造方法
構造方法是一種特殊方法, 使用關鍵字new實體化新物件時會被自動呼叫, 用于完成初始化操作,
宣告物件并實體化的格式:
類名稱 物件名稱=new 類名稱();
- 類名稱:表示要定義變數的型別,只是有了類之后,變數的型別是有用于自己定義的,
- 物件名稱:表示變數的名稱,變數的命名規范與方法相同,
- new:是作為開辟堆記憶體的唯一方法,表示實體化物件,
- 類名稱():這就是一個構造方法,
所謂構造方法,就是在每一個類中定義的,并且實在使用關鍵字new實體化一個新物件的時候默認呼叫的方法,
class Person {
private String name;//實體成員變數
private int age;
private String sex;
//默認建構式 構造物件
public Person() {
this.name = "caocao";
this.age = 10;
this.sex = "男";
}
//帶有3個引數的建構式
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//呼叫不帶引數的建構式 如果程式沒有提供會呼叫不帶引數的建構式
p1.show();
Person p2 = new Person("zhangfei",80,"男");//呼叫帶有3個引數的建構式
p2.show();
}
}
// 執行結果
name: caocao age: 10 sex: 男
name: zhangfei age: 80 sex: 男
使用構造方法需要注意以下幾點:
- 方法名稱必須與類名稱相同
- 構造方法沒有回傳值型別宣告
- 每一個類中一定至少存在一個構造方法(沒有明確定義,則系統自動生成一個無參構造)
- 如果類中沒有提供任何的建構式,那么編譯器會默認生成一個不帶有引數的建構式
- 若類中定義了構造方法,則默認的無參構造將不再生成
- 構造方法支持多載. 規則和普通方法的多載一致
- 構造方法不能被static和final修飾
六、this關鍵字
使用this關鍵字,只需遵循一個原則,就是this表示當前物件,而所謂的當前物件就是指呼叫類中方法或屬性的那個物件,

【注意】
- this.data; 表示呼叫當前物件的屬性
- this.func(); 表示呼叫當前物件的方法
- this(); 表示呼叫當前物件的其他構造方法
七、代碼塊
代碼塊用{ }將多行代碼封裝在一起,形成一個獨立的代碼區域,
格式如下:
{
//代碼塊
}
代碼塊有四種:
- 普通代碼
- 構造代碼塊
- 靜態代碼塊
- 同步代碼塊
代碼塊不能獨立運行,需要依賴于其他配置
1.普通代碼塊
普通代碼塊是最常見的代碼塊,它不能單獨存在于類中,需要緊跟在方法名后面,并通過方法呼叫,
public class Main{
public static void main(String[] args) {
{ //直接使用{}定義,普通方法塊
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
2.構造代碼塊
構造代碼塊就是在類中直接定義的,且沒有任何前綴,后綴以及修飾符的代碼塊,
前面提到,在一個類中,至少需要有一個構造方法,如果沒有,編譯器就會“隱式”地配備一個,
private String name;//實體成員變數
private int age;
private String sex;
public Person() {
System.out.println("I am Person init()!");
}
//實體代碼塊
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
p1.show();
}
}
// 運行結果
I am instance init()!
I am Person init()!
name: bit age: 12 sex: man
【注意】
構造代碼塊不在任何方法之內,僅位于類的范圍內,它的地位與其他方法體是對等的,可以理解為構造代碼塊是沒有名稱的方法體,但僅限用于對類資料成員的初始化,且僅運行一次,
此外,在類被實體化的程序中,構造代碼塊內的代碼比構造方法先執行,
3.靜態代碼塊
使用static關鍵字加以修飾的代碼塊就是靜態代碼塊,其主要用來初始化成員變數,它是最早執行的代碼塊,
private String name;//實體成員變數
private int age;
private String sex;
private static int count = 0;//靜態成員變數 由類共享資料 方法區
public Person(){
System.out.println("I am Person init()!");
}
//實體代碼塊
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
//靜態代碼塊
static {
count = 10;//只能訪問靜態資料成員
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();//靜態代碼塊是否還會被執行?
}
}
【結論】
- 靜態代碼塊不管生成多少個物件,其只會執行一次,且是最先執行的
- 靜態代碼塊執行完畢后, 實體代碼塊(構造塊)執行,再然后是建構式執行,
- 靜態成員變數是屬于所以類物件共享的,故此不會受到創建物件個數的影響,
總結
最近學習有點落下了,編程的學習還是在于寫,要刷題,而自己在這方面確實很匱乏,一方面是最近考試多,要備考;一方面是參加了比賽,要備賽,每天像一個猴子一樣蹦蹦跳跳,還以為自己積極向上,哈哈哈哈哈…
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/347108.html
標籤:java
上一篇:Java重點 —— 類和物件
