您好,登錄后才能下訂單哦!
這篇文章給大家介紹Java中類與對象的相關(guān)知識點(diǎn)有哪些,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
C語言是面向過程的,關(guān)注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題。
JAVA是基于面向?qū)ο蟮模P(guān)注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成。
面向過程注重的是過程,指的是在整個過程中所涉及的行為。
面向?qū)ο笞⒅氐氖菍ο?,也就是參與過程所涉及到的主體。是通過邏輯將一個個功能實(shí)現(xiàn)連接起來。
面向過程: 1.把冰箱打開 2. 把東西放入 3. 冰箱關(guān)起來 面向?qū)ο螅?打開冰箱,儲存,關(guān)閉都是對冰箱的操作,是冰箱被動的行為。冰箱就是一個對象,所以只要操作冰箱所具備的功能,都要定義在冰箱中(即類)。
類就是一類對象的統(tǒng)稱。對象就是這一類具體化的一個實(shí)例。類可以比喻為一個一個的模板,里面可能會含有許多屬性或者功能。而按照模板實(shí)例化產(chǎn)生的叫對象。一個模板能夠?qū)嵗鄠€對象。
聲明一個類就是創(chuàng)建一個新的數(shù)據(jù)類型,而類在 Java 中屬于引用類型, Java 使用關(guān)鍵字 class 來聲明類。下面是聲明類的定義:
// 創(chuàng)建類 class <class_name>{ field;//成員屬性 method;//成員方法 } // 實(shí)例化對象 <class_name> <對象名> = new <class_name>();
class為定義類的關(guān)鍵字,ClassName為類的名字,{}中為類的主體。
類中的元素稱為:成員屬性。類中的函數(shù)稱為:成員方法。
示例:這里就聲明了一個類
class Person { public int age;//成員屬性 實(shí)例變量 public String name; public String sex; public void eat() {//成員方法 System.out.println("吃飯!"); } public void sleep() { System.out.println("睡覺!"); } }
class Person { public int age;//成員屬性 實(shí)例變量 public String name; public String sex; public void eat() {//成員方法 System.out.println("吃飯!"); } public void sleep() { System.out.println("睡覺!"); } } public class Main{ public static void main(String[] args) { Person person = new Person();//通過new實(shí)例化對象 person.eat();//成員方法調(diào)用需要通過對象的引用調(diào)用 person.sleep(); //產(chǎn)生對象 實(shí)例化對象 Person person2 = new Person(); Person person3 = new Person(); } }
輸出結(jié)果為:
吃飯!
睡覺!
注意事項(xiàng):
new 關(guān)鍵字用于創(chuàng)建一個對象的實(shí)例。
使用 . 來訪問對象中的屬性和方法。
同一個類可以創(chuàng)建多個實(shí)例。
類的成員可以包含以下:字段、方法、代碼塊、內(nèi)部類和接口等。此處重點(diǎn)介紹前面三個。
在類中、而方法外部定義的變量稱為 “字段” 或 “屬性” 或 “成員變量”(三種稱呼都可以, 一般不會嚴(yán)格區(qū)分)
class Person { public String name; // 字段 public int age; } class Test { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name); System.out.println(person.age); } } // 執(zhí)行結(jié)果 null 0
注意事項(xiàng):
使用 . 訪問對象的字段。
“訪問” 既包含讀, 也包含寫.
對于一個對象的字段如果沒有顯式設(shè)置初始值, 那么會被設(shè)置一個默認(rèn)的初值。
默認(rèn)值規(guī)則
對于各種數(shù)字類型, 默認(rèn)值為 0.
對于 boolean 類型, 默認(rèn)值為 false.
對于引用類型(String, Array, 以及自定制類), 默認(rèn)值為 null
null 在 Java 中為 “空引用”, 表示不引用任何對象. 類似于 C 語言中的空指針. 如果對 null 進(jìn)行 . 操作就會引發(fā)異常。
class Person { public String name; public int age; } class Test { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name.length()); // 獲取字符串長度 } } // 執(zhí)行結(jié)果 Exception in thread "main" java.lang.NullPointerException //空指針異常 at Test.main(Test.java:9)
字段就地初始化:
雖然此時我們都不想屬性都為默認(rèn)值而需要就地初始化,但是后面我們會講到盡量不要用字段的就地初始化,否則程序會顯得非常死板。
class Person { public String name = "張三"; public int age = 18; } class Test { public static void main(String[] args) { Person person = new Person(); System.out.println(person.name); System.out.println(person.age); } } // 執(zhí)行結(jié)果 張三 18
引用中需要注意的地方:
1.下面這段代碼指的是person2這個引用指向person引用指向的對象。
public static void main(String[] args) { Person person = new Person(); Person person2 = person; }
2.一個引用無法指向多個對象,即使多次指向?qū)ο蠛?,最后指向的只能是最后一次指向的對象?/p>
3.我們知道了局部變量是在棧上開辟內(nèi)存的,而它存儲的是地址,也稱為引用。那么引用一定是在棧上嗎?? 答案是否定的,看下面的代碼:
class Person { public String name ; public int age ; } public class TestDemo { Person person = new Person(); public static void main(String[] args) { TestDemo testDemo = new TestDemo(); } }
內(nèi)存布局:
用于描述一個對象的具體行為叫做方法。
class Person { public int age = 18; public String name = "張三"; public void show() { //show方法 System.out.println("我叫" + name + ", 今年" + age + "歲"); } } class Test { public static void main(String[] args) { Person person = new Person(); person.show(); } } // 執(zhí)行結(jié)果 我叫張三, 今年18歲
這樣的 show 方法是和 person 實(shí)例相關(guān)聯(lián)的,如果創(chuàng)建了其他實(shí)例,并且講類當(dāng)中的屬性重新賦值,那么 show 的行為就會發(fā)生變化。
Person person2 = new Person(); person2.name = "李四"; person2.age = 20; person2.show(); // 執(zhí)行結(jié)果 我叫李四, 今年20歲
static關(guān)鍵字的作用:
修飾屬性 (內(nèi)存開辟在方法區(qū)中)
修飾方法 (只有調(diào)用方法時才在棧中開辟內(nèi)存)
代碼塊(本課件中會介紹)
修飾類(后面講內(nèi)部類會講到)
1)修飾屬性:Java靜態(tài)屬性和類相關(guān), 和具體的實(shí)例無關(guān)。換句話說, 同一個類的不同實(shí)例共用同一個靜態(tài)屬性。
class TestDemo{ public int a; public static int count; } public class Main{ public static void main(String[] args) { TestDemo t1 = new TestDemo(); t1.a++; TestDemo.count++; System.out.println(t1.a); System.out.println(TestDemo.count); System.out.println("============"); TestDemo t2 = new TestDemo(); t2.a++; TestDemo.count++; System.out.println(t2.a); System.out.println(TestDemo.count); } }
輸出結(jié)果:
1
1
============
1
2
若需要調(diào)用類當(dāng)中的有static的屬性,則只需要類名.屬性 即可調(diào)用,而不能對象名.屬性 來調(diào)用,否則編譯器會報(bào)警告。
被static修飾的成員變量的內(nèi)存在方法區(qū)中開辟,因?yàn)樗粚儆趯ο笠虼瞬辉诙焉祥_辟內(nèi)存;而在方法區(qū)中開辟內(nèi)存開辟且僅開辟一次。
下圖體現(xiàn)出對象、類、屬性(實(shí)例成員變量、靜態(tài)成員變量)之間的關(guān)系。
2) 修飾方法
如果在任何方法上應(yīng)用 static 關(guān)鍵字,此方法稱為靜態(tài)方法。
靜態(tài)方法屬于類,而不屬于類的對象。
可以直接調(diào)用靜態(tài)方法,而無需創(chuàng)建類的實(shí)例。
靜態(tài)方法可以訪問靜態(tài)數(shù)據(jù)成員,并可以更改靜態(tài)數(shù)據(jù)成員的值。
class TestDemo{ public int a; public static int count; public static void change() { count = 100; //a = 10; error 不可以訪問非靜態(tài)數(shù)據(jù)成員 } } public class Main{ public static void main(String[] args) { TestDemo.change();//無需創(chuàng)建實(shí)例對象 就可以調(diào)用 System.out.println(TestDemo.count); } }
輸出結(jié)果:
100
注意事項(xiàng):靜態(tài)方法和實(shí)例無關(guān), 而是和類相關(guān). 因此這導(dǎo)致了兩個情況:
靜態(tài)方法不能直接使用非靜態(tài)數(shù)據(jù)成員或調(diào)用非靜態(tài)方法(非靜態(tài)數(shù)據(jù)成員和方法都是和實(shí)例相關(guān)的).
this和super兩個關(guān)鍵字不能在靜態(tài)上下文中使用(this 是當(dāng)前實(shí)例的引用, super是當(dāng)前實(shí)例父類實(shí)例的引用, 也是和當(dāng)前實(shí)例相關(guān))
因?yàn)閙ain方法為static方法,因此只能實(shí)例化其他類后才能調(diào)用其他類中的實(shí)例成員變量或?qū)嵗蓡T方法,當(dāng)然main方法也可以直接用類名去調(diào)用其他類中的靜態(tài)成員變量或靜態(tài)方法。
靜態(tài)變量是屬于類的,因此在方法中不能定義被static修飾的靜態(tài)方法(包括普通方法和靜態(tài)方法),但是可以初始化或者使用。
普通方法中可以調(diào)用靜態(tài)方法,而靜態(tài)方法中不能調(diào)用普通方法,卻又可以調(diào)用其它的靜態(tài)方法。
觀察以下代碼及理解其內(nèi)存布局:
class Person { public int age;//實(shí)例變量 存放在對象內(nèi) public String name;//實(shí)例變量 public String sex;//實(shí)例變量 public static int count;//類變量也叫靜態(tài)變量,編譯時已經(jīng)產(chǎn)生,屬于類本身,且只有一份。存放在方法區(qū) public final int SIZE = 10;//被final修飾的叫常量,也屬于對象。 被final修飾,后續(xù)不可更改 public static final int COUNT = 99;//靜態(tài)的常量,屬于類本身,只有一份 被final修飾,后續(xù)不可更 改 //實(shí)例成員函數(shù) public void eat() { int a = 10;//局部變量 System.out.println("eat()!"); } //實(shí)例成員函數(shù) public void sleep() { System.out.println("sleep()!"); } //靜態(tài)成員函數(shù) public static void staticTest(){ //不能訪問非靜態(tài)成員 //sex = "man"; error System.out.println("StaticTest()"); } } public class Main{ public static void main(String[] args) { //產(chǎn)生對象 實(shí)例化對象 Person person = new Person();//person為對象的引用 System.out.println(person.age);//默認(rèn)值為0 System.out.println(person.name);//默認(rèn)值為null //System.out.println(person.count);//會有警告! //正確訪問方式: System.out.println(Person.count); System.out.println(Person.COUNT); Person.staticTest(); //總結(jié):所有被static所修飾的方法或者屬性,全部不依賴于對象。 person.eat(); person.sleep(); } }
輸出結(jié)果為:
0
null
0
99
StaticTest()
eat()!
sleep()!
數(shù)據(jù)屬性的內(nèi)存布局:
什么是封裝??簡單地來說,在我們寫代碼的時候經(jīng)常會涉及兩種角色: 類的實(shí)現(xiàn)者和類的調(diào)用者,而封裝能夠使得類的調(diào)用者不必關(guān)系類的實(shí)現(xiàn)者是如何實(shí)現(xiàn)類的,只要知道類中有什么方法直接調(diào)用即可。降低了類使用者的學(xué)習(xí)和使用成本, 從而降低了復(fù)雜程度。
private/ public 這兩個關(guān)鍵字是訪問修飾限定符。
被 public 修飾的成員變量或者成員方法, 可以直接被類的調(diào)用者使用被 private 修飾的成員變量或者成員方法, 不能被類的調(diào)用者使用
直接使用public:
class Person { public String name = "張三"; public int age = 18; } class Test { public static void main(String[] args) { Person person = new Person(); System.out.println("我叫" + person.name + ", 今年" + person.age + "歲"); } } // 執(zhí)行結(jié)果 我叫張三, 今年18歲
這樣的代碼導(dǎo)致類的使用者(main方法的代碼)必須要了解 Person 類內(nèi)部的實(shí)現(xiàn), 才能夠使用這個類,學(xué)習(xí)成本較高。
一旦類的實(shí)現(xiàn)者修改了代碼(例如把 name 改成 myName), 那么類的使用者就需要大規(guī)模的修改自己的代碼, 維護(hù)成本較高。
使用private:
class Person { private String name = "張三"; private int age = 18; public void show() { System.out.println("我叫" + name + ", 今年" + age + "歲"); } } class Test { public static void main(String[] args) { Person person = new Person(); person.show(); } } // 執(zhí)行結(jié)果 我叫張三, 今年18歲
此時字段已經(jīng)使用 private 來修飾,類的調(diào)用者(main方法中)不能直接使用. 而需要借助 show 方法. 此時類的使用者就不必了解 Person 類的實(shí)現(xiàn)細(xì)節(jié)。
同時如果類的實(shí)現(xiàn)者修改了字段的名字, 類的調(diào)用者不需要做出任何修改(類的調(diào)用者根本訪問不到 name, age這樣的字段)
private 不光能修飾字段, 也能修飾方法
通常情況下我們會把字段設(shè)為 private 屬性, 但是方法是否需要設(shè)為 public, 就需要視具體情形而定. 一般我們希望一個類只提供 “必要的” public 方法, 而不應(yīng)該是把所有的方法都設(shè)為 public。
被private修飾的字段不等于無法在類外使用該字段。那么如何在類外中獲取被private修飾的字段呢?此處jdk為我們提供了getter和setter方法 。
代碼示例:
class Person { private String name;//實(shí)例成員變量 private int age; public void setName(String name){ //name = name;//不能這樣寫,否則name仍為0,局部變量優(yōu)先 this.name = name;//this引用,表示調(diào)用該方法的對象的name } public String getName(){ return name; } public void show(){ System.out.println("name: "+name+" age: "+age); } } public static void main(String[] args) { Person person = new Person(); person.setName("caocao"); String name = person.getName(); System.out.println(name); person.show(); } // 運(yùn)行結(jié)果 caocao name: caocao age: 0
注意事項(xiàng):
getName 即為 getter 方法, 表示獲取這個成員的值
setName 即為 setter 方法, 表示設(shè)置這個成員的值
當(dāng)set方法的形參名字和類中的成員屬性的名字一樣的時候,如果不使用this, 相當(dāng)于自賦值. this 表示當(dāng)前實(shí)例的引用
不是所有的字段都一定要提供 setter / getter 方法, 而是要根據(jù)實(shí)際情況決定提供哪種方法
在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在 VSCode 中可以使用鼠標(biāo)右鍵菜單 -> 源代碼操作 中自動生成 setter / getter 方法
構(gòu)造方法是一種特殊方法, 使用關(guān)鍵字new實(shí)例化新對象時會被自動調(diào)用, 用于完成初始化操作。
new 執(zhí)行過程:
為對象分配內(nèi)存空間
調(diào)用對象的構(gòu)造方法
語法規(guī)則:
方法名稱必須與類名稱相同。
構(gòu)造方法沒有返回值類型聲明。
每一個類中一定至少存在一個構(gòu)造方法(如果沒有明確定義,則系統(tǒng)自動生成一個無參構(gòu)造方法)
注意事項(xiàng):
如果類中沒有提供任何的構(gòu)造函數(shù),那么編譯器會默認(rèn)生成一個不帶有參數(shù)的構(gòu)造函數(shù)
若類中定義了構(gòu)造方法,則默認(rèn)的無參構(gòu)造將不再生成,如果再需要調(diào)用無參的構(gòu)造方法則需要手動寫一個。
構(gòu)造方法支持重載,規(guī)則和普通方法的重載一致。(對返回值不作要求,方法名相同,參數(shù)不同可包括參數(shù)個數(shù)不同或參數(shù)類型不同)
代碼示例:
class Person { private String name;//實(shí)例成員變量 private int age; private String sex; //默認(rèn)構(gòu)造函數(shù) 構(gòu)造對象 public Person() { this.name = "caocao"; this.age = 10; this.sex = "男"; } //帶有3個參數(shù)的構(gòu)造函數(shù) 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();//調(diào)用不帶參數(shù)的構(gòu)造函數(shù) 如果程序沒有提供會調(diào)用不帶參數(shù)的構(gòu)造函數(shù) p1.show(); Person p2 = new Person("zhangfei",80,"男");//調(diào)用帶有3個參數(shù)的構(gòu)造函數(shù) p2.show(); } } // 執(zhí)行結(jié)果 name: caocao age: 10 sex: 男 name: zhangfei age: 80 sex: 男
this表示當(dāng)前對象引用(注意不是當(dāng)前對象),可以借助 this 來訪問對象的字段和方法。this表示當(dāng)前對象引用是因?yàn)樵趧?chuàng)建對象的過程中會調(diào)用合適的構(gòu)造方法,而構(gòu)造方法內(nèi)部能夠用this關(guān)鍵字,而對象在創(chuàng)建的過程當(dāng)中(對象還未被創(chuàng)建出來)就使用了this關(guān)鍵字,證明this指向的是當(dāng)前對象的引用。
class Person { private String name;//實(shí)例成員變量 private int age; private String sex; //默認(rèn)構(gòu)造函數(shù) 構(gòu)造對象 public Person() { //this調(diào)用構(gòu)造函數(shù) this("bit", 12, "man");//必須放在第一行進(jìn)行顯示 } //這兩個構(gòu)造函數(shù)之間的關(guān)系為重載。 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 person = new Person();//調(diào)用不帶參數(shù)的構(gòu)造函數(shù) person.show(); } } // 執(zhí)行結(jié)果 name: bit age: 12 sex: man
this既可以指的是當(dāng)前對象的引用中的屬性,也可以在構(gòu)造方法內(nèi)部使用(若是調(diào)用其它構(gòu)造方法則只能在構(gòu)造方法內(nèi)部使用)。
代碼示例:
class Person { private String name ; private int age ; public Person() { this("zjr",18); } public Person(String name ,int age) { System.out.println("name:"+name+" age:"+age); } } public class TestDemo { public static void main(String[] args) { Person person =new Person(); } }
運(yùn)行結(jié)果:
結(jié)論:
如果用this關(guān)鍵字調(diào)用其它構(gòu)造方法的放在第二行則會報(bào)錯;并且調(diào)用構(gòu)造方法只能調(diào)用一次。要習(xí)慣于使用this關(guān)鍵字,this關(guān)鍵字能夠有效地避免在對象的屬性賦值時兩邊變量名相同會出錯。
字段的初始化方式有:
就地初始化
使用構(gòu)造方法初始化
使用代碼塊初始化
前兩種初始化方式都已介紹過,那么如何單純用代碼塊來初始化屬性??
使用 {} 定義的一段代碼.
根據(jù)代碼塊定義的位置以及關(guān)鍵字,又可分為以下四種:
普通代碼塊(只做了解)
構(gòu)造塊
靜態(tài)塊
同步代碼塊(后續(xù)講解多線程部分再談)
普通代碼塊:定義在方法中的代碼塊。
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); } } // 執(zhí)行結(jié)果 x1 = 10 x2 = 100
構(gòu)造塊:定義在類中的代碼塊(不加修飾符)。也叫:實(shí)例代碼塊。構(gòu)造代碼塊一般用于初始化實(shí)例成員變量。
代碼示例:
class Person{ private String name;//實(shí)例成員變量 private int age; private String sex; public Person() { System.out.println("I am Person init()!"); } //實(shí)例代碼塊 { 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(); } } // 運(yùn)行結(jié)果 I am instance init()! I am Person init()! name: bit age: 12 sex: man
注意事項(xiàng): 實(shí)例代碼塊優(yōu)先于構(gòu)造函數(shù)執(zhí)行。
使用static定義的代碼塊。一般用于初始化靜態(tài)成員屬性。
class Person{ private String name;//實(shí)例成員變量 private int age; private String sex; private static int count = 0;//靜態(tài)成員變量 由類共享數(shù)據(jù) 方法區(qū) public Person(){ System.out.println("I am Person init()!"); } //實(shí)例代碼塊 { this.name = "bit"; this.age = 12; this.sex = "man"; System.out.println("I am instance init()!"); } //靜態(tài)代碼塊 static { count = 10;//只能訪問靜態(tài)數(shù)據(jù)成員 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();//靜態(tài)代碼塊是否還會被執(zhí)行? } }
注意:
靜態(tài)代碼塊不管生成多少個對象,其只會執(zhí)行一次,且是最先執(zhí)行的。
靜態(tài)代碼塊執(zhí)行完畢后, 實(shí)例代碼塊(構(gòu)造塊)執(zhí)行,再然后是構(gòu)造函數(shù)執(zhí)行。
只有靜態(tài)代碼塊不需要實(shí)例化對象就能夠執(zhí)行。只要調(diào)用了類中的某個變量或方法(靜態(tài))就能夠被執(zhí)行。靜態(tài)代碼塊的執(zhí)行是在類的加載過程執(zhí)行的,因此只執(zhí)行一次。
靜態(tài)代碼塊的使用基變量本上跟static方法差不多,也不能出現(xiàn)this與定義被static修飾的變量,不依賴于對象。
靜態(tài)代碼塊中可以使用靜態(tài)變量,但是對于被靜態(tài)修飾的代碼塊與變量執(zhí)行的先后順序又不一樣,它是根據(jù)代碼的執(zhí)行先后順序決定的(前提是在初始化時已經(jīng)賦予初值,否則仍然遵循靜態(tài)代碼塊先執(zhí)行的順序)。例如:
class Person { public String name ; public int age ; public static int count = 10 ; static { count=99; System.out.println("靜態(tài)"); } { System.out.println("實(shí)例"); } } public class TestDemo { public static void main(String[] args) { Person person = new Person(); System.out.println(Person.count); } }
運(yùn)行結(jié)果:
交換執(zhí)行先后順序:
class Person { public String name ; public int age ; static { count=99; System.out.println("靜態(tài)"); } public static int count = 10 ; { System.out.println("實(shí)例"); } } public class TestDemo { public static void main(String[] args) { Person person = new Person(); System.out.println(Person.count); } }
因此如果靜態(tài)變量沒賦初值,則結(jié)果是靜態(tài)代碼塊內(nèi)賦的值;如果靜態(tài)變量賦了初值,則按照執(zhí)行順序決定改變量最后的值,除了變量賦值語句執(zhí)行順序不同以外,靜態(tài)代碼塊內(nèi)的語句都是先執(zhí)行的。
代碼塊中的重點(diǎn)是主要了解實(shí)例代碼塊、靜態(tài)代碼塊、構(gòu)造方法的運(yùn)行順序??偨Y(jié):先運(yùn)行的是靜態(tài)代碼塊,再運(yùn)行實(shí)例代碼塊(構(gòu)造代碼塊),最后運(yùn)行構(gòu)造方法。靜態(tài)代碼塊內(nèi)的只運(yùn)行一次。
我們剛剛注意到,我們在把對象的屬性進(jìn)行打印的時候,我們是自己實(shí)現(xiàn)了show函數(shù)。但在Java中它提供了一個給我們打印屬性的方法。叫toString方法。
代碼示例:
class Person { private String name; private int age; public Person(String name,int age) { this.age = age; this.name = name; } public void show() { System.out.println("name:"+name+" " + "age:"+age); } //重寫Object的toString方法 @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public class Main { public static void main(String[] args) { Person person = new Person("caocao",19); person.show(); System.out.println(person); } } // 執(zhí)行結(jié)果 name:caocao age:19 Person{name='caocao', age=19}
注意事項(xiàng):
toString 方法會在 println 的時候被自動調(diào)用
將對象轉(zhuǎn)成字符串這樣的操作我們稱為序列化
toString 是 Object 類提供的方法, 我們自己創(chuàng)建的 Person 類默認(rèn)繼承自 Object 類, 可以重寫 toString 方法實(shí)現(xiàn)我們自己版本的轉(zhuǎn)換字符串方法. (關(guān)于繼承和重寫這樣的概念, 我們后面會重點(diǎn)介紹).
@Override 在 Java 中稱為 “注解”, 此處的 @Override 表示下面實(shí)現(xiàn)的 toString 方法是重寫了父類的方法,關(guān)于注解后面的課程會詳細(xì)介紹.
IDEA快速生成Object的toString方法快捷鍵:alt+f12(insert)
若我們要觀察println中的toString方法,則我們可以按住ctrl鍵,將鼠標(biāo)點(diǎn)到println中的位置。點(diǎn)入println中會看到如圖所示:
再按ctrl鍵將鼠標(biāo)放在紅框處點(diǎn)入,看到的如圖所示:
最后將進(jìn)入紅框內(nèi)的方法當(dāng)中,如圖所示:
因此我們能夠證實(shí)println中的toString方法是按照哈希值來進(jìn)行處理后打印的。因此如果我們重寫了它的toString方法來打印我們類中的屬性,則直接System.out.println(person);
即可(代碼如上所示),若沒有重寫println中的toString方法,則再用System.out.println(person);
時打印的結(jié)果為:類名+@+經(jīng)過哈希值處理的地址。
匿名只是表示沒有名字的對象
沒有引用的對象稱為匿名對象
匿名對象只能在創(chuàng)建對象時使用
如果一個對象只是用一次, 后面不需要用了, 可以考慮使用匿名對象
class Person { private String name; private int age; public Person(String name,int age) { this.age = age; this.name = name; } public void show() { System.out.println("name:"+name+" " + "age:"+age); } } public class Main { public static void main(String[] args) { new Person("caocao",19).show();//通過匿名對象調(diào)用方法 } } // 執(zhí)行結(jié)果 name:caocao age:19
重點(diǎn):注意匿名對象是如何調(diào)用類中的方法的。
代碼:
class Test { private int num ; public int getNum() { return num; } public void setNum(int num) { this.num = num; } } public class TestDemo2 { public static void Swap(Test test1,Test test2) { int tmp = test1.getNum(); test1.setNum(test2.getNum()) ; test2.setNum(tmp); } public static void main(String[] args) { Test test1 = new Test(); Test test2 = new Test(); test1.setNum(10); test2.setNum(20); System.out.println(test1.getNum()); System.out.println(test2.getNum()); Swap(test1,test2); System.out.println(test1.getNum()); System.out.println(test2.getNum()); } }
運(yùn)行結(jié)果:
關(guān)于Java中類與對象的相關(guān)知識點(diǎn)有哪些就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。