java 在构造函数中调用方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16183831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:08:51  来源:igfitidea点击:

Calling methods inside Constructor

java

提问by Java Beginner

Below I am Having Two classes.Parent and Child. The Child class inherits from Parent class .In Parent class constructor I am calling print() method of Parent class.

下面我有两个班级。父级和子级。Child 类继承自 Parent 类。在 Parent 类构造函数中,我正在调用 Parent 类的 print() 方法。

When I create Object for Child class in main() method the Parent class constructor runs and the Child class print() method is called instead of Parent class print() method.

当我在 main() 方法中为 Child 类创建 Object 时,父类构造函数会运行,并且会调用 Child 类的 print() 方法而不是父类的 print() 方法。

Q1. Why this Happens.

一季度。为什么会这样。

Q2. Why the value of i is 0

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

采纳答案by Antimony

The reason the child method is called is because virtual method dispatch is the norm in Java. When you call the method, it decides which method to actually call at runtime based on the actual type of the object.

调用子方法的原因是因为虚拟方法调度是 Java 中的规范。当您调用该方法时,它会根据对象的实际类型决定在运行时实际调用哪个方法。

As for why it prints 0, that's because ihasn't been set to 45 yet. Each field is initialized with a default value for that type, 0in the case of integers. When you write int i = 45, the compiler will generate code in the constructor to set i = 45. But it places this code afterthe parent constructor is called. Therefore, you're printing the variable before it is initialized with its intended value.

至于为什么打印0,那是因为i还没有设置成45。0在整数的情况下,每个字段都使用该类型的默认值进行初始化。编写时int i = 45,编译器会在构造函数中生成代码来设置i = 45。但是它会调用父构造函数之后放置这段代码。因此,您要在使用预期值初始化变量之前打印变量。

回答by john_omalley

Java actually has some pretty clear rules about this. Essentially the "int i = 45" code in the subclass is an implicit part of the subclass constructor and the superclass constructor alwaysruns first.

Java实际上对此有一些非常明确的规则。本质上,子类中的“int i = 45”代码是子类构造函数的隐式部分,而超类构造函数始终首先运行。

The order of events is:

事件的顺序是:

  • Create the object and zero out all instance variables.
  • Invoke superclass initializers.
  • Invoke superclass constructor.
  • Invoke subclass initializers (int i = 45; in this example)
  • Invoke subclass constructor.
  • 创建对象并将所有实例变量清零。
  • 调用超类初始值设定项。
  • 调用超类构造函数。
  • 调用子类初始值设定项(int i = 45;在本例中)
  • 调用子类构造函数。

This gets really nasty when you have a final field. You could declare "i" final in your example and get the same result!

当您有最后一个字段时,这会变得非常糟糕。您可以在示例中将“i”声明为 final 并获得相同的结果!

In general, invoking non-private (or at least non-final) methods in a constructor is asking for trouble and is often the source of nasty bugs. Invoking an abstract method is a reallybad idea (most of the time).

一般来说,在构造函数中调用非私有(或至少是非最终)方法是自找麻烦,并且通常是令人讨厌的错误的根源。调用抽象方法是一个非常糟糕的主意(大多数情况下)。

回答by vijayk

Java Beginner: I got your problem.. 1.When you create the object of child class at that time print() method called only in child class not in parent class even though parent class constructor called first bcoz the object is of child class Please refer the following example.

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);
        }
    }

output:

输出

parent>> i ValueTwo=
Child>>i Value = 0

2.If you create the parent class object at that time the print() method in parent class is called. Please refer the following example.

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);
        }
    }

output:

输出

parent>> i ValueTwo=
parent>> i ValueOne=

3.And i think you have already cleared why that value of i is 0 or 45.

3.我想你已经清楚为什么 i 的值是 0 或 45。

回答by exexzian

Because at that time of first call to print method iis not initialized to 45 so its printing 0.
call goes like this

因为当时第一次调用print方法i没有初始化为45所以它打印0.
调用是这样的

  • child constructor (as because of constructor chaining from child to parent)
  • parent constructor
  • print method (now here iis not initialized coz child constructor is not complete yet so its printing the default value of iwhich is 0 )
  • now after completion of parent constructor and then child constructor igets its value which is 45 -
  • so now it prints 45 on the next call of print method
  • 子构造函数(因为从子到父的构造函数链接)
  • 父构造函数
  • 打印方法(现在这里i没有初始化,因为子构造函数还没有完成,所以它打印的默认值为i0 )
  • 现在在父构造函数完成后,然后子构造函数i得到它的值为 45 -
  • 所以现在它在下一次调用 print 方法时打印 45

回答by Eric Na

First, I do not see the constructor definition in your Childclass.

首先,我没有在您的Child类中看到构造函数定义。

When you do not define a constructor for a Childclass, its default constructor is:

当你没有为一个Child类定义构造函数时,它的默认构造函数是:

public Child() {
    super();
}

Where super();calls the Parentclass constructor(super class constructor).

其中super();调用Parent类构造函数(超类构造函数)。

However, you defined your print()method in Childclass, and since it has the same signature(name+parameter) as the method in Parentclass, it overrides its super class method with the same signature.

但是,您print()Child类中定义了方法,并且由于它与类中的方法具有相同的签名(名称+参数)Parent,因此它会使用相同的签名覆盖其超类方法。

That is why your Childclass calls Parentclass constructor, while it calls its own print()method.

这就是为什么你的Child类调用Parent类构造函数,而它调用自己的print()方法。

-added:

-添加:

The first i value is 0 because you did not initialize an int variable iin Parentclass, and the value of an uninitialized int variable is 0 by default. After Parentis called, it invokes now Child's print()method, and iis initialized in Childclass, so now iis the value you initialized

第一个 i 值为 0,因为您没有iParent类中初始化 int 变量,而未初始化的 int 变量的值默认为 0。之后Parent被调用,它现在调用Childprint()方法,并i在初始化Child类,所以现在i是你初始化值

回答by Pol0nium

Your child first calls your parent's constructor. At this point, i isn't initialized with the 45 value. That's why it prints 0 (the default int value).

你的孩子首先调用你父母的构造函数。此时, i 未使用 45 值进行初始化。这就是它打印 0(默认 int 值)的原因。