GeeCON Prague 2014*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes tricky question 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 "tricky question" Watch "tricky question" New topic
Author

tricky question

velan vel
Ranch Hand

Joined: Nov 15, 2005
Posts: 137
hai ranchers this may be a tricky question
enjoy this ine




class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(B b) {System.out.print("B");}}
class C extends B {void m1(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C(); c1.m1(c2);
}}

What is the result of attempting to compile and run the program?

a. Prints: A
b. Prints: B
c. Prints: C
d. Compile-time error
e. Run-time error
f. None of the above


------------------------------------------------------------------
$ Velan Vel @ SCJP 1.4 $
You learn From Your Failures, Others Will Learn From Your Success
------------------------------------------------------------------
Mandy Hou
Greenhorn

Joined: Oct 15, 2005
Posts: 21
c


Regards<br />Mandy<br /> <br />-----------------<br />Thinking,Thinking,Thinking,<br />Before you do any action!!!
harish shankarnarayan
Ranch Hand

Joined: Sep 12, 2005
Posts: 158
1:static methods look on references
2:instance methods look on objects
AM I right
then how come it prints A.
explain


Harish<br />SCJP 1.4 (85%)
Srinivasa Raghavan
Ranch Hand

Joined: Sep 28, 2004
Posts: 1228
C1 is of type 'A'. So it knows only one 'm1() method whose parameter is of Type 'A'. So when you call c1.m1(c2); The method in 'A' should get called and it prints 'a'
[ December 06, 2005: Message edited by: Srinivasa Raghavan ]

Thanks & regards, Srini
MCP, SCJP-1.4, NCFM (Financial Markets), Oracle 9i - SQL ( 1Z0-007 ), ITIL Certified
harish shankarnarayan
Ranch Hand

Joined: Sep 12, 2005
Posts: 158
ya got it,
was a little confused
thanks Srini.
Jan Valenta
Ranch Hand

Joined: Nov 30, 2005
Posts: 32
Be carefull, this:



prints out 'C'.


Anybody knows about a job for <a href="http://cern.ch/jvalenta/valenta-cv.pdf" target="_blank" rel="nofollow">SCJP5.0, Ph.D. in Software Engineering, 2 years Java, C, C++</a> in Montreal, QC, Canada? Thanks!
jeroen dijkmeijer
Ranch Hand

Joined: Sep 26, 2003
Posts: 131
Yes indeed very tricky one,
apparently the m1 method doesnt get overrriden, if you make the m1 method in A public and leave the visibility of B and C to default, you (Me myself) 'd expect a compiler error on reducing visibility but that doesnt occur.
so that gives only one applicable method for A.
regards
Gyanesh Sharma
Ranch Hand

Joined: Nov 27, 2005
Posts: 47
While the question and answer is pretty straight forward, I am not sure why some of the comments are misleading in this thread.
Why does Srini say C1 is of type A?
Also the methods are legally overloaded, not overridden. So there is not even a question of choosing the right method (reference or instance).
Bert Bates
author
Sheriff

Joined: Oct 14, 2002
Posts: 8815
    
    5
There's something else that I really like about this question!

On the real exam you'll often see a lot of code jammed together like in this example, so it's a good thing to get used to, and it's a good thing to look for in mocks.


Spot false dilemmas now, ask me how!
(If you're not on the edge, you're taking up too much room.)
Balaji Sampath
Ranch Hand

Joined: Sep 30, 2005
Posts: 63
HEY!!! sorryy.. really confused..

So for this code:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(B b) {System.out.print("B");}}
class C extends B {void m1(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C(); c1.m1(c2);
}}

I beleive the answer "C".

and for the code:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(A b) {System.out.print("B");}}
class C extends B {void m1(A c) {System.out.print("C");}}
class D {
public static void main(String[] args) {A c1 = new C(); C c2 = new C(); c1.m1(c2);}}

whats is the answer.. details appreciated...
Gyanesh Sharma
Ranch Hand

Joined: Nov 27, 2005
Posts: 47
In both samples, the answer would still be the same. In the second example, you are overriding the method m1. Since you are creating the object of type C only, the method of C is called.
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Originally posted by Gyanesh Sharma:
In both samples, the answer would still be the same.


No. Most of the postings in this thread are accurate,
but the inaccurate ones are just going to confuse people.

The original problem prints A:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(B b) {System.out.print("B");}}
class C extends B {void m1(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C(); c1.m1(c2);
}}



Variation #1 prints C:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(A b) {System.out.print("B");}}
class C extends B {void m1(A c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C(); c1.m1(c2);
}}


Variation #2 also prints C:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(B b) {System.out.print("B");}}
class C extends B {void m1(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
C c1 = new C(); C c2 = new C(); c1.m1(c2);
}}

If you're not sure exactly what you're talking about,
then please run the examples and see what they do
pefore posting. (I'm reasonably sure I know what I'm
talking about, but I took the precaution anyway.

If you have posted something inaccurate, please
consider using the pencil-on-paper icon to fix it.


bitguru blog
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Variation #3 prints A:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m2(B b) {System.out.print("B");}}
class C extends B {void m3(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
A c1 = new C(); C c2 = new C(); c1.m1(c2);
}}

And here calling c1.m3(c2) would be a
compile-time error. Does that help anyone
understand the original problem?
praveen Shangunathan
Ranch Hand

Joined: Sep 06, 2005
Posts: 65
as a rule of thumb,

overload -> compile time -> looks at reference.

override -> runtime -> looks as the object.

so first thing to find out is if a method is overloaded or overridden.
Anjana Ravindran
Ranch Hand

Joined: Aug 22, 2005
Posts: 76
Hi Brian,

Ur detailed answer is gud. But can you please explain why each behaves differently (clearly too)?

Thanks in advance,
Anjana
Gyanesh Sharma
Ranch Hand

Joined: Nov 27, 2005
Posts: 47
my bad
Anjana Ravindran
Ranch Hand

Joined: Aug 22, 2005
Posts: 76
0. Reference A, Object C. methods are overloaded and looks at reference type. Hence 'A'
1. Reference A, Object C. methods are overridden and looks at object type. Hence 'C'
2. Reference C, Object C. Hence 'C'
3. Reference A, Object C. methods are neither overloaded nor overridden. normal method call. looks at reference type. no such method called 'm3'. compilation error.

Let me know whether if my reasoning is wrong.

Regards,
Anjana
Deepa Srdhar
Greenhorn

Joined: Nov 23, 2005
Posts: 6
When the code is changed as follows:



it prints B.
Can someone please explain this. Thanks.
velan vel
Ranch Hand

Joined: Nov 15, 2005
Posts: 137
it searches the best match from subclasses to super class
Sasikanth Malladi
Ranch Hand

Joined: Nov 04, 2000
Posts: 175
To put everything into perspective,
void aMethod(ParentObject po){} and
void aMethod(ChildObject co){}
(whether they appear in the same class or across a class hierarchy) are overloaded and not overrridden.
For overridden methods, the arguments must exactly match.
This problem boils down to distinguishing between overloaded and overridden methods.
Also one very important distinction between overloading and overriding must be remembered: overloading is resolved at compile time and overriding at runtime.
Hence, in an overloaded method, the reference type determines which method gets called whereas in an overridden method the object type determines which method gets called (polymorphism at play).
HTH,
Sashi
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Well the reason I posted variation #3 (see above) is
that I think it's obvious to just about everyone that
it will print A, yet it is equivalent to the original
problem that some here find baffling.

Overridden methods are overridden methods, and if you
know how they work in Java then you understand why
variation #1 prints C. But there's nothing magic about
an overloaded method. That it has the same name as
another method might be confusing to humans, but to
the Java compiler* it's just another method and it
makes no difference if you rename it to something else.



*I say "Java compiler" here because anything having to
do with method overloading is handled at compile time.
Yes, Java has a form of dynamic method dispatch, but it
is limited. Overloaded methods do not participate, nor
do the run-time types of the arguments.
[ December 08, 2005: Message edited by: Brian Cole ]
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Oops, encountered a weird double-posting problem, so I'll
change this posting to include a new-and-exciting variation #4.

Variation #4 prints B:
class A {void m1(A a) {System.out.print("A");}}
class B extends A {void m1(B b) {System.out.print("B");}}
class C extends B {void m1(C c) {System.out.print("C");}}
class D {
public static void main(String[] args) {
C c1 = new C(); B c2 = new C(); c1.m1(c2);
}}

Note that the run-time type of c2 is still C, but that's irrelevant.
[ December 08, 2005: Message edited by: Brian Cole ]
 
 
subject: tricky question