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