The Artima Developer Community
Sponsored Link

Java Answers Forum
Flaw in inheritance and overloading combination?

3 replies on 1 page. Most recent reply: Jul 31, 2002 4:44 PM by Kishori Sharan

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 3 replies on 1 page
Antonello Cruz

Posts: 1
Nickname: toni
Registered: Jul, 2002

Flaw in inheritance and overloading combination? Posted: Jul 31, 2002 12:03 PM
Reply to this message Reply
Advertisement
Reading Bruce Eckel? Thinking in Java, I stepped in this problem when solving one exercise about inheritance and overloading. This was the compiling-time error message I got:

Reference to method is ambiguous, both method overTest(int) in Base and method overTest(float) in Test match
      x.overTest(10);
       ^

The code is very simple and just for learning and understanding the topic. I really don?t believe it is wrong! Here it is:
class Base {
   public void overTest() {
      System.out.println("method without any arguments");
   }
   
   public void overTest(String s) {
      System.out.println("method with String argument: " + s);
   }
   
   public void overTest(int i) {
      System.out.println("method with int argument: " + i);
   }
}
 
public class Test extends Base {
   public void overTest(float f) {
      System.out.println("method with float argument: " + f);
   }
   
   public static void main(String[] args) {
      Test x = new Test();
      x.overTest();
      x.overTest((args.length > 0) ? args[0] : "TIJ");
      x.overTest(10);
      x.overTest(1.4f);
   }
}

I tried casting the method call but it didn?t work.
      x.overTest((int) 10);

I tried also sdk 1.3.1 and 1.2.2 to compile this but I got the same message. I did not have the opportunity to test in a system different from windows, though.

The code works if you put everything in one class ? without deriving a new class. Such as in this code:
public class Test1 {
	public void overTest() {
		System.out.println("method without any arguments");
	}
	
	public void overTest(String s) {
		System.out.println("method with String argument: " + s);
	}
	
	public void overTest(int i) {
		System.out.println("method with int argument: " + i);
	}
	
	public void overTest(float f) {
		System.out.println("method with float argument: " + f);
	}
	
	public static void main(String[] args) {
		Test1 x = new Test1();
      x.overTest();
      x.overTest((args.length > 0) ? args[0] : "TIJ");
      x.overTest(10);
      x.overTest(1.4f);
	}
}

or if you make the methods static, such as in this example:
class Base2 {
   public static void overTest() {
      System.out.println("method without any arguments");
   }
   
   public static void overTest(String s) {
      System.out.println("method with String argument: " + s);
   }
   
   public static void overTest(int i) {
      System.out.println("method with int argument: " + i);
   }
}
 
public class Test2 extends Base2 {
   public static void overTest(float f) {
      System.out.println("method with float argument: " + f);
   }
   
   public static void main(String[] args) {
      overTest();
      overTest((args.length > 0) ? args[0] : "TIJ");
      overTest(10);
      overTest(1.4f);
   }
}

It does not look the behavior it should have to me. Am I missing something here? Does anyone understand why this happens? Does it compile under a different operating system?


Don Hill

Posts: 70
Nickname: ssswdon
Registered: Jul, 2002

Re: Flaw in inheritance and overloading combination? Posted: Jul 31, 2002 1:59 PM
Reply to this message Reply
Just tell the compiler that you want the literal 10 to be treated as a long such as
overTest(10l);
overTest(1.4f);

this should be fine, the compiler is trying to cast to a prim type so you need to specify the explicit cast.

HTH


> Reading Bruce Eckel? Thinking in Java, I stepped in
> this problem when solving one exercise about
> inheritance and overloading. This was the
> compiling-time error message I got:
>
> Reference to method is ambiguous, both method
> overTest(int) in Base and method overTest(float) in
> Test match
>
      x.overTest(10);
> ^

> The code is very simple and just for learning and
> understanding the topic. I really don?t believe it is
> wrong! Here it is:
>
> class Base {
> public void overTest() {
> System.out.println("method without any
> t any arguments");
> }
> 
> public void overTest(String s) {
> System.out.println("method with String
> tring argument: " + s);
> }
> 
> public void overTest(int i) {
> System.out.println("method with int argument: "
> nt: " + i);
> }
> }
> 
> public class Test extends Base {
> public void overTest(float f) {
> System.out.println("method with float argument:
> ment: " + f);
> }
> 
> public static void main(String[] args) {
> Test x = new Test();
> x.overTest();
> x.overTest((args.length > 0) ? args[0] :
> [0] : "TIJ");
> x.overTest(10);
> x.overTest(1.4f);
> }
> }

> I tried casting the method call but it didn?t work.
>
      x.overTest((int) 10);

> I tried also sdk 1.3.1 and 1.2.2 to compile this but
> I got the same message. I did not have the
> opportunity to test in a system different from
> windows, though.
>
> The code works if you put everything in one class ?
> without deriving a new class. Such as in this code:
>
> public class Test1 {
> public void overTest() {
> System.out.println("method without any
> y arguments");
> }
> 
> public void overTest(String s) {
> System.out.println("method with String argument: "
> " + s);
> }
> 
> public void overTest(int i) {
> System.out.println("method with int argument: " +
> + i);
> }
> 
> public void overTest(float f) {
> System.out.println("method with float argument: " +
> + f);
> }
> 
> public static void main(String[] args) {
> Test1 x = new Test1();
> x.overTest();
> x.overTest((args.length > 0) ? args[0] :
> [0] : "TIJ");
> x.overTest(10);
> x.overTest(1.4f);
> }
> }

> or if you make the methods static, such as in this
> example:
>
> class Base2 {
> public static void overTest() {
> System.out.println("method without any
> t any arguments");
> }
> 
> public static void overTest(String s) {
> System.out.println("method with String
> tring argument: " + s);
> }
> 
> public static void overTest(int i) {
> System.out.println("method with int argument: "
> nt: " + i);
> }
> }
> 
> public class Test2 extends Base2 {
> public static void overTest(float f) {
> System.out.println("method with float argument:
> ment: " + f);
> }
> 
> public static void main(String[] args) {
> overTest();
> overTest((args.length > 0) ? args[0] : "TIJ");
> overTest(10);
> overTest(1.4f);
> }
> }

> It does not look the behavior it should have to me.
> Am I missing something here? Does anyone understand
> why this happens? Does it compile under a different
> operating system?

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Flaw in inheritance and overloading combination? Posted: Jul 31, 2002 3:58 PM
Reply to this message Reply
If you specify a long in this case, it will use the float overload, which I don't think was the intent.

The problem here is that when you specify an integer value, it can legally satisfy both the int overload in the base and the float overload in the derived class. I think the way you'd really want to solve this problem is to remove the ambiguity, by adding the following to your derived class:
   public void overTest(int i)
   {
      super.overTest(i);
   }

Kishori Sharan

Posts: 211
Nickname: kishori
Registered: Feb, 2002

Re: Flaw in inheritance and overloading combination? Posted: Jul 31, 2002 4:44 PM
Reply to this message Reply
Here is the explanation of why you got this compiler error saying : "Method reference is ambiguous". If you just move overTest ( float ) to Base class and overTest (int) to Test class then the code will compile and run fine. Again, if you make overTest in Base and Test "static" then again code will compile and work fine. So, what is the real problem? We need to look into the method invocation process in Java. In case of two methods matching ( not exaclty rather applicable)the more specific method is chosen for invocation. One important thing to mention here is that for all non-static methods of a class there is one extra method argument that is provided by compiler and its name is "this" with its type as same as class type. For example, for overTest ( int i ) in Base class we can think of real overTest(int i ) method as overTest(Base this, int i ) and for overTest ( float f ) in Test class it can be thought as overTest (Test this, float f). Now based on argument passed as 10 there are two methods that are applicable:
Base->overTest(int i)
Test->overTest(float f)
If you try to find out, which method is more specific then you jump to conclusion that Base->overTest(int i) is more specific because int i can be assigned to float f, but not vice-versa. And, according to your conclusion Base->overTest(int i) should be chosen by the compiler. But, this is not the case. We are forgetting the hidden parameter "this" for every non-static methods. Methods signature should be viewed as:

Base->overTest(Base this, int i)
Test->overTest(Test this, float f)

Here, Base this cannot be assigned to Test this and at the same time float f cannot be assigned to int i. And, this is why the method reference is ambigous in this case. I think you got the point. Now let us move overTest(float) to Base class and then overTest(int i ) to Test. Now methods signature can be viewed as:
Base->overTest(Base this, float f)
Test->overTest(Test this, int i)

Now it is clear that Base this and float f cannot be assigned to Test this and int i respectively. However, opposite is true. Therefore. Test-> (int i ) will be called. The same argument applies when you move both methods in Base. Since the "this" arguments will be of the same kind i.e. Base, so int i is the most specific method argument in that case.

So, what is the solution. One has been provided in the previous post by Matt. Others are: make methods static. Of course, then you are not using method overriding rather method hiding. Or, move all methods in one class. Do whatever suits your design and requirements.

Thanks
Kishori

Thanks
Kishori

Flat View: This topic has 3 replies on 1 page
Topic: changing the color of row of table Previous Topic   Next Topic Topic: sorting


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2017 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us