简体   繁体   English

Java子类构造函数继承的成员

[英]Java subclass constructor inherited member

I have a question as to why does this piece of code, when executed, prints out the value 0. I don't exactly understand what happens in the SubClass constructor, and why is it that when I erase the overridden method implicitValue, it prints out 10. Does the SubClass constructor make use of the SuperClass constructor? 我有一个问题,为什么这段代码在执行时为什么会打印出0值。我不完全了解SubClass构造函数中发生的情况,为什么在擦除覆盖的方法hiddenValue时会打印出该值呢? out 10. SubClass构造函数是否使用SuperClass构造函数? Thank you. 谢谢。

class SuperClass {
    protected int superClassValue;

    public SuperClass() {
        superClassValue = implicitValue();
    }

    public int implicitValue() {
        return 10;
    }

    public int getValue() {
        return superClassValue;
    }
}

class SubClass extends SuperClass {
    private int subClassValue;

    public SubClass() {
        subClassValue = 20;

    }

    public int implicitValue() {
        return subClassValue;

    }
}

class Example {
    public static void main(String argv[]) {
        SubClass ss = new SubClass();
        System.out.println("The value is " + ss.getValue());

    }
}

TL;DR TL; DR

Problem is that implicitValue from SubClass is used by superclass implicit SuperClass constructor ( super() ) via implicitValue() method, before subClassValue = 20; 问题是, implicitValueSubClass所使用的超类隐式超类构造( super()通过) implicitValue()方法,前subClassValue = 20; will be executed in SubClass constructor, so it returns default value of subClassValue which for int field is 0 . 将在SubClass构造函数中执行,因此它返回subClassValue默认值,其中int字段为0


Does the SubClass constructor make use of the SuperClass constructor? SubClass构造函数是否使用SuperClass构造函数?

Yes, subclass constructor at start always invokes superclass constructor, so code 是的,子类构造函数在开始时始终会调用超类构造函数,因此代码

public SubClass() {
    subClassValue = 20;
}

is same as 与...相同

public SubClass() {
    super();//superclass constructor
    subClassValue = 20;
}

But lets take a look at your code. 但是,让我们看看您的代码。 You are printing result of getVlaue() method which exists in your superclass 您正在打印超类中存在的getVlaue()方法的结果

public int getValue() {
    return superClassValue;
}

As you see it returns value of superClassValue . 如您所见,它返回superClassValue值。 Before you invoke getVlaue() you are creating ss instance, so you are invoking code 在调用getVlaue()之前,您正在创建ss实例,因此您正在调用代码

super();//superclass constructor
subClassValue = 20;

which means you are invoking constructor of superclass which looks like 这意味着您正在调用超类的构造函数,如下所示

public SuperClass() {
    superClassValue = implicitValue();
}

so this.superClassValue is initialized with returned value of implicitValue() method, but because of dynamic binding (late binding) JVM will try to search for implementation of this method starting from actual class of this which is SubClass , and since this class has its own overridden version it will be invoked 所以this.superClassValue被初始化的返回值implicitValue()方法,但由于动态绑定 (后期绑定)JVM将尝试寻找实现这种方法从实际的类的开始的thisSubClass ,由于该类有其自己的覆盖版本,它将被调用

public int implicitValue() {
    return subClassValue;
}

but subClassValue wasn't set to anything yet 但是subClassValue尚未设置为任何值

super();// <-- we are still here
subClassValue = 20;// this line was not executed yet

so subClassValue still has its default value 0 , which means that 因此subClassValue仍具有其默认值0 ,这意味着

superClassValue = implicitValue(); //will be initialized with 0;

so 所以

public int getValue() {
    return superClassValue;
}

will return 0 . 将返回0

Yes, the subclass constructor implicitly calls the superclass constructor if such a call is not explicitly given. 是的,如果未明确给出此类调用,则子类构造函数将隐式调用超类构造函数。 But it prints 0 because of the fact that the implicitValue method is overridden in SubClass . 但它打印0 ,因为一个事实,即implicitValue方法在重写SubClass

  1. The superclass constructor is called. 超类构造函数被调用。 Here, the SuperClass part of the object is created. 在这里,创建了对象的SuperClass部分。 All variables are initialized. 所有变量均已初始化。 Because there is no explicit value given, the compiler gives superClassValue the default value, 0 . 因为没有给出显式值,所以编译器将superClassValue的默认值设置为0 The superclass constructor then calls implicitValue() , which calls the subclass's method. 然后,超类构造函数将调用implicitValue() ,后者将调用子类的方法。 This method returns superClassValue , which was initialized to 0 . 该方法返回已初始化为0 superClassValue This value is explicitly assigned back to superClassValue . 该值被明确分配回superClassValue
  2. The subclass initializes its subClassValue to 10 . 子类将其subClassValue初始化为10
  3. The getValue() method is called, and it returns superClassValue , which is 0 . 调用getValue()方法,并返回superClassValue ,该值为0 The value is 0 is printed. The value is 0

If you were to remove the implicitValue method in SubClass , then it would inherit SuperClass 's version of the method, which returns 10 . 如果要删除implicitValue的方法SubClass ,那么它会继承SuperClass的方法,该方法返回的版本10

If you were to modify the implicitValue method in SubClass to return 5 , then it would initialize superClassValue to 5 , and it would print The value is 5 . 如果要修改implicitValue的方法SubClass返回5 ,那么它会初始化superClassValue5 ,这将打印The value is 5

  1. In your case: SuperClass constructor will be called by default. 在您的情况下:默认情况下将调用SuperClass构造函数。

  2. When Java process: new SubClass(). 在Java进程中:new SubClass()。 It will call constructor of SuperClass first. 它将首先调用SuperClass的构造函数。 When constructor of SuperClass is being called - Value return from implicitValue() will be assigned to superClassValue - The method implicitValue() being called is the method Of SubClass (NOT implicitValue() of SupperClass being called as you thought - Polymorphism feature of OOP). 调用SuperClass的构造方法时-将从hiddenValue()返回的值分配给superClassValue-调用的隐含值()方法是SubClass的方法(如您所想的那样调用SupperClass的NOT hiddenValue()-OOP的多态性功能) 。 When implicitValue() of SubClass is being called, subClassValue is not initialized yet (subClassValue = 20; not run yet) so subClassValue still be ZERO. 调用SubClass的implicitValue()时,subClassValue尚未初始化(subClassValue = 20;尚未运行),因此subClassValue仍为零。 That is the reason you see Zero in the output. 这就是在输出中看到零的原因。

  3. When you remove override implicitValue in SubClass. 当您删除SubClass中的override hiddenValue时。 implicitValue() being called is implicitValue of SupperClass --> This is why you see 10 in the output. 被调用的implicitValue()是SupperClass的implicitValue->这就是为什么您在输出中看到10的原因。

It sounds like something is wrong with your Override method or subclass. 听起来您的Override方法或子类有问题。 Because it sounds like when it is implements a variable the value is not getting instantiated so it is defaulting to 0 and then when you remove it the super class takes over resulting in you getting the value 10. 因为这听起来像是在实现变量时未实例化该值,所以它默认为0,然后在删除它时,超类将接管,从而得到值10。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM