-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?

2
  • Wait a minute, why you expected that outputs? Have you tried to debug your code? Commented Jun 25, 2019 at 5: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 Commented Jun 25, 2019 at 5:35

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Good answer. One small nit: Instead of "trivial type cast" I would have stated that there is an implicit conversion.
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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.