Reputation: 373
I asked a similiar question yesterday, but another issue has arisen.
class Cat {
public void isClawedBy(Cat c, Kitten k){
System.out.println("Clawed by a cat");
}
}
class Kitten extends Cat{
public void isClawedBy(Kitten k, Cat c){
System.out.println("Clawed by a Kit");
}
}
Cat g = new Cat();
Cat s = new Kitten();
Kitten t = new Kitten();
g.isClawedBy(s,t);
s.isClawedBy(t,s);
t.isClawedBy(t,t);
The issue i am am confused about is around t.isClawedBy(t,t);
. I understand that s.isClawedBy(t,s);
will throw an error, because s is of static type cat.
But t.isClawedBy(t,t);
is throwing a "The method isClawedBy(Kitten, Cat) is ambiguous for the type Kitten" error. If i change the code to t.isClawedBy(s,t);
or t.isClawedBy(t,s);
it works, but unsure as to why it doesnt work for (t,t).
Thanks in advance
Upvotes: 2
Views: 194
Reputation: 1
Kitten extends cat, so kitten gets the attributes and methods of cat, so kitten class knows 2 methods:
public void isClawedBy(Cat c, Kitten k)
public void isClawedBy(Kitten k, Cat c)
But it doesn't know a method
public void isClawedBy(Kitten k, Kitten k)
so it doesn't know what to do when you call isClawedBy(t, t);
Upvotes: 0
Reputation: 4844
In Java method calls are resolved dynamically. When you call a method the JVM tries to find a method that matches the signature i.e. method name, parameter types and return types. It does this by looking in the method table of the class used, which will contain the method signatures of super types also.
When checking if a signature in the method table is suitable it will take into account the supertypes of the parameter (and return) types. In the case of t.isClawedBy(t,t)
we have two methods that can match as the method defined in Kitten
matches and that defined in Cat
matches - note that these are different methods as they have different parameter types.
As two different methods match the method call is ambiguous.
For isClawed(s,t)
and isClawed(t,s)
there is no ambiguity as s
is a Kitten and cannot be a Cat.
Upvotes: 1
Reputation: 795
It is ambiguous because Kitten
s are Cat
s.
Thus, given:
Cat isClawedBy(Cat c, Kitten k)
Kitten isClawedBy(Kitten k, Cat c)
For a Kitten
, both methods are available. A Kitten
is a Cat
, so a call to Cat.isClawedBy(Cat, Kitten)
with two Kitten
arguments fits the signature. Likewise, a call to Kitten.isClawedBy(Kitten, Cat)
with two Kitten
s also matches the signature.
There is no way for the compiler to tell which method was intended.
Upvotes: 1
Reputation: 5087
It is because you didn't override that method.
For t.isClawedBy(t,t);
there are two possible methods to execute.The Cat's isclawed method and the Kitten's isclawed method.
To override a method paremeters must be the same.
Upvotes: 0