stringtranslate.com

Sobrecarga de funciones

En algunos lenguajes de programación , la sobrecarga de funciones o de métodos es la capacidad de crear múltiples funciones con el mismo nombre y con diferentes implementaciones. Las llamadas a una función sobrecargada ejecutarán una implementación específica de esa función apropiada para el contexto de la llamada, lo que permite que una llamada de función realice diferentes tareas según el contexto.

Por ejemplo, doTask() y doTask(object o) son funciones sobrecargadas. Para llamar a la última, se debe pasar un objeto como parámetro , mientras que la primera no requiere un parámetro y se llama con un campo de parámetro vacío. Un error común sería asignar un valor predeterminado al objeto en la segunda función, lo que daría como resultado un error de llamada ambiguo , ya que el compilador no sabría cuál de los dos métodos utilizar.

Otro ejemplo es una función Print(object o) que ejecuta diferentes acciones según se trate de imprimir texto o fotos. Las dos funciones diferentes pueden estar sobrecargadas como Print(text_object T); Print(image_object P) . Si escribimos las funciones de impresión sobrecargadas para todos los objetos que nuestro programa "imprimirá", nunca tendremos que preocuparnos por el tipo de objeto y la llamada a la función correcta, siempre será: Print(something) .

Idiomas que admiten sobrecarga

Los lenguajes que admiten la sobrecarga de funciones incluyen, entre otros, los siguientes:

Reglas en la sobrecarga de funciones

La sobrecarga de funciones suele estar asociada a lenguajes de programación de tipado estático que aplican la comprobación de tipos en las llamadas a funciones . Una función sobrecargada es un conjunto de funciones diferentes que se pueden llamar con el mismo nombre. Para cualquier llamada en particular, el compilador determina qué función sobrecargada utilizar y la resuelve en tiempo de compilación . Esto es cierto para lenguajes de programación como Java. [10]

La sobrecarga de funciones se diferencia de las formas de polimorfismo en las que la elección se realiza en tiempo de ejecución, por ejemplo, a través de funciones virtuales , en lugar de hacerlo de forma estática.

Ejemplo: Sobrecarga de funciones en C++

#include <flujo de datos> int Volumen ( int s ) { // Volumen de un cubo. return s * s * s ; }          double Volume ( double r , int h ) { // Volumen de un cilindro. return 3.1415926 * r * r * static_cast < double > ( h ); }              long Volume ( long l , int b , int h ) { // Volumen de un cuboide. return l * b * h ; }              int main () { std :: cout << Volumen ( 10 ); std :: cout << Volumen ( 2.5 , 8 ); std :: cout << Volumen ( 100l , 75 , 15 ); }              

En el ejemplo anterior, el volumen de cada componente se calcula utilizando una de las tres funciones denominadas "volumen", con selección basada en el diferente número y tipo de parámetros reales.

Sobrecarga del constructor

Los constructores , utilizados para crear instancias de un objeto, también pueden estar sobrecargados en algunos lenguajes de programación orientados a objetos . Debido a que en muchos lenguajes el nombre del constructor está predeterminado por el nombre de la clase, parecería que solo puede haber un constructor. Siempre que se necesitan varios constructores, se deben implementar como funciones sobrecargadas. En C++ , los constructores predeterminados no toman parámetros, instanciando los miembros del objeto con sus valores predeterminados apropiados, "que normalmente es cero para campos numéricos y cadena vacía para campos de cadena". [11] Por ejemplo, un constructor predeterminado para un objeto de factura de restaurante escrito en C++ podría establecer la propina en 15%:

Factura () : propina ( 0,15 ), // porcentaje total ( 0,0 ) { }     

La desventaja de esto es que se necesitan dos pasos para cambiar el valor del objeto Bill creado. A continuación se muestra la creación y el cambio de valores dentro del programa principal:

Café de facturas ; café . propina = 0,10 ; café . total = 4,00 ;     

Si se sobrecarga el constructor, se pueden pasar la propina y el total como parámetros en la creación. Esto muestra el constructor sobrecargado con dos parámetros. Este constructor sobrecargado se coloca en la clase, así como el constructor original que usamos antes. El que se use depende de la cantidad de parámetros proporcionados cuando se crea el nuevo objeto Bill (ninguno o dos):

Factura ( doble propina , doble total ) : propina ( propina ), total ( total ) { }       

Ahora, una función que crea un nuevo objeto Bill podría pasar dos valores al constructor y configurar los miembros de datos en un solo paso. A continuación, se muestra la creación y configuración de los valores:

Billete de café ( 0,10 , 4,00 );  

Esto puede ser útil para aumentar la eficiencia del programa y reducir la longitud del código.

Otra razón para la sobrecarga del constructor puede ser la de imponer miembros de datos obligatorios. En este caso, el constructor predeterminado se declara privado o protegido (o preferiblemente eliminado desde C++11 ) para que no sea accesible desde el exterior. Para la factura anterior, total podría ser el único parámetro del constructor, ya que una factura no tiene un valor predeterminado razonable para total, mientras que la propina tiene un valor predeterminado de 0,15.

Complicaciones

Dos problemas interactúan con la sobrecarga de funciones y la complican: el enmascaramiento de nombres (debido al alcance ) y la conversión de tipos implícita .

Si se declara una función en un ámbito y luego se declara otra función con el mismo nombre en un ámbito interno, hay dos posibles comportamientos de sobrecarga naturales: la declaración interna enmascara la declaración externa (independientemente de la firma), o tanto la declaración interna como la externa se incluyen en la sobrecarga, y la declaración interna enmascara la externa solo si la firma coincide. La primera se toma en C++: "en C++, no hay sobrecarga entre ámbitos". [12] Como resultado, para obtener un conjunto de sobrecarga con funciones declaradas en diferentes ámbitos, es necesario importar explícitamente las funciones del ámbito externo al ámbito interno, con la usingpalabra clave.

La conversión de tipos implícita complica la sobrecarga de funciones porque si los tipos de parámetros no coinciden exactamente con la firma de una de las funciones sobrecargadas, pero pueden coincidir después de la conversión de tipos, la resolución depende de la conversión de tipos elegida.

Estos pueden combinarse de formas confusas: una coincidencia inexacta declarada en un ámbito interno puede enmascarar una coincidencia exacta declarada en un ámbito externo, por ejemplo. [12]

Por ejemplo, para tener una clase derivada con una función sobrecargada que toma a doubleo an int, usando la función que toma an intde la clase base, en C++, uno escribiría:

clase B { público : void F ( int i ); };      clase D : público B { público : usando B :: F ; void F ( double d ); };           

No incluir los usingresultados en un intparámetro pasado a Fla clase derivada se convierte en un doble y coincide con la función en la clase derivada, en lugar de en la clase base; la inclusión usingda como resultado una sobrecarga en la clase derivada y, por lo tanto, coincide con la función en la clase base.

Advertencias

Si un método está diseñado con una cantidad excesiva de sobrecargas, puede resultar difícil para los desarrolladores discernir qué sobrecarga se está invocando simplemente leyendo el código. Esto es particularmente cierto si algunos de los parámetros sobrecargados son de tipos que son tipos heredados de otros parámetros posibles (por ejemplo, "objeto"). Un IDE puede realizar la resolución de la sobrecarga y mostrar (o navegar hasta) la sobrecarga correcta.

La sobrecarga basada en tipos también puede obstaculizar el mantenimiento del código, ya que las actualizaciones del código pueden cambiar accidentalmente qué método de sobrecarga elige el compilador. [13]

Véase también

Citas

  1. ^ "Clojure - Aprenda Clojure - Funciones". clojure.org . Consultado el 13 de junio de 2023 .
  2. ^ "Especificación del lenguaje Kotlin". kotlinlang.org .
  3. ^ Bloch 2018, p. 238-244, §Capítulo 8, Punto 52: Eliminar las advertencias no marcadas.
  4. ^ "37.6. Sobrecarga de funciones". Documentación de PostgreSQL . 2021-08-12 . Consultado el 2021-08-29 .
  5. ^ "Guía y referencia del usuario de la base de datos PL/SQL". docs.oracle.com . Consultado el 29 de agosto de 2021 .
  6. ^ "Manual de Nim". nim-lang.org .
  7. ^ "Documentos de Crystal". crystal-lang.org .
  8. ^ "Embarcadero Delphi". embarcadero.com .
  9. ^ Watt, David A.; Findlay, William (1 de mayo de 2004). Conceptos de diseño de lenguajes de programación . John Wiley & Sons, Inc., págs. 204-207. ISBN 978-0-470-85320-7.
  10. ^ Bloch 2018, p. 238-244, §Capítulo 8, ítem 52: Utilice la sobrecarga con criterio.
  11. ^ Chan, Jamie (2017). Aprenda C# en un día y apréndalo bien (edición revisada). pág. 82. ISBN 978-1518800276.
  12. ^ de Stroustrup, Bjarne . "¿Por qué la sobrecarga no funciona para las clases derivadas?".
  13. ^ Bracha, Gilad (3 de septiembre de 2009). "Sobrecarga sistémica". Sala 101.

Referencias

Enlaces externos