繁体   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