Articulo de referencia

Sobrecarga de funciones

En algunos lenguajes de programación , la sobrecarga de funciones o de métodos consiste en la capacidad de crear múltiples funciones con el mismo nombre pero con implementacione...

En algunos lenguajes de programación , la sobrecarga de funciones o de métodos consiste en la capacidad de crear múltiples funciones con el mismo nombre pero con implementaciones diferentes. Las llamadas a una función sobrecargada ejecutarán una implementación específica de dicha función, adecuada al contexto de la llamada, lo que permite que una misma llamada realice distintas tareas según el contexto.

Definición básica

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

Otro ejemplo es una función Print(object o) que ejecuta diferentes acciones según si imprime texto o fotos. Las dos funciones diferentes se pueden sobrecargar como Print(text_object T); Print(image_object P) . Si escribimos las funciones print 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 es siempre: Print(algo) .

Idiomas que admiten sobrecarga

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

Entre los lenguajes que no admiten la sobrecarga de funciones se incluyen C , Python , Rust y Zig .

Reglas en la sobrecarga de funciones

  • El mismo nombre de función se utiliza para más de una definición de función en un módulo, clase o espacio de nombres en particular.
  • Las funciones deben tener firmas de tipo diferentes , es decir, difieren en el número o los tipos de sus parámetros formales (como en C++) o adicionalmente en su tipo de retorno (como en Ada). [ 9 ]

La sobrecarga de funciones se asocia generalmente con lenguajes de programación de tipado estático que imponen la verificación de tipos en las llamadas a funciones . Una función sobrecargada es un conjunto de diferentes funciones que se pueden invocar con el mismo nombre. Para cada llamada, el compilador determina qué función sobrecargada usar y lo resuelve en tiempo de compilación . Esto se aplica a lenguajes de programación como Java. [ 10 ]

La sobrecarga de funciones difiere 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++

importar std ;// Volumen de un cubo. int volumen ( int s ) { return s * s * s ; }// Volumen de un cilindro. double volume ( double r , int h ) { return std :: numbers :: pi * r * r * static_cast < double > ( h ); }// Volumen de un cuboide (prisma rectangular). long volume ( long l , int b , int h ) { return l * b * h ; }int main () { std :: println ( "{}" , volumen ( 10 )); std :: println ( "{}" , volumen ( 2.5 , 8 )); std :: println ( "{}" , volumen ( 100l , 75 , 15 )); }

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

Sobrecarga de constructores

Los constructores , utilizados para crear instancias de un objeto, también pueden sobrecargarse en algunos lenguajes de programación orientados a objetos . Dado 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 necesiten varios constructores, deben implementarse como funciones sobrecargadas. En C++ , los constructores predeterminados no toman parámetros, instanciando los miembros del objeto con sus valores predeterminados apropiados, "que normalmente son cero para campos numéricos y una 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 }, total { 0.0 } {}

La desventaja es que se requieren dos pasos para cambiar el valor del objeto Bill creado. A continuación se muestra cómo crear y cambiar los valores dentro del programa principal:

Factura del café ; café.propina = 0.10 ; café.total = 4.00 ;

Al sobrecargar el constructor, se pueden pasar la propina y el total como parámetros al crear el objeto. Esto muestra el constructor sobrecargado con dos parámetros. Este constructor sobrecargado se encuentra en la clase, al igual que el constructor original que usamos anteriormente. Cuál se utiliza depende del número de parámetros proporcionados al crear 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 establecer los miembros de datos en un solo paso. A continuación se muestra la creación y la configuración de los valores:

Bill cafe ( 0.10 , 4.00 );

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

Otra razón para sobrecargar constructores puede ser para garantizar la obligatoriedad de los miembros de datos. En este caso, el constructor predeterminado se declara privado o protegido (o preferiblemente se elimina desde C++11 ) para que sea inaccesible desde fuera. Para la factura anterior, el total podría ser el único parámetro del constructor , ya que una factura no tiene un valor predeterminado adecuado para el 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 ámbito ) y la conversión implícita de tipos .

Si una función se declara en un ámbito y luego otra función con el mismo nombre se declara en un ámbito interno, hay dos comportamientos de sobrecarga posibles: 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 declaración externa solo si la firma coincide. El primero 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 implícita de tipos complica la sobrecarga de funciones porque, si los tipos de los 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 qué conversión de tipos se elija.

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

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

clase Base { público : void fn ( int i ); };clase Derivada : pública Base { pública : usando Base :: fn ; void fn ( double d ); };

No incluir los usingresultados en un intparámetro pasado a fnla clase derivada que se convierte a un double y coincide con la función en la clase derivada, en lugar de en la clase base; Incluir usinglos resultados en una sobrecarga en la clase derivada y, por lo tanto, coincidir con la función en la clase base.

Advertencias

Si un método tiene un número excesivo de sobrecargas, puede resultar difícil para los desarrolladores discernir qué sobrecarga se está llamando simplemente leyendo el código. Esto es especialmente cierto si algunos de los parámetros sobrecargados son de tipos que heredan de otros parámetros posibles (por ejemplo, "object"). Un IDE puede resolver la sobrecarga y mostrar (o navegar a) la sobrecarga correcta.

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

Véase también

Citas

  1. "Clojure - Aprende Clojure - Funciones" . clojure.org . Consultado el 13 de junio de 2023 .
  2. "Documentación de Crystal" . crystal-lang.org .
  3. "Embarcadero Delphi" . embarcadero.com .
  4. "Especificación del lenguaje Kotlin" . kotlinlang.org .
  5. Bloch 2018 , págs. 238-244, §Capítulo 8 Punto 52: Eliminar las advertencias no verificadas.
  6. "Manual de Nim" . nim-lang.org .
  7. "37.6. Sobrecarga de funciones" . Documentación de PostgreSQL . 12 de agosto de 2021. Consultado el 29 de agosto de 2021 .
  8. "Guía y referencia del usuario de PL/SQL para bases de datos" . docs.oracle.com . Consultado el 29 de agosto de 2021 .
  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ágs. 238-244, §Capítulo 8 Punto 52: Utilice la sobrecarga con criterio.
  11. Chan, Jamie (2017). Aprende C# en un día y apréndelo bien ( Edición revisada). pág. 82. ISBN   978-1518800276.
  12. 1 2 Stroustrup, Bjarne . "¿Por qué no funciona la sobrecarga para las clases derivadas?" .
  13. Bracha, Gilad (3 de septiembre de 2009). "Sobrecarga sistémica" . Habitación 101.

Referencias

  • Bloch, Joshua (2018). «Java eficaz: Guía del lenguaje de programación» (tercera  ed.). Addison-Wesley. ISBN 978-0134685991.
  • Meyer, Bertrand (octubre de 2001). "Sobrecarga vs. Tecnología de objetos" (PDF) . Columna Eiffel. Journal of Object-Oriented Programming . 14 (4). 101 Communications LLC: 3–7 . Recuperado el 27 de agosto de 2020 .
Obtenido de " https://en.wikipedia.org/w/index.php?title=Function_overloading&oldid=1344668986 "