Java中你真的會用Constructor構造器嗎之看完本篇你就真的會了
引言
相信大家對于java里的構造器應該都是有了解的,這次我們來了解一些構造器的不同使用方式,了解構造器的調用順序,最后可以靈活的在各種情況下定義使用構造器,進一步優(yōu)化我們的代碼;
構造器簡介
還是簡單介紹一下構造器到底是什么吧,
構造器是類中一種特殊的方法,通過調用構造器來完成對象的創(chuàng)建,以及對象屬性的初始化操作。
構造器定義方式:
[修飾符列表] 構造器名(形式參數(shù)列表){
構造方法體;
}
構造器有以下幾個特點:
- 構造器名和類名一致;
- 構造器用來創(chuàng)建對象,以及完成屬性初始化操作;
- 構造器返回值類型不需要寫,包括 void 也不能寫
- 構造器的返回值類型實際上是當前類的類型
- 一個類中可以定義多個構造器,這些構造器構成方法重載
構造器的使用其實很常見,調用語法為:new 構造器名(實際參數(shù)列表) ,假如我們現(xiàn)在有一個Person類,調用默認構造器:
Person p = new Person(); // 這里的Person()其實就是調用的默認構造器??!
構造器的使用需要注意:
當一個類沒有顯式的定義任何構造器的時候,系統(tǒng)默認提供無參數(shù)構造器,當顯式的定義構造器之后,系統(tǒng)不再提供無參數(shù)構造器。無參數(shù)構造器又叫做缺省構造器,或默認構造器;
構造器重載
雖然系統(tǒng)會給我們提供默認構造器并賦予初始值,我們自己也可以顯式的指定初始值,但是可不可以多種構造器同時存在一個類中呢?
這就需要重載構造器,因為構造器也是方法的一種,方法都可以重載,構造器當然也可以;
構造器重載方式和方法重載差不多,只需要構造器名相同,參數(shù)列表不同就可以了;
測試代碼:
public class ConstructorOverloadTest {
String name;
int age;
// 默認構造器(無參構造器)
ConstructorOverloadTest() {}
// 含參構造器 重載版
ConstructorOverloadTest(String myName, int myAge) {
this.name = myName;
this.age = myAge;
}
public static void main(String[] args) {
// 調用無參構造器
var p1 = new ConstructorOverloadTest();
System.out.println("p1的初始化結果為:");
System.out.println("姓名 :" + p1.name);
System.out.println("年齡:" + p1.age);
// 調用有參構造器
var p2 = new ConstructorOverloadTest("張三", 18);
System.out.println("p2的初始化結果為:");
System.out.println("姓名 :" + p2.name);
System.out.println("年齡:" + p2.age);
}
}
輸出結果為:
p1的初始化結果為:
姓名 :null
年齡:0
p2的初始化結果為:
姓名 :張三
年齡:18
當然這里只寫了一個重載版本,還可以定義多個重載版本,這里就不列舉了;我們只需要能夠根據(jù)實際情況使用恰當?shù)闹剌d就可以了,不用都寫出來;
構造器間的相互調用
如果系統(tǒng)中有多個構造器,并且我們想要通過一個構造器A調用另一個構造器B,該怎么辦?
可能有人會想到調用構造器肯定要創(chuàng)建一個對象啊,所以直接new一個不就可以了嘛; 但是我們通過一個構造器調用另一個構造器的目的就是為了簡化代碼的,這樣反而又多此一舉了;
如果不new一個新的對象,那么我們可以通過 this引用 來調用相應的構造器;
還是不太明白?看看下面的代碼!
測試代碼如下:
public class ConstructorTest01 {
public static void main(String[] args) {
// 調用兩個參數(shù)的構造器
Person p1 = new Person("張三", 18);
System.out.println("兩個參數(shù)的構造器初始化結果為:");
System.out.println("姓名:" + p1.name);
System.out.println("身份證號:" + p1.idNum);
System.out.println("年齡:" + p1.age);
// 調用三個參數(shù)的構造器
Person p2 = new Person("李四", "6666666", 20);
System.out.println("三個參數(shù)的構造器初始化結果為:");
System.out.println("姓名:" + p2.name);
System.out.println("身份證號:" + p2.idNum);
System.out.println("年齡:" + p2.age);
}
}
class Person {
String name;
String idNum;
int age;
// 有兩個參數(shù)的構造器
Person(String myName, int myAge) {
this.name = myName;
this.age = myAge;
}
// 有三個參數(shù)的構造器
Person(String myName, String myIdNum, int myAge) {
// 通過this調用兩個參數(shù)的構造器
this(myName, myAge);
this.idNum = myIdNum;
}
}
輸出結果為:
兩個參數(shù)的構造器初始化結果為:
姓名:張三
身份證號:null
年齡:18
三個參數(shù)的構造器初始化結果為:
姓名:李四
身份證號:6666666
年齡:20
通過this調用有一點需要注意:
使用this調用另一個重載的構造器只能在構造器中使用,且必須作為構造器執(zhí)行體的第一條語句
可能有人會問:如果在有三個參數(shù)的構造器里面不用this指針,而是直接把上一個構造器的代碼復制過來不行嗎?
當然可以,但是不建議;我們得知道為什么要存在this這個調用構造器的方法,它不是無緣無故存在的;在軟件開發(fā)時有一個原則:不要把相同代碼重復寫兩次以上;因為一旦一個構造器內的初始代碼需要修改,那么很有可能其他的構造器初始代碼也要跟著修改,如果構造版本多的話是非常麻煩的;而使用this恰恰可以避免這個問題,只需要修改一個地方,其他幾個構造器就隨著更改了;這樣的代碼不僅更加簡潔,而且降低了維護成本;
子類構造器調用父類構造器
繼承有一個規(guī)則是:當繼承發(fā)生后,子類不會獲得父類的構造器;
但是子類的構造器可以通過一定方法區(qū)調用父類構造器,類似于通過this引用調用重載的構造器;
而子類構造器調用父類的構造器不用this關鍵字,這里有一個新的關鍵字:super
super和this用法差不多,使用它就可以實現(xiàn)子類構造器調用父類的構造器;
看個代碼就明白了:
測試代碼:
class Person {
String name;
int age;
// 父類的構造函數(shù)
Person(String myName, int myAge) {
this.name = myName;
this.age = myAge;
}
}
public class Kids extends Person{
String school;
// 子類的構造函數(shù)
Kids(String myName, int myAge, String mySchool) {
// 通過super來調用父類構造器初始化過程
super(myName, myAge);
this.school = mySchool;
}
public static void main(String[] args) {
Kids k = new Kids("張三", 5, "奧特曼小學");
System.out.println("name:" + k.name);
System.out.println("age:" + k.age);
System.out.println("school:" + k.school);
}
}
輸出結果為:
name:張三
age:5
school:奧特曼小學
通過代碼可以看出來super確實和this非常像,無非就是super調用父類構造器,this調用同一個類的重載的構造器;
且使用super也需要注意:
super調用父類構造器也必須在子類構造器執(zhí)行體的第一行,所以this和super不會同時出現(xiàn);
構造器的調用順序
這里先看一個代碼:
class Creature {
Creature() {
System.out.println("Creature的無參構造器的調用");
}
}
class Person extends Creature {
Person(String name) {
System.out.println("Person的一個參數(shù)構造器的調用");
}
Person(String name, int age) {
// this調用同一個類中重載的構造器
this(name);
System.out.println("Person的兩個參數(shù)構造器的調用");
}
}
public class Kids02 extends Person {
Kids02() {
// 顯式調用父類的兩個參數(shù)的構造器
super("張三", 18);
System.out.println("Kids02的無參構造器的調用");
}
public static void main(String[] args) {
// 創(chuàng)建一個Kids02對象
new Kids02();
}
}
這個代碼中,Person類繼承了Creature類,Kids02類繼承了Person類,Perosn類中又通過this調用同一個類中重載的構造器,
Kids02類中用super 顯式調用父類的兩個參數(shù)的構造器;
那么輸出是什么呢?到底先調用的是誰的構造器,最后調用的誰的構造器?
輸出如下:
Creature的無參構造器的調用
Person的一個參數(shù)構造器的調用
Person的兩個參數(shù)構造器的調用
Kids02的無參構造器的調用
通過這個代碼和結果,可以總結出來,父類構造器總在子類構造器之前執(zhí)行,或者可以說:
創(chuàng)建任何對象總是從該類所在繼承樹最頂層類的構造器開始執(zhí)行的,然后依次向下執(zhí)行;
對于this和super也是一樣;
這個代碼好好理解一下,就會對構造器間的關系體會更深;
總結
對象的初始化離不開構造器,對構造器的學習真正需要的還是大量的練習,這些內容也是需要熟練掌握的;這關乎著你在實際開發(fā)應用過程中對整個代碼的影響和對象能否恰到好處的初始化;希望你能夠真正學會并應用到這些方法,且通過這篇文章能有所收獲!
ps:如果內容有問題歡迎討論?。?/p>
到此這篇關于Java中你真的會用Constructor構造器嗎之看完本篇你就真的會了的文章就介紹到這了,更多相關Java 構造器 Constructor內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
spring boot加入攔截器Interceptor過程解析
這篇文章主要介紹了spring boot加入攔截器Interceptor過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-10-10
Spring中的@CrossOrigin注冊處理方法源碼解析
這篇文章主要介紹了Spring中的@CrossOrigin注冊處理方法源碼解析,@CrossOrigin是基于@RequestMapping,@RequestMapping注釋方法掃描注冊的起點是equestMappingHandlerMapping.afterPropertiesSet(),需要的朋友可以參考下2023-12-12
深入探究TimSort對歸并排序算法的優(yōu)化及Java實現(xiàn)
這篇文章主要介紹了TimSort歸并排序的優(yōu)化及Java實現(xiàn),TimSort 是一個歸并排序做了大量優(yōu)化的版本,需要的朋友可以參考下2016-05-05
Java隨機值設置(java.util.Random類或Math.random方法)
在編程中有時我們需要生成一些隨機的字符串作為授權碼、驗證碼等,以確保數(shù)據(jù)的安全性和唯一性,這篇文章主要給大家介紹了關于Java隨機值設置的相關資料,主要用的是java.util.Random類或Math.random()方法,需要的朋友可以參考下2024-08-08

