Open In App

Does overloading work with Inheritance?

Last Updated : 22 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

If we have a function in base class and another function with the same name in derived class, can the base class function be called from derived class object? This is an interesting question and as an experiment, predict the output of the following C++ program: 

C++




#include <iostream>
using namespace std;
class Base
{
public:
    int f(int i)
    {
        cout << "f(int): ";
        return i+3;
    }
};
class Derived : public Base
{
public:
    double f(double d)
    {
        cout << "f(double): ";
        return d+3.3;
    }
};
int main()
{
    Derived* dp = new Derived;
    cout << dp->f(3) << '\n';
    cout << dp->f(3.3) << '\n';
    delete dp;
    return 0;
}


The output of this program is: 

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

Instead of the supposed output: 

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

Overloading doesn’t work for derived class in the C++ programming language. There is no overload resolution between Base and Derived. The compiler looks into the scope of Derived, finds the single function “double f(double)” and calls it. It never disturbs the (enclosing) scope of Base. In C++, there is no overloading across scopes and derived class scopes are not an exception to this general rule. (See this for more examples)

Reference: technical FAQs on www.stroustrup.com 

Now consider the Java version of this program: 

Java




class Base
{
    public int f(int i)
    {
        System.out.print("f (int): ");
        return i+3;
    }
}
class Derived extends Base
{
    public double f(double i)
    {
        System.out.print("f (double) : ");
        return i + 3.3;
    }
}
class myprogram3
{
    public static void main(String args[])
    {
        Derived obj = new Derived();
        System.out.println(obj.f(3));
        System.out.println(obj.f(3.3));
    }
}


The output of the above program is: 

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

So in Java, overloading works across scopes, contrary to C++. The Java compiler determines the correct version of the overloaded method to be executed at compile time based upon the type of arguments used to call the method and the parameters of the overloaded methods of both these classes that receive the values of arguments used in call and executes that overloaded method.

Finally, let us try to get the output of the following C# program: 

C#




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


Note: Console.ReadKey() is used to halt the console. It is similar to getch() in C/C++. 
The output of the above program is: 

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

Instead of the assumed output: 

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

Explanation: Here, the object we are creating is of the derived class, so the compiler will give preference to the derived class first and will perform implicit type casting if needed. So as soon as the compiler comes to “Console.WriteLine(obj.f(3));”, it will check for parameter compatibility. Here, the value 3 is of type int which is compatible with the parameter type double of derived class function f. So the compiler will perform the implicit type conversion of int to double. Hence the output f(double) : 6.3 will come. 

Now when the compiler comes to “Console.WriteLine(obj.f(3.3));”, again it will give preference to the derived class first and will find it callable. So it will evaluate the derived class function f. Hence the output f(double): 6.6 will come.

Now let’s take another case where we are putting the base class function f into derived class and vice-versa as shown below:

C#




using System;                    
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 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 (int): 6
f (double) : 6.6

Are you shocked to see the expected output? How is it possible? 
Well, we have an answer to these questions. As the object we have created is of the derived class, the C# compiler will give first preference to derived and if it does not find any compatibility, then it goes for the base class. So when the compiler comes to “Console.WriteLine(obj.f(3));”, it will check the derived class method f and finding it callable, the compiler will execute this and the output f (int): 6 comes. Now when the compiler comes to “Console.WriteLine(obj.f(3.3));”, it will check the derived class method and find out that it is not suitable as the value 3.3 (double) is not compatible with the int data type. Hence the compiler will now prefer the base class and there it will find the best match, so it will execute that one. So the output for that one will be f (double) : 6.6.

The reason is the same as explained in the case of the C++ program. In C#, just like in C++, there is no overload resolution between class Base and class Derived. Also, there is no overloading across scopes and derived class scopes are not an exception to this general rule. This is same as C++ because C# is designed to be much closer to C++, according to Anders Hejlsberg, the creator of the C# language.

 



Previous Article
Next Article

Similar Reads

Does C support function overloading?
First of all, what is function overloading? Function overloading is a feature of a programming language that allows one to have many functions with same name but with different signatures. This feature is present in most of the Object Oriented Languages such as C++ and Java. But C doesn't support this feature not because of OOP, but rather because
2 min read
C++ | Operator Overloading | Question 10
How can we restrict dynamic allocation of objects of a class using new? (A) By overloading new operator (B) By making an empty private new operator. (C) By making an empty private new and new[] operators (D) By overloading new operator and new[] operators Answer: (C) Explanation: If we declare new and [] new operators, then the objects cannot be cr
1 min read
C++ | Operator Overloading | Question 2
Which of the following operators cannot be overloaded (A) . (Member Access or Dot operator) (B) ?: (Ternary or Conditional Operator ) (C) :: (Scope Resolution Operator) (D) .* (Pointer-to-member Operator ) (E) All of the above Answer: (E) Explanation: See What are the operators that cannot be overloaded in C++?Quiz of this Question
1 min read
C++ | Function Overloading and Default Arguments | Question 5
Which of the following in Object Oriented Programming is supported by Function overloading and default arguments features of C++. (A) Inheritance (B) Polymorphism (C) Encapsulation (D) None of the above Answer: (B) Explanation: Both of the features allow one function name to work for different parameter. Quiz of this Question
1 min read
C++ | Function Overloading and Default Arguments | Question 2
Output? #include&lt;iostream&gt; using namespace std; int fun(int x = 0, int y = 0, int z) { return (x + y + z); } int main() { cout &lt;&lt; fun(10); return 0; } (A) 10 (B) 0 (C) 20 (D) Compiler Error Answer: (D) Explanation: All default arguments must be the rightmost arguments. The following program works fine and produces 10 as output. #include
1 min read
C++ | Function Overloading and Default Arguments | Question 3
Which of the following overloaded functions are NOT allowed in C++? 1) Function declarations that differ only in the return type int fun(int x, int y); void fun(int x, int y); 2) Functions that differ only by static keyword in return type int fun(int x, int y); static int fun(int x, int y); 3)Parameter declarations that differ only in a pointer * v
1 min read
C++ | Function Overloading and Default Arguments | Question 4
Predict the output of following C++ program. include&lt;iostream&gt; using namespace std; class Test { protected: int x; public: Test (int i):x(i) { } void fun() const { cout &lt;&lt; &quot;fun() const &quot; &lt;&lt; endl; } void fun() { cout &lt;&lt; &quot;fun() &quot; &lt;&lt; endl; } }; int main() { Test t1 (10); const Test t2 (20); t1.fun(); t
1 min read
C++ | Operator Overloading | Question 3
Which of the following operators are overloaded by default by the compiler in every user defined classes even if user has not written? 1) Comparison Operator ( == ) 2) Assignment Operator ( = ) (A) Both 1 and 2 (B) Only 1 (C) Only 2 (D) None of the two Answer: (C) Explanation: Assign operator is by default available in all user defined classes even
1 min read
C++ | Function Overloading and Default Arguments | Question 5
Output of following program? #include &lt;iostream&gt; using namespace std; int fun(int=0, int = 0); int main() { cout &lt;&lt; fun(5); return 0; } int fun(int x, int y) { return (x+y); } (A) Compiler Error (B) 5 (C) 0 (D) 10 Answer: (B) Explanation: The statement "int fun(int=0, int=0)" is declaration of a function that takes two arguments with de
1 min read
C++ | Operator Overloading | Question 4
Which of the following operators should be preferred to overload as a global function rather than a member method? (A) Postfix ++ (B) Comparison Operator (C) Insertion Operator &lt;&lt; (D) Prefix++ Answer: (C) Explanation: cout is an object of ostream class which is a compiler defined class. When we do "cout &lt;&lt; obj&quot; where obj is an obje
1 min read
Practice Tags :