Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

tricky question

 
velan vel
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 21
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
c
 
harish shankarnarayan
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
1:static methods look on references
2:instance methods look on objects
AM I right
then how come it prints A.
explain
 
Srinivasa Raghavan
Ranch Hand
Posts: 1228
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
harish shankarnarayan
Ranch Hand
Posts: 158
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ya got it,
was a little confused
thanks Srini.
 
Jan Valenta
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Be carefull, this:



prints out 'C'.
 
jeroen dijkmeijer
Ranch Hand
Posts: 132
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 8898
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Balaji Sampath
Ranch Hand
Posts: 63
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
Brian Cole
Author
Ranch Hand
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 65
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
my bad
 
Anjana Ravindran
Ranch Hand
Posts: 76
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When the code is changed as follows:



it prints B.
Can someone please explain this. Thanks.
 
velan vel
Ranch Hand
Posts: 137
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
it searches the best match from subclasses to super class
 
Sasikanth Malladi
Ranch Hand
Posts: 175
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 907
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic