简体   繁体   中英

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? 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

Problem is that implicitValue from SubClass is used by superclass implicit SuperClass constructor ( super() ) via implicitValue() method, before subClassValue = 20; will be executed in SubClass constructor, so it returns default value of subClassValue which for int field is 0 .


Does the SubClass constructor make use of the SuperClass constructor?

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

public int getValue() {
    return superClassValue;
}

As you see it returns value of superClassValue . Before you invoke getVlaue() you are creating ss instance, so you are invoking code

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

public int implicitValue() {
    return subClassValue;
}

but subClassValue wasn't set to anything yet

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

so subClassValue still has its default value 0 , which means that

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

so

public int getValue() {
    return superClassValue;
}

will return 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 .

  1. The superclass constructor is called. Here, the SuperClass part of the object is created. All variables are initialized. Because there is no explicit value given, the compiler gives superClassValue the default value, 0 . The superclass constructor then calls implicitValue() , which calls the subclass's method. This method returns superClassValue , which was initialized to 0 . This value is explicitly assigned back to superClassValue .
  2. The subclass initializes its subClassValue to 10 .
  3. The getValue() method is called, and it returns superClassValue , which is 0 . The value is 0 is printed.

If you were to remove the implicitValue method in SubClass , then it would inherit SuperClass 's version of the method, which returns 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 .

  1. In your case: SuperClass constructor will be called by default.

  2. When Java process: new SubClass(). It will call constructor of SuperClass first. 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). When implicitValue() of SubClass is being called, subClassValue is not initialized yet (subClassValue = 20; not run yet) so subClassValue still be ZERO. That is the reason you see Zero in the output.

  3. When you remove override implicitValue in SubClass. implicitValue() being called is implicitValue of SupperClass --> This is why you see 10 in the output.

It sounds like something is wrong with your Override method or subclass. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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