tipos sencillos polimorfismo poliformismo herencia ejemplos clases abstractas polymorphism return-type

polymorphism - sencillos - polimorfismo java



Tipo de retorno polimorfismo en C-like languages (5)

Debido a la conversión automática de tipos, no es obvio saber a qué función llamar cuando los tipos de devolución están cerca.

¿Por qué no vemos lenguajes similares a C que permiten que los callables tengan polimorfismo en el tipo de retorno? Pude ver cómo la inferencia de tipo adicional sería un obstáculo, pero tenemos muchos idiomas con sistemas de inferencia de tipo completo (que funcionan para diferentes niveles de "trabajo").

Editar: Por polimorfismo de retorno, me refiero a sobrecargar la firma de la función solo en el tipo de devolución. Por ejemplo, C ++ y Java solo permiten la sobrecarga en el tipo de parámetros formales, no en el tipo de devolución.


En C ++ puedes hacer esto con clases en gran medida. Por ejemplo, supongamos que tengo un tipo de datos que se convierte rutinariamente a ASCII en entrada y salida;

typedef char* pchar; class MyType { public: operator pchar() { return(ConvertToASCII()); } MyType& operator=(char* input) { ConvertFromASCII(input); return(*this); } pchar ConvertToASCII(); void ConvertFromASCII(pchar ASCII); }

Este tipo de cosas se usa a menudo en marcos C ++. Por ejemplo, eche un vistazo a la implementación de la clase MFC CString. En mi humilde opinión, es una herramienta muy útil, aunque peligrosa en ciertas circunstancias.


Me encantaría ver esta característica en algún idioma, no solo para que la función foo pueda devolver un doble o un int o una cadena, sino también para que foo pueda devolver una estructura u objetos de diferentes clases. La desambiguación de las llamadas sería bastante trivial: si la llamada es ambigua, se requiere un molde para seleccionar el tipo de retorno deseado. Ejemplo:

string s = foo(); //foo returns a string double x = foo(); //foo returns a double int i = foo(); //foo returns an integer float f = (float)(int)foo(); //call the int foo and convert to float

en adición

Animal a = fooFactory(); //fooFactory returns an Animal Plant p = fooFactory(); //foofactory returns a Plant

estas situaciones no aparecen muy a menudo, pero cuando lo hacen, la solución es a menudo bastante fea ...


Si por "polimorfismo de tipo de retorno" te refieres a sobrecarga según el tipo de valor de retorno, no estoy seguro acerca de otros idiomas, pero para C ++ esta es la respuesta (más o menos de la boca del caballo):

Los tipos de retorno de función no entran en juego en la resolución de sobrecarga simplemente porque Stroustrup (supongo que con la contribución de otros arquitectos de C ++) quería que la resolución de sobrecarga fuera ''independiente del contexto''. Consulte 7.4.1 - "Tipo de sobrecarga y retorno" del "Lenguaje de programación C ++, tercera edición".

La razón es mantener la resolución para un operador individual o llamada de función independiente del contexto.

Querían que se basara solo en cómo se llamaba la sobrecarga, no cómo se usaba el resultado (si se utilizó en absoluto). De hecho, muchas funciones se llaman sin usar el resultado o el resultado se usaría como parte de una expresión más grande. Un factor que estoy seguro entró en juego cuando decidieron esto era que si el tipo de devolución formaba parte de la resolución habría muchas llamadas a funciones sobrecargadas que tendrían que resolverse con reglas complejas o tendrían que tener el lanzamiento del compilador un error que la llamada fue ambigua.

Y, sabe Dios, la resolución de sobrecarga de C ++ es lo suficientemente compleja tal como está ...


double x = (double)foo();

Lo anterior es ambiguo si hay versiones de foo () que pueden devolver double, int, float, etc.