Inheritence from exercise 10 no.3

hi,

i got a question regarding sheet 10 exercise 3.: Inheritance Hierarchy, at the last part it ask for the result of ad.foo(cd) which the solution said to be C.foo(B). why is that? my answer is D.foo(C) since the method is from D and argument would take its static type of C. is my understanding wrong?

thanks in advance

Yes. To see why, answer the following questions(s):

  • What is the maximally specific method?
  • Why would the compiler know that foo(C) is invokable on an object of static type A?

I tried and i still failed to understand.

New

(Ps: its a joke)

2 Likes

Well, clearly you know the correct answer to the exercise, since you can look at the solutions.

However, you misunderstood something about the process for arriving at that answer.

Since I don’t know why, and since I can not look into your head, I can only ask probing questions.

You might want to look at the “Overloadind and Overriding” slides (CMS->Materials), and compare the process described in there to your own.

Alternatively, you can try to explain step-by-step how you came up with your (wrong) answer and then we can perhaps see where your mistake is.

1 Like

ad.foo(cd) => C.foo(B) (from solution), my answer is D.foo(C)

from this i got that we have a static type c for the argument and using the dynamic type d for the method (by that i mean we look up a method foo which have type c in class d).

edit:
so i got another approach to it and hopefully its right.

first we got that ad have a static type A so we start from there and since cd have a static type C, we check in a which of its method have a parameter that C extends to and as close as possible ( C <= B, therefore A.foo(B) ). but since b is overwritten in class c we got C.foo(B) instead.

Yes, your latter approach seems to be correct.

I guess in your first approach you missed that overloading is resolved at compile-time, so only signatures from A are available, even though the dynamic type is D.

This may seem unintuitive at first, but imagine a piece of code where the dynamic Type could vary (for example, by using a random number to decide what object to create). Now, if the compiler were to pick foo(C), but we actually created an instance of A, we would have a problem.

Hence, only the signatures from the static type can be used, as they are the only ones that are guaranteed to be available.

(I hope you don’t mind this extra explanation. I personally find that knowing why something is the case makes it much easier to remember)

I have a simular question , In exercise sheet 10 ex3 , in the correction it’s written that cd.foo(ab) will print D.foo(A), my answer is B.foo(A) , I want to know why. Such that the static type is C

  • Which methods override B.foo(A), and which are overridden by it?

Again, all you tell us is that you got he wrong solution. That’s unfortunate, but if you want us to figure out where the problem is, you need to tell a bit more.

well so in compiling time, we will use the static type in this situation C, I will check if D override a function that accept argument of type A that exist in C if yes I use it no I use the one in C argument if argument type cover the argument type I’m giving, but I think I understrand why now, so C is extanding B which have a foo(A a), so in our case D is overriding foo(A a) from B that got inherited by C. that’s why we are allowed to use override foo(A a ) in D.

Exactly. Remember that on a child class, all the methods inherited from the parent class are available. You can override them with a new definition, but if you do not, you inherit the implementation from the parent.

Thus, in the class C, there are the following methods:

  • foo(A), inherited from B, which overrides the original method from A
  • foo(B), defined in C, overriding the original method from A
  • foo(C), inherited from B

In D, we have

  • foo(A), defined in D, overriding the one from B, which overrides the original method from A
  • foo(B), inherited from C, overriding the original method from A
  • foo(C), defined in D, overriding the original from B`

Thus, you find the call to foo(A), which is available on C (even though it’s not written), and then at runtime you have an instance of D where the method foo(A) is overridden.

2 Likes