• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Sub-class confusion...I thought I understood

 
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
here is the question:

The answer is prints: AAA
Ok I am really confused, because this is how I've been thinking about sub-classes, and it has been working all along. The line A c2 = new C(); means to me, we are creating a variable c2 that is a reference type of A, but in actuality it is a C (which works because C is an "A" somehow). But in reality even though c2 has a reference of A, if you call functions on c2 that only a "C" has, it will work because in "reality" it is really a C. So basically it can be thought of as, the more important aspect of an object declaration is not the refernce type but rather the object created. But the above example proves otherwise, it is like saying the reference type is more important than the actual object that is created. I would think it should print ABC, but I indeed tried it out and it doesn't. My world is flipped upside down, please help with an explanation that makes intrinsic sense.
 
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
For overloaded methods, the compiler will do static binding depending on type of object reference (A).
 
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The following program shows what happens with overriding methods.
In this case the method invocation is resolved at runtime based on the actual object.
 
Wilson Mui
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I think I am getting a little clearer. Let me restate the specifications and see if I am correct.
There is basically a difference in how overriden methods are handled and overloaded methods. Overriden methods are not statically bound. Meaning in the case where I have a subclass calling a overridden method. The actual method that did the overriding will be called (i.e.
Sub subTest = new Sub();
subTest.method() //will call the subTest's .method() and not the super's method().
That is the simple case. In the more advanced case where I declare an object as such
Super superTester = new Sub() //Super is a superclass of Sub
then superTester.method() will call the super's method() if the method was overloaded, but it will call the Sub's method() if method() was overriden. Please tell me this is right, or I'm gonna go nuts.
 
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also remember that static / private methods cannot be overidden , rather they are hidden , so the compile time determination applies for those methods too
 
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Wilson Mui:
My world is flipped upside down, please help with an explanation that makes intrinsic sense.


Wilson,
Your world has been flipped upside down because you have confused method overloading with method overriding. The methods in this program are not overridden. Instead, they are overloaded.
The reference c2 is of type A so reference c2 does not provide access to overloaded methods that are declared in subclasses of type A. For that reason, the arguments to method m1 are converted to type A and method m1(A a) is invoked in all three cases.
 
Wilson Mui
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Dan, it's your tests by the way that are kicking my butt...good or bad, I'm not sure.
Anyway, I think I understand now, but I may disagree with the wording you are using. The way you are explaning it sounds like this. You are saying because the method m1() is overloaded it means the method needs to be declared at compile time. Ok I agree with that (now). But then you say because c2 is a referenced by an reference of type A, and since "A" doesn't have scope to see the other overriden m1() methods, then the lines that read:
c2.m1(a1);
c2.m1(b1);
c2.m1(c1);
will have the parameter automatically cast up to type A.
Now this may be slight. How I see it, and from what others are telling me, is that c2 is referenced by a reference of type "A." And because the methods are overloaded then it needs to be determined which method exactly it should be using at compile time. This is where we differ. I think the compiler then says "ok c2 is referenced by a type "A", therefore that is what it is. Now go to the object A and see if there is an m1() method, and see if it takes a parameter that matches." See the difference in what I am saying and what you are saying is that I think teh compiler cares more about the type of reference that is pointing to the object that the object type of the parameters. I think the compiler, once it has determined that the object in question is an "A" it will only go to the A.m1() regardless of what parameter is in the method call (as long as it works). What you are saying is that the compiler changes the parameter so that it matches the parameter of A's m1().
I'm not sure if there is even a difference in what we are saying...but it's just how I understand it I guess. What do you think?
P.S. If I changed the B object to this:

class B extends A {
void m1(B b) {
System.out.println("B");
}
void m1(C c){
System.out.println("C");
}
}
and ran the main again, it will still output AAA...
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wilson, your comment was as follows.

I think the compiler, once it has determined that the object in question is an "A" it will only go to the A.m1() regardless of what parameter is in the method call (as long as it works). What you are saying is that the compiler changes the parameter so that it matches the parameter of A's m1().


Yes, that is called a method invocation conversion as described in
Section 5.3 of the Java Language Specification. The method invocation conversion implements the "as long as it works" part of your comment.
Other than that I agree that there is probably not a lot of difference between what we are saying.
 
We're all out of roofs. But we still have tiny ads:
New web page for Paul's Rocket Mass Heaters movies
https://coderanch.com/t/785239/web-page-Paul-Rocket-Mass
reply
    Bookmark Topic Watch Topic
  • New Topic