無意中翻到這條提問,看了很多回答,發(fā)現(xiàn)歧義較重,在這里解答一下,為了避免后邊來的朋友們踩雷
新手學習Java在構造方法這里很容易踩雷,構造方法是用來初始化的,這句勉強沒錯,可構造方法是用來創(chuàng)建對象的,這句就錯了,實際上,在構造方法執(zhí)行之前,類的內(nèi)存空間已經(jīng)開辟完成了,意思就是說對象已經(jīng)創(chuàng)建了,這步是由new關鍵字來完成的,而構造方法的作用是給類中的變量進行初始化賦值
假設,假設構造方法是用來創(chuàng)建對象用的,就無法解釋抽象類中為什么允許構造方法的存在,抽象類無法實例化,不能被創(chuàng)建,但是抽象類中允許構造方法的存在,舉例從側面證明一下:
abstract class Animal{
String name;
public Animal() {
System.out.println("抽象父類的無參構造");
}
abstract void eat();
}
class Dog extends Animal{
public Dog() {
super();
System.out.println("子類的無參構造");
}
@Override
void eat(){
}
}
public class Test {
public static void main(String[] args) {
Dog d = new Dog();
System.out.println(d.name);
}
}
隨手敲的很簡陋的一段代碼,不要在意格式上的不嚴謹,領會精神,這段代碼執(zhí)行后的結果為:
抽象父類的無參構造
子類的無參構造
null
當執(zhí)行Dog d = new Dog()這句代碼時,大致會分兩步,一是加載類,開辟類的內(nèi)存空間,這是由new完成的,第二步執(zhí)行構造方法,為類中的變量初始化賦值,在執(zhí)行Dog的無參構造時,系統(tǒng)會默認調(diào)用父類的無參構造,也就是super(),super關鍵字是對該類的父類進行的引用,它并不是一個對象,這也是個難點,感興趣的可以去查一下,而super()這句代碼可以簡單理解為調(diào)用這個類的父類的無參構造
在上述代碼中,父類Animal是一個抽象類,而抽象類不可被實例化,如果構造方法的作用是創(chuàng)建對象,在這一步上邏輯就無法自洽,而實際情況是:抽象類執(zhí)行了構造方法,但卻沒有創(chuàng)建對象,同時成員變量name也有了初始值null
構造方法是一種特殊的方法,與一般的方法不同是:
1.構造方法的名字必須與定義他的類名完全相同,沒有返回類型,甚至連void也沒有。
2.構造方法的調(diào)用是在創(chuàng)建一個對象時使用new操作進行的。構造方法的作用是初始化對象。
3.不能被static、final、synchronized、abstract和native修飾。構造方法不能被子類繼承。
class RectConstructor{
double length;
double width;
double area(){
return length*width;
}
//下面這個方法就是所謂的構造方法,沒有返回值,方法名與類名相同~~~
RectConstructor(double width,double length){//帶參數(shù)的構造方法
this.length=length;
this.width=width;
}
}
其實構造方法就是為了給類中成員賦初值~~~~~~~~~~~~~
構造方法和實例方法的區(qū)別 一、主要的區(qū)別在于三個方面:修飾符、返回值、命名1、和實例方法一樣,構造器可以有任何訪問的修飾符,public、private、protected或者沒有修飾符 ,都可以對構造方法進行修飾。
不同于實例方法的是構造方法不能有任何非訪問性質(zhì)的修飾符修飾,例如static、final、synchronized、abstract等都不能修飾構造方法。解釋:構造方法用于初始化一個實例對象,所以static修飾是沒有任何意義的;多個線程不會同時創(chuàng)建內(nèi)存地址相同的同一個對象,所以synchronized修飾沒有意義; 構造方法不能被子類繼承,所以final和abstract修飾沒有意義。
2、返回類型是非常重要的,實例方法可以返回任何類型的值或者是無返回值(void),而構造方法是沒有返回類型的,void也不行。3、至于命名就是構造方法與類名相同,當然了實例方法也可以與類名相同,但是習慣上我們?yōu)閷嵗椒臅r候通常是小寫的,另一方面也是與構造方法區(qū)分開。
而構造方法與類名相同,所以首字母一般大寫。下面看幾個例子熟悉一下: publicclassSample { privateintx; publicSample() { // 不帶參數(shù)的構造方法 this(1); } publicSample(intx) { //帶參數(shù)的構造方法 this.x=x; } publicintSample(intx) { //不是構造方法 returnx++; } } 上面的例子即使不通過注釋我們也很容易能區(qū)分開的,再看下面一個例子 publicclassMystery { privateString s; publicvoidMystery() { //不是構造方法 s = "constructor"; } voidgo() { System.out.println(s); } publicstaticvoidmain(String[] args) { Mystery m = newMystery(); m.go(); } } 程序執(zhí)行的結果為null,雖然說Mystery m = new Mystery();調(diào)用了Mystery 類的構造方法,但是public void Mystery()并不是構造方法,他只是一個普通的實例方法而已,那該類的構造方法哪去了呢?二、說到這就得說一下java的默認構造方法 我們知道,java語言中規(guī)定每個類至少要有一個構造方法,為了保證這一點,當用戶沒有給java類定義明確的構造方法的時候,java為我們提供了一個默認的構造方法,這個構造方法沒有參數(shù),修飾符是public并且方法體為空。
如果用戶有定義構造方法,就不會有默認構造方法!?。∑鋵嵞J的構造方法還分為兩種,一種就是剛剛說過的隱藏的構造方法,另一種就是顯示定義的默認構造方法.如果一個類中定義了一個或者多個構造方法,并且每一個構造方法都是帶有參數(shù)形式的,那么這個類就沒有默認的構造方法,看下面的例子。123456789 publicclassSample1{} publicclassSample2{ publicSample2(inta){System.out.println("My Constructor");} } publicclassSample3{ publicSample3(){System.out.println("My Default Constructor");} } 上面的三個類中Sample1有一個隱式的默認構造方法,下列語句Sample1 s1=new Sample()合法; Sample2沒有默認的構造方法,下列語句Sample2 s2=new Sample2()不合法,執(zhí)行會編譯錯誤 Sample3有一個顯示的默認構造方法,所以以下語句Sample3 s3=new Sample3();合法。
聲明:本網(wǎng)站尊重并保護知識產(chǎn)權,根據(jù)《信息網(wǎng)絡傳播權保護條例》,如果我們轉載的作品侵犯了您的權利,請在一個月內(nèi)通知我們,我們會及時刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學習鳥. 頁面生成時間:3.254秒