• Post Reply Bookmark Topic Watch Topic
  • New Topic

Polymorphism - Deciding which method gets called ?  RSS feed

 
Sushant Kunwara
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
While studying polymorphism , i have some doubts that i am unable to clarify .....
Here they are :

Suppose our inheritance ladder be :
C1 <- C2 <- C3 <-....... <- C100
where C1 is most general (superclass) and C100 is most specific class .
Now , if i write java code in my main() :



So, what will happen in scenarios as given below :

Scenario - 1) If someMethod() is only defined in C1 ? How will compiler search for this someMethod() ?Will it be executed ?
Scenario - 2) If that someMethod() is static and only defined in C1 , then how will it be searched and executed ?
Scenario - 3) If someMethod() is only present in C100 , then what will happen ?

Thanks in advance....
 
Paweł Baczyński
Bartender
Posts: 2087
44
Firefox Browser IntelliJ IDE Java Linux Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch!

1. The compiler search for the method in C100, if not found it will search for the method in C99, etc.
2. The compiler search for the method in C21, if not found it will search for the method in C20, etc.
3. Compile error.

You could easily check those scenarios by writing some code and experimenting...
 
Campbell Ritchie
Marshal
Posts: 56599
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Beware of trying to override static methods. Overriding only applies to non‑private non‑final instance methods, and you can get dangerous confusion if you try to override static methods. Look at these FAQ (look for No 16).
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paweł Baczyński wrote:
You could easily check those scenarios by writing some code and experimenting...


You're getting some good answers, Sushant (and welcome to the Ranch), but I think Pawel has already given you some of the best advice there is: just run some code and find out! Even though you can get your answers here, or from other references, nothing quite makes inheritance (which is really what you're asking about) sink in like running some basic experiments. Feel free to ask for help if you have problems, but hands-on learning may be the best way for this.
 
Dave Tolls
Ranch Foreman
Posts: 3068
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paweł Baczyński wrote:2. The compiler search for the method in C21, if not found it will search for the method in C20, etc.


The others are correct (especially the "try it out" part), but this isn't.
Obj is of class C21, so it will look for someMethod() in C21 -> C1 as a non-static method, and in C21 only as a static method.
Doesn't matter if there's a static version anywhere in C20 -> C1 it will not use those and will flag an error for this scenario.
 
Sushant Kunwara
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Obj is of class C21, so it will look for someMethod() in C21 -> C1 as a non-static method, and in C21 only as a static method.



Dave , this is what i did and found that it searched for static in superclasses also i.e. in C21 -> C20 ..- > C1. May be i am wrong , here is the code :
I have taken 3 classes , A ,B,C and one TestRun class. Inheritance structure i build is A->B->C , where A is most general and C most specific.




Output was :This is Static reached

How do you explain this then ?
 
Dave Tolls
Ranch Foreman
Posts: 3068
37
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ha!

I could have sworn I got an error when doing just that this morning!
Can I use "it's Friday" as an excuse?
 
Tony Docherty
Bartender
Posts: 3271
82
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dave Tolls wrote:I could have sworn I got an error when doing just that this morning!

What you possibly saw was an IDE warning - Eclipse's warning message in these scenarios is something like "The static method p from the type Class A should be accessed in a static way"
 
Brandon Bushnell
Greenhorn
Posts: 23
Eclipse IDE Java Mac
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason it worked is because the compiler is doing this:



Compiler: “Okay, I need to find the p method, let me look in ClassC first!”
Compiler: “There’s no p method in ClassC, hmmm, maybe I can look at its superclass; ClassB”
Compiler: “Nope, no p method in ClassB either. But ClassB also has a superclass; ClassA, let me look there!”
Compiler: “Found it! Let me execute the p Method from ClassA!"

When you have multiple subclasses, the compiler will start at the bottom (ClassC) to look for the method and move up the chart until one of the superclasses contain the method. In your case, ClassA!
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brandon Bushnell wrote:
When you have multiple subclasses, the compiler will start at the bottom (ClassC) to look for the method and move up the chart until one of the superclasses contain the method. In your case, ClassA!


This is true for non-static methods, Brandon, but for static methods the compiler will simply look at the class of the variable obj, and run the method defined or inherited by that class. It's the same as if you replaced
with
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To illustrate more fully, this code:

produces this output:

One of the others who know better will have to confirm this, but I think the compiler's ability to search for superclass methods is limited to static methods. At compile time, it doesn't have enough information to be sure that an object variable of type ClassB contains a reference to an object of ClassC (for example, when the variable is passed in to a method). It's only at run time that I think the fact that obj contains a reference to a ClassC object causes ClassC's methods to run (which, as you point out, could be inherited all the way down from ClassA).
 
Tony Docherty
Bartender
Posts: 3271
82
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stevens Miller wrote:This is true for non-static methods, Brandon, but for static methods the compiler will simply look at the class of the variable obj, and run the method defined or inherited by that class. It's the same as if you replaced
with

This is a very interesting and important difference between the way static and instance methods are handled. In the given code if class A and C have instance methods p() then the instance method in C will be run whereas if class A and C have static methods p() the static method in A will be run.
 
Rico Felix
Ranch Hand
Posts: 411
5
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here are a few guidelines:
  • If the subclass doesn't override the super-class instance method then the super-class method is used...
  • If the subclass does override the super-class instance method then the subclass method is used...
  • Static methods are bound to the class in which they are defined in, therefore they cannot be overridden but can be redefined...

  • Therefore as with the case of instance methods its a search until found operation starting from the object type all the way up to the reference type, if not found in reference type then flag an error...
    Static methods are search on spot using the reference type, if not found then flag an error...
     
    Stevens Miller
    Bartender
    Posts: 1445
    30
    C++ Java Netbeans IDE Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rico Felix wrote:
  • Static methods are bound to the class in which they are defined in, therefore they cannot be overridden but can be redefined...



  • I would say that that static methods can be inherited, that they cannot be overridden, but they can be hidden (in the same way that instance variables can be hidden). To confirm that they cannot be overridden, one can try putting an "@Override" annotation ahead of ClassC's static p method. You'll get a compiler error if you do that. That's because ClassC's p method is entirely defined by ClassC. Among other things, this means that "super" is useless in a subclass's static methods, even if those methods all have the same name as a static method in any of that subclass's superclasses (whereas, in an instance method, you can use super to run the inherited--or any other accessible--method of the parent class).

    The behavior is the same as for instance variables. Consider what happens if you add a public String to ClassA and to ClassC, giving each the same name, and then try to access that String through a reference in a variable of Class B:



    Notwithstanding that the JVM can find ClassC's instance method, q, and run it when in it is invoked from a reference contained in a ClassB variable, it cannot find the same instance's public String s, unless the variable is cast to a ClassC explicitly (requiring a nightmarish syntax that should be a strong sign you're using a dubious technique). Thus, the output from the above is this:

     
    Rico Felix
    Ranch Hand
    Posts: 411
    5
    IntelliJ IDE Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    @Stevens Miller thank you for adding the extra clarifications... It was implied that inheritance is understood seeing that if you extend a class you can be treated like that class...
     
    Stevens Miller
    Bartender
    Posts: 1445
    30
    C++ Java Netbeans IDE Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Just to continue a bit further with this scintillating saga, it is interesting to note that hiding a public instance variable with a subclass's private instance variable of the same name gets you a compile-time error:



    ClassB's x isn't accessible outside an instance of ClassB. If ClassB had no variable named "x," an instance of ClassB that referred to "x" would be referring to the x inherited from ClassA. The existence of its own instance variable by that same name in ClassB, however, hides it inaccessibly. Note that this compiles fine, but an attempt to use something like this:


    will not compile, as "obj.x" is seen as an attempt to access the private member variable "x" in ClassB, not the public member variable of the same name in the parent class, ClassA.
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!