0

I thought that super(); means almost the same as we call the superclass constructor, but it doesnt.

class A {
    A() {
        foo();
    }

    void foo() {
        System.out.print("A");
    }


}

class B extends A {
    void foo() {
        System.out.print("B");
    }

    B() {
        super();
        super.foo();
    }
}

When I call new B(); it prints BA why? I was debuging it and super() call constructor of A but it prints B(this is what Im not understanding), and why after this super.foo() prints A as it should. Can someone explain how does it works?

Marv
  • 3,517
  • 2
  • 22
  • 47
  • 4
    I don't believe the marked question is actually a duplicate - the OP's issue is actually nothing to do with `super`, instead it's about virtual calls from a base class. – Oliver Charlesworth Jan 30 '18 at 19:50
  • 1
    I don't think the duplicate answers your exact question directly, but since this has been closed: I think to visualize why `B`'s `foo` is called when you call `super`, it's best to make A an abstract class and `foo` an abstract method. Now which method is going to be called is perfectly clear because `A`'s `foo` is abstract. – Marv Jan 30 '18 at 20:01
  • You overrode `foo`. In `B`. I believe that the constructor in `A` then called the version in `B` that was overrode. Then, it calls the super's version of `foo`, which prints A. (Correct me if I'm wrong) – ifly6 Jan 30 '18 at 20:12
  • Can u give a better explanation of this virtual calls, so i undesrtand how it works? @OliverCharlesworth – Piotr Kedra Jan 30 '18 at 20:28
  • 1
    @PiotrKedra https://stackoverflow.com/questions/9453701/what-is-virtual-method-calling-in-java – Marv Jan 30 '18 at 20:47
  • Thanks for the references – Piotr Kedra Jan 31 '18 at 12:22

2 Answers2

1

The reason it prints BA:

you call new B();

  1. B constructor calls A constructor (your super() call)
  2. A constructor calls foo
  3. foo() is overridden in B, so it resolves to B.foo()
  4. B.foo() prings "B"
  5. B.foo() returns, and A constructor returns
  6. B constructor moves to next call, which is to super.foo()
  7. Because of the "super" qualification, this resovles to A.foo()
  8. A.foo() prints "A"

The end

Why does it print "B" from A's call to foo()? Because foo() is an instance method, "this" is an instance of B, and B has a method with the same signature as A.foo, so this resolves to the subclass method B.foo. This is called virtual method resolution and is a fundamental concept of object-oriented programming. The terminology is that B.foo overrides A.foo.

Sean F
  • 4,344
  • 16
  • 30
0

Your program flow is as follows:

  1. The constructor of B is called.
  2. It calls the constructor of A with the super();. As an aside, that line is unnecessary and would be done automatically if left out.
  3. The constructor of A calls foo() of B. The call foo(); is to the B version of foo() because the object is an instance of B, and the B version of foo() overrode the A version of foo(). So you get a 'B' printed.
  4. The constructor of A returns to the constructor of B, which calls super.foo();. This calls the A version of foo() because you specifically told it to do so with the "super" prefix. So it prints an 'A'. (Note that this is not a call to a constructor, in case you were confused about that.)

The reference in one of the comments (What is virtual method calling in java?) explains more about this.

Steve Brandli
  • 556
  • 4
  • 14