2

Let's go directly to the code:

Father.java:

public class Father {

    public void DoSmth(Father object) {
        // Do something else and print
        Print(object);
    }

    public void Print(Father object) {
        System.out.println("Father");
    }

}

Son.java:

public class Son extends Father {

    public void Print(Son object) {
        System.out.println("Son");
    }

}

Main.java:

public class Main {

    public static void main(String[] args) {

        Father o1 = new Father();
        Son o2 = new Son();

        o1.DoSmth(o1);
        o1.DoSmth(o2);

    }

}

So, I would like to get:

Father
Son

Howerver, I'm getting:

Father
Father

I really didn't understand very much why (for o1.DoSmth(o2)) it's calling the method from the Father class, since o2 is of type Son. Is there anyway I could get the desired answer?

Thanks in advance

P.S.: I, actually, want to call the method Print (of the Son class) from inside the Father class. Is it possible?

R. Thomes
  • 45
  • 5
  • You are calling the method from `Father` as you are calling it from the `o1` instance. – DamCx May 24 '18 at 09:59
  • @Seelenvirtuose Yes, that is a mistake, but no, it's not the only mistake. Eran answer is correct. – Shadov May 24 '18 at 10:02
  • Unrelated: In java, method names go camelCase, not UpperCase, as in C#. Not following such conventions confuses your readers. – GhostCat May 24 '18 at 11:59

2 Answers2

5

public void Print(Son object) doesn't override public void Print(Father object). It overloads it.

That said, DoSmth(Father object) is executed in both case on a Father instance, so it would call public void Print(Father object) of Father class even if Son class did override it.

If you change the Son class method to:

@Override
public void Print(Father object) {
    System.out.println("Son");
}

and change your main to:

public static void main(String[] args) {
    Father o1 = new Father();
    Son o2 = new Son();

    o1.DoSmth(o1);
    o2.DoSmth(o2);
}

You'll get the output

Father
Son
Eran
  • 387,369
  • 54
  • 702
  • 768
  • @Seelenvirtuose Good thing that there is no concept of agree and disagree when it comes to deterministic output. Those invocations won't print `Son` – Shadov May 24 '18 at 10:04
  • Yeah. I was wrong. The method `Print(Son object)` can never be called via the `DoSmth` method call. This answer is very correct. – Seelenvirtuose May 24 '18 at 10:05
  • Ho yup, kinda made my mind up without reading everything you wrote. my bad. – N.K May 24 '18 at 10:06
  • I have to admit my explanation was a bit off. Fixed now. I answered as if `object.Print(object);` was being called instead of `Print(object);`. – Eran May 24 '18 at 10:09
  • Thanks for the response. But I, actually, want to call the method Print (of the Son class) from inside the Father class. Is it possible? P.S.:I know that it doesn't make sense to want that in this example, but it's just an example to make things more clear. – R. Thomes May 24 '18 at 11:48
  • 1
    @R.Thomes If you want a `Parent` object to call `Print` method of `Son` class, perhaps you want to call `object.Print(object)` from `DoSmth` (in which case you can just remove the argument of the `Print` method and call `object.Print()`) – Eran May 24 '18 at 12:14
  • @Eran, that's exactly what I want. However, I actually need to pass the parameter (not in this example, but in the real case). So, if I write "object.Print(object)" in the "DoSmth", it does work! but only if I write in the Son class "public void Print(Father object)". If I keep the "public void Print(Son object)" it does not work, and I didn't understand why. Could you help me? – R. Thomes May 24 '18 at 12:26
  • @R.Thomes if you keep the method in the `Son` class as `public void Print(Son object)`, it does not override the Father class's `Print` method, and therefore the `Father`'s `Print` method is called. – Eran May 24 '18 at 12:28
  • @Eran, I think I got it! So I cannot override and overload at the same time, is that right? – R. Thomes May 24 '18 at 12:45
  • @actually you can override and overload at the same time. If both Father and Son classes had both `public void Print(Father object)` and `public void Print(Son object)`, the compile time type of the passed argument would have determined which method the compiler chooses (that's overload resolution), and the runtime type of `object` would determine whether a Father class method or a Son class method is executed (that's method overriding). – Eran May 24 '18 at 12:51
0

This is because you are calling the Print method on the Father-instance. If you instead of passing the object as the parameter and called object.Print() you should get your expected result

  • Actually, I need to pass the parameter (not in this example, but in the real case). So, if I write "object.Print(object)" in the "DoSmth", it does work! but only if I write in the Son class "public void Print(Father object)". If I keep the "public void Print(Son object)" it does not work, and I didn't understand why. Could you help me? – R. Thomes May 24 '18 at 12:18