• 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
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

Exam Question: I can't explain this downcasting

 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why does this program output AAA.
I checked the instance of a3 using instanceof and it shows 'C', so why isn't the m1() of class C getting called !!! It's driving me nuts.
---------------------
public class Inheritance
{
public class A
{
public void m1(A a)
{
System.out.println("A");
}
}

public class B extends A
{
public void m1(B b)
{
System.out.println("B");
}
}

public class C extends B
{
public void m1(C c)
{
System.out.println("C");
}
}

public static final void main (String args[])
{
Inheritance i = new Inheritance();
Inheritance.A a1 = i.new A();
Inheritance.A a2 = i.new B();
Inheritance.A a3 = i.new C();
Inheritance.C c1 = i.new C();
a1.m1(c1);
a2.m1(c1);
a3.m1(c1);
/*
System.out.println("a1: " + a1);
System.out.println("a2: " + a2);
System.out.println("a3: " + a3);
c1.m1(a1);
c1.m1(a2);
c1.m1(a3);
*/
}
}
---------------------
 
Ranch Hand
Posts: 366
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Johny,

public class Inheritance
{
public class A
{
public void m1(A a)
{
System.out.println("A");
}
}

public class B extends A
{
public void m1(B b)
{
System.out.println("B");
}
}

public class C extends B
{
public void m1(C c)
{
System.out.println("C");
}
}

public static final void main (String args[])
{
Inheritance i = new Inheritance();
Inheritance.A a1 = i.new A();
Inheritance.A a2 = i.new B();
Inheritance.A a3 = i.new C();
Inheritance.C c1 = i.new C();
a1.m1(c1);
a2.m1(c1);
a3.m1(c1);
Inheritance.B b1 = i.new B();
b1.m1(c1); // This will print b
/*
System.out.println("a1: " + a1);
System.out.println("a2: " + a2);
System.out.println("a3: " + a3);
c1.m1(a1);
c1.m1(a2);
c1.m1(a3);
*/
}
}

In your code, you are not overrrding method m1. instead you are overloading it in the subclasses.
for example m1 takes an argument of class A in class A whereas m1 takes an argument of class B in class B. This is overloading not overriding. The result you expected will be obtained if all the m1 methods have the same arguments, say of class C. Then , it will be different.
I added a sample line of code which prints B only to show you that you have overloaded code
Hope this helps
sri
 
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
johnny NoName,
Welcome to Javaranch, a friendly place for Java greenhorns
We ain't got many rules 'round these parts, but we do got one. Please change your displayed name to comply with the JavaRanch Naming Policy.
Thanks Pardner! Hope to see you 'round the Ranch!
 
Mo Bustany
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Name change done
 
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I changed the references directly to each one instance type

the net result is 'ABC'.
But it is also If I override instead of overloading


So surely the m1(A a) method is called everytime.
Perhaps due to the fact that overloaded methods
are totally different methods?
Maybe because a parameter widening conversion have been done being
???
Finally the answer is:
Why the JVM calls the father's method?
 
Ranch Hand
Posts: 182
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was having trouble with this until a friend of mine explained to me like this: since a1, a2, and a3 are declared as being of type A, they can only see the methods declared in A. Since they were instantiated as being of type A, B and C, respectively, you can cast them to the class that has the method you want to use. I�ve added a bit of code to your program so it will print "ABC" after the "AAA":

I had to use two set of parenthesis so it would perform the casting before the method invocation.
Hope It Helps,
Francisco
 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
public class Inheritance
{
public class A
{
public void m1(A a)
{
System.out.println("A");
}
}

public class B extends A
{
}

public class C extends B
{
}
public static final void main (String args[])
{
Inheritance i = new Inheritance();
Inheritance.A a1 = i.new A();
Inheritance.A a2 = i.new B();
Inheritance.A a3 = i.new C();
Inheritance.C c1 = i.new C();
a1.m1(c1);
a2.m1(c1);
a3.m1(c1);
}
}
Here the output is also AAA.
Even now if the following code is executed output will stiil be AAA
public static final void main (String args[])
{
Inheritance i = new Inheritance();
Inheritance.A a1 = i.new A();
Inheritance.A a2 = i.new B();
Inheritance.A a3 = i.new C();
Inheritance.C c1 = i.new C();
a1.m1(c1);
a2.m1(c1);
a3.m1(c1);
}
So what i could recall from discussion is
exact-method has precedence. Lets say if method
m1(C c) is searched in instance of class C.
if not found then searched in super class B
If not found in superclass also, then type coversion of C to A is done and then method name is matched.
 
Mo Bustany
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yep, Francisco A Guimaraes' answer is the most valid. the Instances of A,B and C are assigned to variable of type A. So only A methods can be seen. The other m1 methods are distinctly different from the signature of m1 of A so they are never seen. PLEASE NOTE: Try this test, define a public member int variable, mVar in each of the three classes and assigned them different int values. Then use a1,a2,a3 to display them. You will get a surprising result. But first try to guess what the values will be.
<code>
public class A
{
public int mVar = 10;
......
}
public class B extends A
{
public int mVar = 20;
......
}
...........
...........
</code>
 
Igor Zeta
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rawat
You have said:

I expect a call to

in spite of the fact that this is the most specific method,but what has been called is the method owned by A as we have just seen before.
So what is coming out is that by default it is called the method owned by the type of the instance if no-cast is specified...

P.S.
Replying to Mo Bustany...The result I guess is the same as we've had with method call !?


[ February 05, 2003: Message edited by: Igor Zeta ]
 
Ranch Hand
Posts: 101
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I modifie dthe code little bit. The behavior here changes. Could someone explain why it is different in this case:
class A
{
public void m1(A a)
{
System.out.println("A");
}
}
class B extends A
{
public void m1(B b)
{
System.out.println("B");
}
}
class C extends B
{
public void m1(C c)
{
System.out.println("C");
}
}
public class Inheritance{
public static final void main (String args[])
{
A a1 = new A();
A a2 = new B();
A a3 = new C();
A c1 = new C();
System.out.println("Without casting:");
a1.m1(c1);
a2.m1(c1);
a3.m1(c1);
System.out.println("With casting:");
a1.m1(c1);
((B)a2).m1(c1);
((C)a3).m1(c1);
}
}
Why does it print A A and A even with the casting?
 
Igor Zeta
Ranch Hand
Posts: 40
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
After this two-day discussion we must arrive to a conclusion.
The method that will be called is the one that best fit into the parameter type relating to the object type.
Let's show it:

Being a1,a2,a3,c1 of type A and being A the superclass of B and C an implicit widening conversion to A has place.Narrowing in a second moment is allowed.

Result --> AAA

Result --> AAA

Result --> ABB

Result --> ABC
This shows that if nothing is declared it will be called the type's method else the one the best fit.
reply
    Bookmark Topic Watch Topic
  • New Topic