簡體   English   中英

在Constructor中調用方法

[英]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”代碼是子類構造函數的隱式部分,並且超類構造函數始終首先運行。

事件的順序是:

  • 創建對象並將所有實例變量清零。
  • 調用超類初始值設定項。
  • 調用超類構造函數。
  • 調用子類初始值設定項(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。
電話是這樣的

  • 子構造函數(因為構造函數從子級鏈接到父級)
  • 父構造函數
  • print方法(現在這里i沒有初始化coz子構造函數還沒有完成所以它打印的默認值為i ,即0)
  • 現在完成父構造函數后,子構造函數i得到它的值為45 -
  • 所以現在它在下一次打印方法打印時打印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被調用,它現在調用Childprint()方法,而i是在初始化Child類,所以現在i是你初始化值

您的孩子首先調用您父母的構造函數。 此時,我沒有使用45值初始化。 這就是它打印0(默認的int值)的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM