[英]Calling methods inside Constructor
下面我有兩個班。父母和孩子。 Child類繼承自Parent類。在Parent類構造函數中,我調用Parent類的print()方法。
當我在main()方法中為子類創建Object時,運行Parent類構造函數並調用Child類的print()方法而不是Parent類的print()方法。
Q1。 為什么會發生這種情況。
Q2。 為什么i的值為0
public class Sample
{
public static void main(String[] args)
{
Child objChild = new Child();
objChild.print();
}
}
class Parent
{
void print()
{
System.out.println("i Value");
}
Parent()
{
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("i Value = "+i);
}
}
OP
i Value = 0
i Value = 45
調用子方法的原因是因為虛方法調度是Java中的標准。 當您調用該方法時,它會根據對象的實際類型決定在運行時實際調用哪個方法。
至於它打印0的原因,那是因為i
尚未設置為45。 每個字段都使用該類型的默認值進行初始化,在整數的情況下為0
。 當你寫int i = 45
,編譯器將在構造函數中生成代碼以設置i = 45
。 但它會在調用父構造函數之后放置此代碼。 因此,在使用其預期值初始化變量之前,您將打印該變量。
Java實際上有一些非常明確的規則。 本質上,子類中的“int i = 45”代碼是子類構造函數的隱式部分,並且超類構造函數始終首先運行。
事件的順序是:
當你有一個最終的領域時,這真的很討厭。 您可以在示例中聲明“i”final並獲得相同的結果!
通常,在構造函數中調用非私有(或至少非最終)方法是在尋找麻煩,並且通常是令人討厭的錯誤的來源。 調用抽象方法是一個非常糟糕的主意(大部分時間)。
Java初學者 :我遇到了你的問題.. 1.當你創建子類的對象時,print()方法只在子類中調用而不在父類中調用,即使父類構造函數調用第一個bcoz,該對象是子類請參考以下示例。
public class Test
{
public static void main(String[] args)
{
//create the object of child class
Child child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent>> i ValueOne=");
}
Parent()
{
System.out.println("parent>> i ValueTwo=");
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("Child>>i Value = "+i);
}
}
輸出 :
parent>> i ValueTwo=
Child>>i Value = 0
2.如果此時創建父類對象,則調用父類中的print()方法。 請參考以下示例。
public class Test
{
public static void main(String[] args)
{
//create the object of Parent class
Parent parent = new Parent();
}
}
class Parent
{
void print()
{
System.out.println("parent>> i ValueOne=");
}
Parent()
{
System.out.println("parent>> i ValueTwo=");
print();
}
}
class Child extends Parent
{
int i = 45;
void print()
{
System.out.println("Child>>i Value = "+i);
}
}
輸出 :
parent>> i ValueTwo=
parent>> i ValueOne=
3.我認為你已經清楚了為什么i的值是0或45。
因為在第一次調用打印方法的時候i
沒有初始化為45所以它的打印0。
電話是這樣的
i
沒有初始化coz子構造函數還沒有完成所以它打印的默認值為i
,即0) i
得到它的值為45 - 首先,我沒有在您的Child
類中看到構造函數定義。
如果沒有為Child
類定義構造函數,則其默認構造函數為:
public Child() {
super();
}
凡super();
調用Parent
類構造函數(超類構造函數)。
但是,您在Child
類中定義了print()
方法,並且由於它與Parent
類中的方法具有相同的簽名(name + parameter),因此它將使用相同的簽名覆蓋其超類方法。
這就是你的Child
類調用Parent
類構造函數的原因,同時它調用自己的print()
方法。
-添加:
第一個i值為0,因為您沒有在Parent
類中初始化int變量i
,並且默認情況下uninitialized int變量的值為0。 后Parent
被調用,它現在調用Child
的print()
方法,而i
是在初始化Child
類,所以現在i
是你初始化值
您的孩子首先調用您父母的構造函數。 此時,我沒有使用45值初始化。 這就是它打印0(默認的int值)的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.