Supongamos que estoy trabajando en un sistema existente, razonablemente grande. Tengo un objeto, myObject
de clase MyClass
(por el bien del ejemplo, supongamos que estoy trabajando en Java). myObject
es una composición que contiene Collection
, digamos, List
ay otros objetos que (creo) son irrelevantes. Contiene métodos delegados que solo sirven para invocar los métodos de los List
que está compuesto, con el fin de asegurarse de List
que no estén expuestos (lo siento si me equivoco con mi terminología).
Digamos que este List
es un List<String>
pero, por alguna razón, el método de acceso principal es un método de máscara para la clase SomeOtherClass
. Si quisiera insertar un nuevo par de valores en mi List
, entonces tendría un objeto SomeOtherClass
llamado someObject
. Llamaría myObject.insert(someObject)
y dentro del insert
método habría algo de magia que recuperaría un String
para poner en el List<String>
.
Supongamos ahora que solo tengo un String
valor y ningún SomeOtherClass
objeto para insertar. Suponiendo que no puedo modificar el insert
método porque rompería todo en este sistema. Entonces, ¿debería sobrecargar el insert
método? ¿O debería crear un nuevo objeto SomeOtherClass
cada vez que quiera llamar insert
?
Supongo que si lo sobrecargara, se vería así ...
public void insert(String s) {
...
}
public void insert(SomeOtherObject obj) {
this.insert(obj.magicStringMethod());
}
(Este ejemplo es un rompecabezas artificial basado en una situación similar (un poco más compleja) con respecto a la sobrecarga que encontré ayer. Lo ampliaré si hay algo que no estaba claro)
¿Sería este un lugar apropiado para sobrecargar un método? Si no, ¿cuándo debería sobrecargar un método?
magicStringMethod()
en mi ejemplo, en mi caso, obtendría unaString
representación deSomeOtherObject
cuál era un objeto de dominio.Respuestas:
Se sobrecarga cuando desea admitir diferentes tipos:
o para admitir una interfaz progresiva utilizando diferentes listas de parámetros:
Incluso puede volverse un poco loco y admitir ambos tipos diferentes Y una interfaz progresiva, pero debe tener en cuenta que debe evitar crear variaciones en el comportamiento entre los métodos sobrecargados. Cada método sobrecargado debería ser funcionalmente el mismo que los demás en un grupo sobrecargado, de lo contrario no estará claro cómo, cuándo o por qué se varía el comportamiento. Si desea que dos funciones hagan algo completamente diferente, debe nombrarlas en consecuencia.
fuente
Yo diría que la sobrecarga es apropiada cuando ambos métodos son semánticamente equivalentes. Para robar de los ejemplos de dukeofgaming:
Estos están sobrecargados adecuadamente:
Estos no son:
Ese es un ejemplo extremo (si no lo captó, el último método en realidad resta en lugar de sumar), pero la idea es que si tiene varios métodos en una clase con el mismo nombre, se comporten de manera consistente.
En su ejemplo, a partir de la información dada, parecen ser equivalentes (ya que uno llama al otro) y creo que es razonable sobrecargarlos. No está de más preguntar a alguien de mayor rango en su equipo si no está seguro de si el método debe agregarse, pero si lo agrega, usaría el mismo nombre (es decir, lo sobrecargaría).
fuente
Esencialmente para que los parámetros del método dicten cómo se comportará el método.
Un ejemplo rápido sería:
Si pasa la suma del método (a, b) un par de enteros, sabe que debe llamar a la primera implementación, ya que la llamada al método coincide con la firma del método (es decir, la suma doble (doble, doble) no funcionará si proporciona método de suma dos enteros).
La firma de la llamada debe coincidir con las implementaciones disponibles, por lo que intentar llamar a sum (string, string) no funcionará a menos que tenga esto:
tl; dr: para que la clase maneje el método correcto de acuerdo con los parámetros que le dé a un método con el mismo nombre.
Al heredar, se llama anulación
Un buen ejemplo de este otro escenario es cuando desea alterar el comportamiento predeterminado de una clase al heredarlo, y particularmente cuando tiene algo similar al patrón de método de plantilla , donde tiene cada paso de algún algoritmo implementado en un método.
Imagina que tienes
class Robot
un método llamadofireAtTarget(Target target)
... que se llamafireWeaponA(target); fireWeaponB(target); fireWeaponC(target);
uno después del otro. También desea tener una colección llamada robot_army a la que solo puede agregar objetos de la clase Robot. El robot dispara ametralladoras por defecto en susfireWeaponX()
métodos.Entonces usted quiere tener
class LazorRobot
yclass MissileRobot
, de implantación de los robot de nuevo ?, no, sólo hay LazorRobot y hereda MissileRobot robot, y la sobrecarga de cadafireWeaponX()
método para uso lazorz o misiles y tendrá el mismo comportamiento con diferentes armas, sin tener que reimplementar El resto de los métodos.tl; dr: para que el comportamiento del método dependa de la clase sin romper la interfaz (robot_army solo acepta Robot, pero acepta por extensión cualquier clase que herede Robot).
fuente
when inheriting
, probablemente no sea necesaria la sección completa . :)sum(String, String)
ysum(int, int)
?