• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Overloading/Overriding Methods

 
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please refer to the code below. I am getting compiler error "The method printObj(Son) is ambiguous for the type GrandSon". Just want to better undertand reason for this error and also what are the other possibilities where i might get this error.

* This is my own code. Trying to understand Overloading and Overriding from Kathy Sierra/Bert Bates SCJP book pg 99


Thank you for your help.
 
Ranch Hand
Posts: 138
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sachin,
In your code
you pass the object of the class Grandson as argument but there is no method definition with grandson object as argument.So only you got this error.
If you add the method wiht Grandson obj as argument you can resolve this problem.


Hopes this helps.
 
Ranch Hand
Posts: 317
Eclipse IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sachin,

As there is not exact match for a method printObj with a parameter "GrandSon". So the compiler will check for any other method which can be used in a polymorphic way, means any overloaded version which can be used by passing "GrandSon" object. Candidate methods are those which accepts the parent class of "GrandSon". In your code there are three such methods :



All of these three methods can be called by passing "GrandSon" as an argument. So compiler will be confuse because of multiple eligible methods and will not be able to conclude any single method to call, Hence throws an exception regarding ambiguous methods.
 
Sachin Deokar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Harpreet Singh janda wrote:Hi Sachin,

As there is not exact match for a method printObj with a parameter "GrandSon". So the compiler will check for any other method which can be used in a polymorphic way, means any overloaded version which can be used by passing "GrandSon" object. Candidate methods are those which accepts the parent class of "GrandSon". In your code there are three such methods :



All of these three methods can be called by passing "GrandSon" as an argument. So compiler will be confuse because of multiple eligible methods and will not be able to conclude any single method to call, Hence throws an exception regarding ambiguous methods.


I agree Harpreet. But the code just works fine if i delete

If the option is between

It chooses 1st. Is it coz Son is the immediate parent of Grandson?

Thanks for your comments.

Sachin
 
Ranch Hand
Posts: 91
Notepad
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Sachin.

Let me try to explain

class Dad {
String printMe() {
System.out.println("Dad");
return "Dad";
}
}

public class Son extends Dad {

String printMe() {
System.out.println("Son");
return "Son";
}

public static void main(String[] args) {
GrandSon o = new GrandSon();
o.printObj(o);
}
}

interface Intfc {
String printMe();
}

class GrandSon extends Son implements Intfc {
public String printMe() {
System.out.println("GrandSon");
return "GrandSon";
}

void printObj(Son o) {
System.out.println("1 " + o.printMe());
}

void printObj(Dad o) {
System.out.println("2 " + o.printMe());
}



void printObj(Intfc o) {
System.out.println("3 " + o.printMe());
}
}


In your code

GrandSon IS A relationship with Son
Son IS A relationship with Dad

so we can say

GrandSon IS A relationship with Dad

Intfc IS implemented by GrandSon

Thus we can say

Intfc Is implemented immediately by Son and then by Dad thus

even if write in our code only these two methods

It will cause compiler error that
reference to printObj is ambiguous, both method printObj(Dad) in GrandSon and method printObj(Intfc) in GrandSon match
o.printObj(o);
Here it happens because both Son and Dad are in contract with Intfc.
 
Sachin Deokar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Sumit.

I do understand now that at runtime jvm gets confused between those two methods as they both pass IS A relationship and hence the runtime ambiguous error. Also, it maybe coz both are its immediate parents (Son is extended and Intfc is implemented by GrandSon).

But still trying to find the reason why the code works when I remove printObj(Intfc o) and just keep the two methods mentioned below? Out of these two options it chooses printObj(Son o). Is it coz Son is the immediate parent of Grandson and it is closer in hierarchy compared to Dad?



 
Ranch Hand
Posts: 183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Hi ,

THis is bec the compiler looks for the most specific method. Among printObj(Son)
and printObj(Dad) method printObj(Son) is the most specific one. So the compiler gives
no error. But when you also have printObj(intrf) together with these two methods compiler
cannot find the most specific method and hence the error.
 
Sachin Deokar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How would you define "specific"?

Simran Dass wrote:
Hi ,

THis is bec the compiler looks for the most specific method. Among printObj(Son)
and printObj(Dad) method printObj(Son) is the most specific one. So the compiler gives
no error. But when you also have printObj(intrf) together with these two methods compiler
cannot find the most specific method and hence the error.

 
Simran Dass
Ranch Hand
Posts: 183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

One which is closest in the inheritance hierarchy. Grandson extends Son , Son extends Dad.
So printObj(Son) is the closest one.
 
Sachin Deokar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Simran Dass wrote:
One which is closest in the inheritance hierarchy. Grandson extends Son , Son extends Dad.
So printObj(Son) is the closest one.



Thanks Simran.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sachin Deokar wrote:


Note: Inheritance with regard to object oriented programming has a different meaning than biological inheritance. Calling classes in an inheritance hierarchy "Dad", "Son" and "GrandSon" confuses the two and makes it more difficult to understand object oriented inheritance.

In object oriented programming, there is an "is a" relationship between subclasses and superclasses. An instance of a subclass is a (specialized version of an) instance of the superclass. When you write "class Son extends Dad", what you're saying is that a Son is a Dad, which is kind of strange.

It's better to use class names that reflect the "is a" relationship. For example, make a class Animal, and a class Cat that extends Animal. A Cat is an Animal.
 
Greenhorn
Posts: 27
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
here we will not get if we comment any two printObj method in GrandSon class.

Compile time error is coming because compiler is confusing which method to use and if we are putting below code in GrandSon class then we ll not get compiler error because compiler know the method of GranSon type .

void printObj(GrandSon o) {
System.out.println("4 " + o.printMe());
}
 
Sachin Deokar
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper Young wrote:
It's better to use class names that reflect the "is a" relationship. For example, make a class Animal, and a class Cat that extends Animal. A Cat is an Animal.



Thanks Jasper. I agree with you. My naming convention doesn't reflect the "is a" relationship and would be more mindful of that concept while naming my classes in future..

Thank you all for your comments and helping me clear my confusion.
reply
    Bookmark Topic Watch Topic
  • New Topic