¿Funciona la sobrecarga con Herencia?

Si tenemos una función en la clase base y otra función con el mismo nombre en la clase derivada, ¿se puede llamar a la función de la clase base desde el objeto de la clase derivada? Esta es una pregunta interesante y, como experimento, prediga la salida del siguiente programa C++

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

La salida de este programa es: 

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

En lugar de la supuesta salida: 

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

La sobrecarga no funciona para la clase derivada en el lenguaje de programación C++. No hay resolución de sobrecarga entre Base y Derivado. El compilador examina el alcance de Derived, encuentra la función única «doble f (doble)» y la llama. Nunca perturba el alcance (que encierra) de Base. En C++, no hay sobrecarga entre los ámbitos y los ámbitos de clases derivadas no son una excepción a esta regla general. (Ver esto para más ejemplos)

Referencia: preguntas frecuentes técnicas en www.stroustrup.com 

Ahora considere la versión Java de este programa: 

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

La salida del programa anterior es: 

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

Entonces, en Java, la sobrecarga funciona en todos los ámbitos, al contrario que en C++. El compilador de Java determina la versión correcta del método sobrecargado que se ejecutará en tiempo de compilación según el tipo de argumentos utilizados para llamar al método y los parámetros de los métodos sobrecargados de ambas clases que reciben los valores de los argumentos utilizados en la llamada y ejecuta ese método sobrecargado.

Finalmente, intentemos obtener el resultado del siguiente programa C#

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

Nota : Console.ReadKey() se usa para detener la consola. Es similar a getch() en C/C++. 
La salida del programa anterior es: 

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

En lugar de la salida asumida: 

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

Explicación: aquí, el objeto que estamos creando es de la clase derivada, por lo que el compilador dará preferencia a la clase derivada primero y realizará una conversión de tipos implícita si es necesario. Entonces, tan pronto como el compilador llegue a » Console.WriteLine(obj.f(3));», verificará la compatibilidad de los parámetros. Aquí, el valor 3 es de tipo int , que es compatible con el tipo de parámetro double de la función de clase derivada f . Entonces, el compilador realizará la conversión de tipo implícita de int a double . Por lo tanto, vendrá la salida f(doble): 6.3

Ahora, cuando el compilador llega a » Console.WriteLine(obj.f(3.3));» , nuevamente dará preferencia a la clase derivada primero y la encontrará invocable. Entonces evaluará la función de clase derivada f . Por lo tanto, vendrá la salida f(doble): 6.6 .

Ahora tomemos otro caso en el que estamos colocando la función de clase base f en la clase derivada y viceversa, como se muestra a continuación:

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

Producción: 

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

¿Estás sorprendido de ver el resultado esperado? ¿Como es posible?  
Bueno, tenemos una respuesta a estas preguntas. Como el objeto que hemos creado es de la clase derivada, el compilador de C# dará preferencia a la clase derivada y, si no encuentra ninguna compatibilidad, se va a la clase base. Entonces, cuando el compilador llega a » Console.WriteLine(obj.f(3));», verificará el método de clase derivada f y lo encontrará invocable, el compilador ejecutará esto y la salida f (int): 6 viene . Ahora, cuando el compilador llega a » Console.WriteLine(obj.f(3.3));»,verificará el método de la clase derivada y descubrirá que no es adecuado ya que el valor 3.3 (doble) no es compatible con el tipo de datos int. Por lo tanto, el compilador ahora preferirá la clase base y allí encontrará la mejor coincidencia, por lo que la ejecutará. Entonces, la salida para ese será f (doble): 6.6 .

El motivo es el mismo que el explicado en el caso del programa C++. En C#, al igual que en C++, no hay resolución de sobrecarga entre la clase Base y la clase Derivada. Además, no hay sobrecarga entre los ámbitos y los ámbitos de clases derivadas no son una excepción a esta regla general. Esto es lo mismo que C++ porque C# está diseñado para estar mucho más cerca de C++, según Anders Hejlsberg , el creador del lenguaje C#.

Este artículo es una contribución de Pravasi Meet . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *