File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Sub-class confusion...I thought I understood Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Sub-class confusion...I thought I understood" Watch "Sub-class confusion...I thought I understood" New topic
Author

Sub-class confusion...I thought I understood

Wilson Mui
Ranch Hand

Joined: Apr 09, 2003
Posts: 140
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.
Roger Chung-Wee
Ranch Hand

Joined: Sep 29, 2002
Posts: 1683
For overloaded methods, the compiler will do static binding depending on type of object reference (A).


SCJP 1.4, SCWCD 1.3, SCBCD 1.3
John Zoetebier
Ranch Hand

Joined: Mar 28, 2003
Posts: 76
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

Joined: Apr 09, 2003
Posts: 140
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.
preeti khane
Ranch Hand

Joined: Mar 12, 2003
Posts: 93
Also remember that static / private methods cannot be overidden , rather they are hidden , so the compile time determination applies for those methods too
Dan Chisholm
Ranch Hand

Joined: Jul 02, 2002
Posts: 1865
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.


Dan Chisholm<br />SCJP 1.4<br /> <br /><a href="http://www.danchisholm.net/" target="_blank" rel="nofollow">Try my mock exam.</a>
Wilson Mui
Ranch Hand

Joined: Apr 09, 2003
Posts: 140
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

Joined: Jul 02, 2002
Posts: 1865
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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Sub-class confusion...I thought I understood
 
Similar Threads
inheritance question
overriding + overloading
question
Qn from dan exam
overloading problem, pls help!