0
public class Base {
    public Base() {
    foo();
  }

public void foo() {
    System.out.println("Base.foo()");
  }
}



public class Derived extends Base {

public Derived () {}

public void foo() {
    System.out.println("Derived.foo()");
  }
}

And then, when i call those:

public class Running {

public static void main(String[] args) {
    Base b = new Base();
    Derived d = new Derived();
  }
}

It outputs:

*Base.foo()*

*Derived.foo()*

So why, when it gets to derived constructor, it invokes the base constructor but uses the derived's method instead?

PS: If I mark those methods as private, it will print out:

*Base.foo()*

*Base.foo()*
sodaluv
  • 449
  • 2
  • 9
  • 22
  • Please indent correctly and it will be easier to read. You’re overriding a method, so the most specific implementation for the type of the object gets called. Go read up on overriding a method in a derived class. On the other hand there’s no avoiding calling the base class constructor because the "base part" of the object needs to be constructed too. In real life this is also most often what you want. – Ole V.V. Jul 10 '16 at 11:07

3 Answers3

2

This is how Java works read this page https://docs.oracle.com/javase/tutorial/java/IandI/super.html

And more specifically the Note here :

Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.

So as you can see this is expected behavior. Even though you dot have a super call it is still automatically inserting it.

In regards of the second Question even though you are within the super constructor body still you Instance is of the Subtype. Also if you have some familiarity with C++ read this Can you write virtual functions / methods in Java?

The reason why it will write the base class when marking with private is because private methods are not Inherited. This is part of the Inheritance in Java topic.

Community
  • 1
  • 1
Alexander Petrov
  • 9,204
  • 31
  • 70
2

To answer the question in your title. As I said, you cannot avoid the base class constructor being called (or one of the base class constructors if it has more than one). You can of course easily avoid the body of the constructor being executed. For example like this:

public class Base {

    public Base(boolean executeConstructorBody) {
        if (executeConstructorBody) {
            foo();
        }
    }

    public void foo() {
        System.out.println("Base.foo()");
    }
}

public class Derived extends Base {

    public Derived() {
        super(false);
    }

    public void foo() {
        System.out.println("Derived.foo()");
    }
}

public class Running {

    public static void main(String[] args) {
        Base b = new Base(true);
        Derived d = new Derived();
    }
}

Now the main method prints only:

Base.foo()
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Because in the contructor of the Derived class it automatically gets injected a call to super(), if you do not add a call to super or to other constructor in the same class (using this).