-2

I have the following code and it runs successfully. But carefully note its output:

using System;                    
class Base 
{ 
    public int f(int i) 
    { 
        Console.Write("f (int): "); 
        return i + 3; 
    } 
} 
class Derived : Base 
{ 
    public double f(double i) 
    { 
        Console.Write("f (double) : "); 
        return i+3.3; 
    } 
} 
class MyProgram 
{ 
    static void Main(string[] args) 
    { 
        Derived obj = new Derived(); 
        Console.WriteLine(obj.f(3)); 
        Console.WriteLine(obj.f(3.3)); 
        Console.ReadKey(); // write this line if you use visual studio 
    } 
} 
Output:

f(double) : 6.3
f(double):  6.6 


Expected Output:

f(int) : 6
f(double) : 6.6 

Here it calls only Derived class method. But if I will change this program a little bit like shown below then output is unexpected. Then I tried something and I think it is to the order of precedence for types. When I swapped the Base class from int to double and Derived class from double to int, then the expected output was true.

using System;
namespace MyProgram
{
    class Base
    {
        public double f(double i)
        {
            Console.Write("f (double): ");
            return i + 3.3;
        }
    }
    class Derived : Base
    {
        public int f(int i)
        {
            Console.Write("f (int): ");
            return i + 3;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Derived obj = new Derived();
            Console.WriteLine(obj.f(3));
            Console.WriteLine(obj.f(3.3));
        }
    }
}
Output:

f(int) : 6
f(double) : 6.6 

How it is possible?

Tim
  • 398
  • 2
  • 6
  • 13
  • Wait a minute, why you expected that outputs? Have you tried to debug your code? – Sá´‡M Jun 25 '19 at 05:21
  • 3
    This is not `overloading`. This is `hiding`. You hide `f` method in `Base` class. When you initiate `Derived` and call `f` method. Of course `f` where is in `Derived` will run – Eldaniz Ismayilov Jun 25 '19 at 05:35

2 Answers2

1

In the first example, the compiler can do a trivial type cast between numeric types (int to double). This makes the f(double) function a possible call target. The compiler will prefer to call functions on the derived class where possible, because the derived class will probably contain more-specific logic. The base class is likely to contain more generic logic, so is less valuable.

In the second example, the function on the derived class is only callable with an int parameter. The compiler chooses this function because it's on the derived class, even though the function on the base class is potentially valid too. The function on the base class is the only option when the parameter is a double.

NZgeek
  • 199
  • 4
  • 1
    Good answer. One small nit: Instead of "trivial type cast" I would have stated that there is an [implicit conversion](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/implicit-numeric-conversions-table). – John Wu Jun 25 '19 at 05:50
0

Because that the default function to a derived object is the derived function (in your first program - double, and in the second - int). Just if it doesn't have the expected function, it will use the base function.

So:

  • In the first program - 3 is ok too for double, so it can use the derived function (double).
  • In the second program, 3 is ok for int, but 3.3 isn't ok for int. So for 3.3 it has to use the int function of the base class.