En algunos lenguajes de programación , la sobrecarga de funciones o la sobrecarga de métodos es la capacidad de crear múltiples funciones del mismo nombre con diferentes implementaciones. Las llamadas a una función sobrecargada ejecutarán una implementación específica de esa función adecuada al contexto de la llamada, lo que permitirá 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 este último, se debe pasar un objeto como parámetro , mientras que el primero 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 resultaría en un error de llamada ambiguo , ya que el compilador no sabría cuál de los dos métodos usar.
Otro ejemplo es una Print(object o)
función que ejecuta diferentes acciones en función de si está imprimiendo 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 sobrecargados para todos los objetos de nuestro programa "imprimir", que nunca tiene que preocuparse por el tipo del objeto, y la correcta función de llamada de nuevo, la llamada es siempre: Print(something)
.
Idiomas que admiten la sobrecarga
Los idiomas que admiten la sobrecarga de funciones incluyen, entre otros, los siguientes:
Reglas en la sobrecarga de funciones
- Se utiliza el mismo nombre de función para más de una definición de función
- Las funciones deben diferir por la aridad o los tipos de sus parámetros.
Es una clasificación de polimorfismo estático en la que una llamada a función se resuelve usando algún algoritmo de "mejor coincidencia", donde la función particular a llamar se resuelve encontrando la mejor coincidencia de los tipos de parámetros formales con los tipos de parámetros reales. Los detalles de este algoritmo varían de un idioma a otro.
La sobrecarga de funciones generalmente se asocia con lenguajes de programación de tipo estático que imponen la verificación de tipos en las llamadas a funciones . Una función sobrecargada es en realidad solo un conjunto de funciones diferentes que tienen el mismo nombre. La determinación de qué función usar para una llamada en particular se resuelve en tiempo de compilación .
En Java , la sobrecarga de funciones también se conoce como polimorfismo en tiempo de compilación y polimorfismo estático.
La sobrecarga de funciones no debe confundirse con 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 estáticamente.
Ejemplo: sobrecarga de funciones en C ++
#include int Volume ( 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 < doble > ( 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 la selección basada en el número y tipo de parámetros reales diferentes.
Sobrecarga del constructor
Los constructores , que se utilizan 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 idiomas 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. Por ejemplo, un constructor predeterminado para un objeto de factura de restaurante escrito en C ++ podría establecer la propina en 15%:
Bill () : propina ( 0.15 ), // porcentaje total ( 0.0 ) { }
El inconveniente 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:
Bill café ; cafe . propina = 0,10 ; cafe . total = 4,00 ;
Al sobrecargar el constructor, se podría pasar la punta 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 en el constructor original que usamos antes. Cuál se usa 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 establecer los miembros de datos en un solo paso. A continuación se muestra la creación y configuración de los valores:
Bill café ( 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 la sobrecarga del constructor puede ser la aplicación de miembros de datos obligatorios. En este caso, el constructor predeterminado se declara privado o protegido (o preferiblemente eliminado desde C ++ 11 ) para que sea inaccesible desde el exterior. Para la factura anterior, el total podría ser el único parámetro del constructor, ya que una factura no tiene un valor predeterminado sensible para el total, mientras que la propina tiene un valor predeterminado de 0.15.
Complicaciones
Dos problemas interactúan y complican la sobrecarga de funciones: 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 ambas, la declaración interna y la declaración 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 en los ámbitos". [2] Como resultado, para obtener un conjunto de sobrecarga con funciones declaradas en diferentes ámbitos, es necesario importar explícitamente las funciones del ámbito exterior al ámbito interior, con la using
palabra clave.
La conversión de tipo 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 tipo, la resolución depende de qué tipo de conversión se elija.
Estos pueden combinarse de maneras confusas: una coincidencia inexacta declarada en un alcance interno puede enmascarar una coincidencia exacta declarada en un alcance externo, por ejemplo. [2]
Por ejemplo, para tener una clase derivada con una función sobrecargada que toma un double
o un int
, usando la función que toma un int
de la clase base, en C ++, se escribiría:
clase B { público : void F ( int i ); };clase D : público B { público : usando B :: F ; vacío F ( doble d ); };
No incluir los using
resultados en un int
parámetro pasado a F
en la clase derivada que 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 using
da como resultado una sobrecarga en la clase derivada y, por lo tanto, hace coincidir la función en la clase base.
Advertencias
Si un método está diseñado con un número excesivo de sobrecargas, puede ser difícil para los desarrolladores discernir qué sobrecarga se está llamando simplemente leyendo el código. Esto es particularmente cierto si algunos de los parámetros sobrecargados son de tipos heredados de otros posibles parámetros (por ejemplo, "objeto"). Un IDE puede realizar la resolución de sobrecarga y mostrar (o navegar hasta) la sobrecarga correcta.
La sobrecarga basada en tipos también puede dificultar el mantenimiento del código, donde las actualizaciones de código pueden cambiar accidentalmente qué método de sobrecarga elige el compilador. [3]
Ver también
Referencias
- ^ "Especificación del lenguaje Kotlin" . kotlinlang.org .
- ^ a b Stroustrup, Bjarne . "¿Por qué la sobrecarga no funciona para las clases derivadas?" .
- ^ Bracha, Gilad (3 de septiembre de 2009). "Sobrecarga sistémica" . Sala 101.
enlaces externos
- Meyer, Bertrand (octubre de 2001). "Sobrecarga vs Tecnología de Objetos" (pdf) . Columna Eiffel. Revista de programación orientada a objetos . 101 Comunicaciones LLC. 14 (4): 3–7 . Consultado el 27 de agosto de 2020 .