Jump to content


Photo

Concepto: Sobrecarga de métodos (Overload)


  • Please log in to reply
2 replies to this topic

#1 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6295 posts
  • LocationArgentina

Posted 18 December 2008 - 01:50 PM

Hola,
Ahora voy a tocar otro concepto: la sobrecarga de métodos, o comunmente conocido como overload (inglés).

Concepto
¿Se han preguntado si es posible tener dos o más funciones o procedimientos de igual nombre que hagan algo similar?
La respuesta es SI. Se puede, y todo gracias a la sobrecarga de métodos.

La sobrecarga nos permite emplear dos o más métodos con el mismo nombre. Lo que los hace diferente a cada uno es el/los tipo/s y/o la cantida de parámetros.

El requisito para que esto funcione es que se incluya la cláusula overload al final de la declaración de los mismos.

Caso Práctico
Deseamos calcular la suma de números, por un lado reales y por el otro de enteros. No se nos ocurren nombres originales para cada una por tanto los sobrecargamos:


delphi
  1. type
  2.   Toperacion = class(TObject)
  3.   public
  4.     function Suma(A,B: integer): integer; overload;
  5.     function Suma(A,B: double): double; overload;
  6.   end;
  7.  
  8. implementation
  9.  
  10. function TOperacion.Suma(A,B: integer): integer;
  11. begin
  12.   result := A + B;
  13. end;
  14.  
  15. function TOperacion.Suma(A,B: double): double;
  16. begin
  17.   result := A + B;
  18. end;



Como se vé, El nombre es el mismo, tienen igual cantidad de parámetros pero sus tipos son diferentes.
Esta técnica es incluso aplicable fuera de las clases. Es decir que podemos declarar funciones y procedimientos "sueltos" en una unit y aplicar la sobrecarga.

¿Cómo es que funciona?
En tiempo de ejecución, el compilador interpreta los tipos y cantidades de parámetros que posee y aplica el algoritmo adecuado. En tiempo de diseño no se aplica esta técnica.

¿Cúando es conveniente esta técnica?
Puede ser utilizada, y se la recomienda, cuando se necesita aplicar diversos algoritmos que en definitiva necesita dar soporte a una misma funcionalidad.

Vamos a dar un ejemplo un tantito más complejo, pero que ilustra enormemente este técnica.
Por ejemplo, en los casos de TMamifero, TPerro, de los manuales anteriores, podríanos sernos útil un método Cazar(). Pero como somos un tanto "exquisitos" podemos interpretar a Cazar() en los siguientes contextos:
1. Caza una presa en particular.
2. Escojer una presa, dada una posición determinada del mapa.
3. Que escoja una presa al azar.

Entonces necesitamos sobrecargar el método tres veces:


delphi
  1. TMamifero = class(TObject)
  2.   public
  3.     // Otros métodos interesantes
  4.     function MatarPresa(Presa: TMamifero): boolean;
  5.     function PresaEnMapa(X,Y: integer; var Presa: TMamifero): boolean;
  6.  
  7.     // métodos de caza
  8.     function Cazar(Presa: TMamifero): boolean; overload;
  9.     function Cazar(X,Y: integer): boolean; overload;
  10.     function Cazar: boolean; overload;
  11.   end;



Las implementaciones de cada uno podrían ser como las siguientes:



delphi
  1. // cazar a una presa específica
  2. function TMamifero.Cazar(Presa: TMamifero): boolean;
  3. var Puede: boolean;
  4. begin
  5.   result := MatarPresa(Presa);
  6. end;
  7.  
  8. // cazar a la presa ubicada en X,Y
  9. function TMamifero.Cazar(X, Y: integer): boolean;
  10. var Puede: boolean;
  11.     Presa: TMamifero;
  12. begin
  13.   Puede := PresaEnMapa(X,Y,Presa);
  14.   if Puede
  15.      then result := MatarPresa(Presa)
  16.      else result := False;
  17. end;
  18.  
  19. // cazar al azar
  20. function TMamifero.Cazar: boolean;
  21. var X,Y, intentos: integer;
  22.     Presa: TMamifero;
  23.     Puede: boolean;
  24. begin
  25.   Puede := False;
  26.   intentos := 0;
  27.   // repetir busqueda al azar hasta encontrar una o se nos terminen
  28.   // los intentos.
  29.   repeat
  30.     Puede := PresaEnMapa(Random(200),Random(200),Presa);
  31.     inc(intentos);
  32.   until (Puede = True) OR (intentos > 50);
  33.  
  34.   if Puede
  35.      then result := MatarPresa(Presa)
  36.      else result := False;
  37. end;



Como puede verse, en todos los Cazar() se llama a un método en común: MatarPresa(). La particularidad que nos ofrece la sobrecarga es de aplicar MatarPresa() en diferentes contextos. De este modo nos evitamos estar inventando nombres rebuscados para cada método: CazarAPresa, CazarEnMapa, CazarAlAzar.

La implementación de MatarPresa puede encargarse de verificar algunas cuestiones técnicas. Por ejemplo:
1. Determinar si la presa es "fácil".
2. Ver si el parámetro Presa es válido (un objeto válido, creado: existe en memoria).
3. Etc

PresaEnMapa, lleva otro algoritmo y su función es la de comprobar de si en la posición X,Y hay una presa. Si la hay, queda en el parámetro Presa la referencia a dicha Presa.

Saludos,
  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6295 posts
  • LocationArgentina

Posted 19 December 2008 - 08:58 AM

Para completar la idea, unos ejemplos de como se lo puede utilizar.



delphi
  1. var Perro, Gato: TMamifero;
  2. begin
  3.   // Creamos los objetos
  4.   Perro := TPerro.Create; // según polimorfismo
  5.   Gato := TGato.Create;  // según polimorfismo
  6.   ....
  7.  
  8.   Perro.Cazar(Gato);      // cazará al gato
  9.   Perro.Cazar(50,100);    // cazará en la posición (50,100) del mapa
  10.   Perro.Cazar;              // cazará en alguna posición al azar
  11.   ...
  12.   // Liberamos los objetos
  13.   Gato.Free;
  14.   Perro.Free;
  15. end;



Saludos,
  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7419 posts
  • LocationRepública Dominicana

Posted 19 December 2008 - 09:03 AM

Otro aporte de excelentissima calidad amigo, Muchas Gracias (y) :)

Saludos.
  • 0




IP.Board spam blocked by CleanTalk.