前言
? ? ? ?從這篇文章開始,我們就進入到了JavaSE的核心部分。這篇文章是Java類和對象的第一篇,主要介紹類和對象的概念,this關鍵字以及構造方法~~
什么是類?什么是對象?
? ? ? ?學過C語言的老鐵們,可以類比struct自定義一個結構體,類就類似結構體,對象就類似使用結構體關鍵字來創建結構體變量(結構體普通變量,結構體指針,結構體數組),但是類里面可以定義方法(也就是C語言中的函數)
? ? ? ?沒有學過C語言的老鐵們,可以這樣理解,假設你是一個建筑工程師,類就是你畫出來的建筑圖紙,而對象就是用圖紙實際建造出來的房子,圖紙就是用來描述這個房子具體的細節(長,寬,高,材料等等)
類是用來對一個實體(對象)來進行描述的,主要描述該實體(對象)具有哪些屬性(外觀尺寸等),哪些功能(用來干啥),描述完成后計算機就可以識別了。
類的創建
我們可以使用 class 關鍵字來定義一個類
一個類里面包含字段/屬性/成員變量,也可以包含成員方法~~
class 類名{
? ? ? ?字段、屬性、成員變量;(定義在類里面,方法外面)
? ? ? ?成員方法;
}
下面我們來定義一個學生類:
class Student{//字段、屬性、成員變量public String name;public int age;public String stuNum;//成員方法public void sleep(){System.out.println(name + "睡覺");}public void haveClass(){System.out.println(name + "上課");}public void doHomework(){System.out.println(name + "做作業");}
}
對象的實例化
什么是對象的實例化,簡單來說就是創建一個對象,我們需要使用類名和 new 關鍵字來進行創建~~
創建格式:
類名 對象 = new 類名()
代碼示例:
Student student1 = new Student();
對象的使用
我們可以通過對象來訪問對象里面的成員變量和成員方法~~
使用格式:對象后面加一個點號再加相應的成員方法或者成員變量即可。
我們來試著使用一下,還是上面的學生類為例子:
public static void main(String[] args) {Student student1 = new Student();student1.name = "張三";student1.age = 10;student1.stuNum = "32";student1.sleep();student1.haveClass();student1.doHomework();}
面向過程和面向對象的區別
? ? ? ?面向過程和面向對象本質上都是解決問題的方法,面向過程注重的是過程,而面向對象就是需要對象與對象之間的聯系,面向對象的關鍵就是(找到對象,創建對象和使用對象),例如你上網購物,如果你是面向過程,你就會這樣子,下單,工廠制作商品,工人發貨,物流人員進行運輸,快遞員將快遞送到指定地點,你去那個地方取件,最后確認收貨,這就是面向過程。
? ? ? ?如果你是面向對象,那么就是你和快遞這兩個對象之間的聯系,你只需要關心為這個對象(商品)付款然后取件,就沒了。
? ? ? ?C語言就是典型的面向過程的編程語言,而Java是一門純面向對象的語言(Object Oriented Program,簡稱OOP),在面向對象的世界里,一切皆為對象。面向對象是解決問題的一種思想,主要依靠對象之間的交互完成一件事情。
this 關鍵字介紹
? ? ? ?現在我以下面的代碼為例子:
class Date{public int year;public int month;public int day;public void initDate1(int year, int month, int day){year = year;month = month;day = day;}public void initDate2(int y, int m, int d){year = y;month = m;day = d;}public void printDate(){System.out.println(year + "年 " + month + "月 " + day + "日 ");}
}public class Test{public static void main(String[] args) {Date d1 = new Date();Date d2 = new Date();Date d3 = new Date();d1.initDate1(2024,5,13);d1.printDate();System.out.println("=====================");d1.initDate2(2024,5,13);d1.printDate();}
}
思考一下輸出結果是什么?
再談對象中成員變量
? ? ? ?對象中的成員變量和神奇,一旦對象創建好,對象里面的成員變量其實會被賦值成默認值,所以上面才會出現0年0月0日~~
? ? ? ?根據上一篇的JVM內畫圖,我們來看一下對象的分布:
對象在堆里是只包含成員變量,沒有成員方法的~~
來現在解決一下為什么下面的代碼不行~~
public void initDate1(int year, int month, int day){year = year;month = month;day = day;}
因為程序遵循局部變量優先使用原則,所以上面的代碼相當于是局部變量自己給自己賦值~~
如何解決?
添加 this 關鍵字就可以了
public void initDate1(int year, int month, int day){this.year = year;this.month = month;this.day = day;}
this 關鍵字能讓編譯器識別這是成員變量而不是局部變量~~
因此建議大家習慣性地使用this關鍵字~~
再理解this
public class Test{public static void main(String[] args) {Date d1 = new Date();Date d2 = new Date();Date d3 = new Date();d1.initDate1(2024,5,13);d1.printDate();System.out.println("=====================");d2.initDate2(2024,5,14);d2.printDate();System.out.println("=====================");d3.initDate2(2024,5,15);d3.printDate();}
}
? ? ? ?問題來了,上面創建了三個對象,都調用了printDate()方法,這些方法是如何區分這是哪個對象的呢?
在Java中,調用成員方法時會發生隱式傳參:
public void initDate1(Date this, int year, int month, int day){this.year = year;this.month = month;this.day = day;}public void initDate2(Date this, int y, int m, int d){year = y;month = m;day = d;}public void printDate(Date this){System.out.println(year + "年 " + month + "月 " + day + "日 ");}
大家看到上面的 Date this(這個是可以不用寫的,寫了你會發現沒有報錯) 這個就是因為Java 自動幫你傳遞了這個對象,所以 this 其實就是可以指代這個對象時誰。
當你調用某個對象的成員方法時,Java會自動幫你把對象傳遞過去,并且使用 this 來接收這個對象,所以上面我們可以使用 this.year = year 來避免局部變量自我賦值,而是將局部變量賦值給對象的成員變量。
this與成員方法
由于this 就是指向對象的,所以我們可以在非靜態的成員方法中進行使用來調用其他的成員方法~~
靜態與非靜態會在下一篇文章中講解~~
構造方法
? ? ? ?構造方法的作用是給成員變量進行初始化的
創建格式:
修飾符 類名(形參列表){
? ? ? ?方法體
}
注意構造方法沒有返回值,并且和普通的方法一樣是可以發生方法的重載的~~
名字必須與類名相同,在創建對象時,由編譯器自動調用,并且在整個對象的生命周期內只調用一次。
再談對象的實例化
對象的示例化簡單來說可以分為兩步,第一步是分配內存空間,第二步是調用構造方法
一旦new 類名(參數) 的時候就會調用構造方法~
可是上面的代碼中,我們沒有寫過構造方法,代碼為什么會正常執行并且沒有報錯呢?
因為在Java中,如果你沒有寫過任何的構造方法的話,Java會給你自動提供一個空的構造方法(這個方法是空的,沒有任何效果)
但是如果你寫了構造方法的話,Java是不會幫你提供一個空的構造方法~~
例如下面的代碼:
class Dog{public String name;public Dog(int year){System.out.println(year + "出生了");}
}public class Test{public static void main(String[] args) {Dog dog = new Dog(2024);Dog dog2 = new Dog();}
}
dog2 是無法進行創建的,因為Dog的構造方法只有public Dog(int year),而沒有Dog()這個構造方法!!!
this與構造方法
在構造方法中是可以使用this關鍵字來調用構造方法的~
調用格式比較特殊,this(參數)
在構造方法中可以調用其他構造方法,但必須放在第一行!!!
并且使用 this 調用構造方法的時候不能形成環!!!
下面代碼就是成環的表現~~
這是不被允許的!!!
public Dog(){this(2024);}public Dog(int year){this();System.out.println(year + "出生了");}
總結
this 關鍵字:
- this.當前對象的成員變量
- this.當前對象的非靜態的成員方法
- this() 調用其他的構造方法