5

The below has this output.

Hello World!
main.ConstructedDerivedClass:6.0
main.ConstructedDerivedClass:6.0
public class ConstructedDerivedClass extends ConstructedBase {

    private static final double version = 6.0;

    public static void main(String[] args) {

        System.out.println("Hello World!");

        ConstructedDerivedClass derivedClass = new ConstructedDerivedClass();
    }

    public ConstructedDerivedClass() {
        showMyAttributes();
    }

    @Override
    protected void showMyAttributes() {
        System.out.println(this.getClass().getName() + ":" + version);
    }  
}

public class ConstructedBase {

    private static final double version = 15.0;

    public ConstructedBase() {
        showMyAttributes();
    }

    protected void showMyAttributes() {
        System.out.println(this.getClass().getName() + ":" + version);
    }
}

I would expect it to just display one line, that of the child class (ConstructedDerivedClass). But instead it print's out twice.I know in general you should avoid calling overriden methods from a constructor, but I wanted to see for myself how was this working.

Actually, I get why version is '6.0' on both lines - since field is being declared static of course static fields are initialized first. But still don't get why two lines.

Any guidance would be appreciated.

Omar D
  • 53
  • 6
  • This might be a duplicate (but I didn't find one after a moment of searching), but even if it is, this is a well written question that clearly shows the output that you're interested in, and the full code that reproduces it. Well done! – Joshua Taylor May 13 '14 at 01:14
  • Thanks. Still new to this. Both answers below where helpful. Kinda hard to pick the one. – Omar D May 13 '14 at 01:20

2 Answers2

7

This is because when you write

public ConstructedDerivedClass() {
    showMyAttributes();
}

The compiler actually places a call to super default constructor in byte code so it's equivalent to

public ConstructedDerivedClass() {
    super();        
    showMyAttributes();
} 
vkg
  • 1,839
  • 14
  • 15
  • And then it prints 6.0 twice because the showMyAttributes method is overridden, therefor the superclass method which should print 15.0 is never called. – jonadv Apr 15 '21 at 12:26
6

When an object is instantiated, it makes an implicit, no-args super-constructor call to its parent class before running its own constructor.

You can imagine that there is this line ALWAYS in your constructors:

public MyClass() {
    super(); //If this line is not here, it is implicit.
    //rest of the code
}

You can override this by providing your own explicit, any-args super-constructor call, but it must be the first line of the method.

public MyClass() {
    super(1, "Hello Word", null); //written explicitly, no other super-constructor code will run
    //rest of the code
}

Which can be useful when the superclass does not have a no-args constructor defined.

Kon
  • 10,702
  • 6
  • 41
  • 58
  • Got it. Only picking the other, because I was able to clearly see how 'showAttributes()' is called twice. But this was helpful also. – Omar D May 13 '14 at 01:22