1

So guys I've been playing around with inheritance and I've stumbled upon this program :

public class HelloWorld {
    static class A {
        void f() { System.out.println("A"); }
    }

    static class B extends A {
        void f() { System.out.println("B"); }
    }

    static class C {
        void func(B b) { b.f(); }
    }

    static class D extends C {
        void func(A a){ a.f(); }
    }

    public static void main(String args[]) {
        ( (new D())).func( (A) (new B()));
        A a =  new B();
        a.f();
        B b = new B();
        C c = new D();
        c.func(b);
    }
}

So how come even though A and C are implemented exactly the same way in the final few lines, A's methods get overriden by B, but C's don't get overriden by D? The program prints as follows : B B B

zxzx28
  • 15
  • 4
  • Does this answer your question? [Why does the line marked with //1 print 57 instead of 39?](https://stackoverflow.com/questions/60269396/why-does-the-line-marked-with-1-print-57-instead-of-39) – Federico klez Culloca Feb 24 '20 at 15:36
  • @FedericoklezCulloca Probably the worst dupe target ever. Such an awful title and badly formatted question. – ruohola Feb 24 '20 at 15:40
  • 1
    Not that this question has any better title. – ruohola Feb 24 '20 at 15:42
  • @ruohola it's just that I remembered that question and it's basically the same. If you find a better one I'll gladly retract mine. – Federico klez Culloca Feb 24 '20 at 15:47
  • I tried writing a simpler title but it said it was already taken sorry guys! I edited it into something I think is a bit better. – zxzx28 Feb 24 '20 at 15:48

2 Answers2

2

Because Class D function definition is more general than C. C's function takes B type parameter but D function takes type A parameter which is a parent of B. It is more general than a function defined in C.

static class D extends C {
    void func(A a){ 
        a.f(); 
    }
}

  B b = new B();
  C c = new D();
  c.func(b);

Variable c is pointing to D's object so c.func(b) invokes method defined in D. A is a parent of B hence B's method is called. Same as it is called using A's reference as shown below.

  A a =  new B();
  a.f();
Ravi Sharma
  • 160
  • 4
0

It is because the method func in D does not override the same of C as the signature change.

static class C {
    void func(B b) { b.f(); }
}
static class D extends C {
    void func(B a){ a.f(); }
}

This will result in an override of the method

Greedo
  • 3,438
  • 1
  • 13
  • 28
  • Well that certainly explains why C's isn't overriden, but how come when I upcast B to A it still uses B's function? – zxzx28 Feb 24 '20 at 15:57
  • Because of polymorphism and the method having the same signature – Greedo Feb 24 '20 at 16:06
  • Yeah apparently I had it the other way around, so was D overwriting C's method? and can the (upcasted) A object use any of B's methods if there were any other ones exclusive to B? – zxzx28 Feb 24 '20 at 16:42
  • D will have two methods at runtime, one for signature A and for for B, so depending on the runtime type it will use the correct method. For the second question, i'm quite sure the answer is "no", but you can try it yourself ;) – Greedo Feb 25 '20 at 09:02