Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Overriding doubt?

 
Swapnil Sapar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"In overriding, the method that is called is determined at runtime by type of the object, irrespective of type of reference."

If the above statement is true then can somebody give the justification for follwing???

class Fish
{
public void bite(long howHard)
{
System.out.println("Fish::bite");
}
}

class Shark extends Fish
{
public void bite(int howHard)
{
System.out.println("Shark::bite");
}
public static void main(String[] arg)
{
Shark s = new Shark();
Fish f = new Shark();

s.bite(10);// prints: Shark::bite, which is OK
f.bite(10);// prints: Fish::bite :roll:
}
}
 
Ankush Bhargava
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The method signatures are different.
Hence, overriding is not happening in this case.

if you change both of them to 'int' or both of them to 'long', you will note the difference.

Cheers.
Ankush
 
Swapnil Sapar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Ankush,
But that is exactly my point.
If the 'overriding is not happening' then why is it working if I use Shark's reference?
How does a reference is determining which method to call?
~Swapnil
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Overriding is not happening when you use the reference s to a Shark. You have s.bite(10), so the compiler has to chose between the two overloaded methods (one of which is inherited from Fish) in class Shark. Because 10 is an int literal it can choose Shark.bite(int) without any ambiguity.
 
Swapnil Sapar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Whooilla !!!
Thanks Barry. Now its clear. Overriding is NOT happening here and its simple overloading which does the magic !
Crystal, No more confusion here.

Cheers!
Swapnil
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


I changed the code slightly and now get an error message that "s.bite(10)" is an ambiguous reference. You might think the compiler would choose the "more specific" signature, which should be "bite(int)" because you can convert an int to a long but you can't convert a long to an int without an explicit cast. However, there is an additional part of the definition of "more specific" which is that the more specific method's declaration must be in the same class as, or a subclass of, the class containing the less specific signature. So just reversing the types of the formal parameters makes the reference ambiguous.

Also, using a short parameter type causes an error because the literal argument "10" won't be converted to a short in a method invocation without an explicit cast "(short)10".

Devious rules to watch for on the exam.

From the Java Language Specification, 2nd Edition:

From Section 15.12.2.2
Let m be a name and suppose that there are two declarations of methods named m, each having n parameters. Suppose that one declaration appears within a class or interface T and that the types of the parameters are T1, . . . , Tn; suppose moreover that the other declaration appears within a class or interface U and that the types of the parameters are U1, . . . , Un. Then the method m declared in T is more specific than the method m declared in U if and only if both of the following are true:

* T can be converted to U by method invocation conversion.
* Tj can be converted to Uj by method invocation conversion, for all j from 1 to n.

...

From Section 5.3
Method invocation [conversion] allows the use of an identity conversion, a widening primitive conversion, or a widening reference conversion.

...

Also from Section 5.3
Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion.

[ December 18, 2004: Message edited by: Mike Gershman ]
 
Barry Gaunt
Ranch Hand
Posts: 7729
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interestingly Mike, using Java 1.5, I do not get any error when compiling your version of the classes. And running it produces:
Fish::bite
Fish::bite


Are you using Java 1.4 to test this?
 
Jay Pawar
Ranch Hand
Posts: 411
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using j2sdk1.4.2_06 and I do not get any errors . I get the same output as Barry mentioned.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you using Java 1.4 to test this?

Well I'll be hornswoggled, the compile fails on Java 1.4 and works on Java 1.5. I am using the old compiler for Java 1.4 exam questions, just to be safe.

Great catch, Barry!

I did some research and found that Sun has done a very low-key (read sneaky) change to the language spec. There is a document
JLS Clarifications and Amendments, Second Edition
which has eliminated the extra class relationship requirement from the definition of "more specific". The document doesn't specify whether this is a clarification (applicable to Java 2) or amendment (only applicable to Java 5).

I suspect that Sun found that the extra requirement was pointless and confusing, but it was still not right to leave the change out of the official "New Features and Enhancements" list.

>>A question for Kathy or Bert is which rule the Java 2 certification exam will follow.<<

Just for the record, here is the clarification/amendment from Sun:
Let m be a name and suppose that there are two member methods named m, each having n parameters. Suppose that the types of the parameters of one member method are T1, . . . , Tn; suppose moreover that the types of the parameters of the other method are U1, . . . , Un. Then the first member method is more specific than other if and only if Tj can be converted to Uj by method invocation conversion, for all j from 1 to n. A method is strictly more specific than another if and only if it is both more specific and the signatures of the two methods are not identical.
 
Mike Gershman
Ranch Hand
Posts: 1272
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using j2sdk1.4.2_06 and I do not get any errors . I get the same output as Barry mentioned.

I double checked and I do get the error with j2sdk 1.4.1_01
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic