Предположим, я работаю над существующей, достаточно большой системой. У меня есть объект myObject
класса MyClass
(для примера, предположим, я работаю в Java). myObject
это композиция, содержащая Collection
, скажем, а List
и другие объекты, которые (я думаю) не имеют значения. Он содержит методы делегата, которые просто служат для вызова методов, из которых List
он состоит, для того, чтобы гарантировать, что List
он не раскрыт (извините, если я неправильно понял мою терминологию).
Допустим , что это List
является , List<String>
но, по некоторым причинам, основной метод доступа является методом маски для класса SomeOtherClass
. Если бы я хотел вставить новую пару значений в свой List
, то у меня был бы объект SomeOtherClass
вызванного someObject
. Я бы позвонил, myObject.insert(someObject)
и внутри insert
метода была бы какая-то магия, которая бы извлекала и String
помещала в List<String>
.
Предположим теперь, что у меня есть только String
значение и нет SomeOtherClass
объекта для вставки. Предполагая, что я не могу изменить insert
метод, потому что он сломает все в этой системе. Тогда я должен перегрузить insert
метод? Или я должен создавать новый объект SomeOtherClass
каждый раз, когда я хочу позвонить insert
?
Я думаю, если бы я перегрузил его, это выглядело бы примерно так ...
public void insert(String s) {
...
}
public void insert(SomeOtherObject obj) {
this.insert(obj.magicStringMethod());
}
(Этот пример - надуманная головоломка, основанная на похожей (немного более сложной) ситуации с перегрузкой, с которой я столкнулся вчера. Я расширю ее, если что-то будет неясно)
Будет ли это подходящим местом для перегрузки метода? Если нет, когда я должен перегружать метод?
magicStringMethod()
в моем примере, в моем случае, получитьString
представление о том,SomeOtherObject
что был объект домена.Ответы:
Вы перегружены, когда хотите поддерживать разные типы:
или для поддержки прогрессивного интерфейса с использованием разных списков параметров:
Вы можете даже немного сойти с ума и поддерживать оба типа и прогрессивный интерфейс, но вы должны помнить, что вам нужно избегать создания изменений в поведении между перегруженными методами. Каждый перегруженный метод должен быть функционально таким же, как и другие в перегруженной группе, иначе будет непонятно, как, когда и почему меняется поведение. Если вы хотите, чтобы две функции делали что-то совершенно другое, вам следует назвать их соответственно.
источник
Я бы сказал, что перегрузка уместна, когда оба метода семантически эквивалентны. Чтобы украсть из примеров Dukeofgaming:
Они перегружены соответственно:
Это не:
Это крайний пример (если вы его не уловили, последний метод фактически вычитает, а не добавляет), но идея в том, что если у вас есть несколько методов в классе с одинаковым именем, они должны вести себя согласованно.
В вашем примере, исходя из представленной информации, они кажутся эквивалентными (поскольку один вызывает другой), и я думаю, что было бы разумно перегрузить их. Это не помешает спросить кого-то более старшего в вашей команде, если вы не уверены, стоит ли добавлять метод, но если вы добавите его, я буду использовать то же имя (то есть перегрузить его).
источник
По существу, чтобы параметры метода диктовали, как метод будет вести себя.
Быстрый пример будет:
Если вы передадите методу sum (a, b) пару целых чисел, он знает, что он должен вызвать первую реализацию, поскольку вызов метода совпадает с сигнатурой метода (т. Е. Double sum (double, double) не будет работать, если вы дадите метод суммы двух целых чисел).
Сигнатура вызова должна соответствовать доступным реализациям, поэтому попытка вызова sum (строка, строка) не будет работать, если у вас нет этого:
tl; dr: чтобы класс обрабатывал правильный метод в соответствии с параметрами, которые вы даете методу с тем же именем.
При наследовании это называется переопределением
Хороший пример этого другого сценария - это когда вы хотите изменить поведение класса по умолчанию, унаследовав его, и особенно когда у вас есть что-то похожее на шаблон шаблонного метода , где у вас есть каждый шаг некоторого алгоритма, реализованного в методе.
Представьте, что у вас есть
class Robot
и называется методfireAtTarget(Target target)
... который вызываетfireWeaponA(target); fireWeaponB(target); fireWeaponC(target);
один за другим. Вы также хотите иметь коллекцию с именем robot_army, в которую вы можете добавлять только объекты класса Robot. Робот стреляет из пулеметов по умолчанию в своихfireWeaponX()
методах.Тогда вы хотите иметь,
class LazorRobot
иclass MissileRobot
вы внедряете Robot заново? Нет, просто LazorRobot и MissileRobot наследуют Robot и перегружают каждыйfireWeaponX()
метод, чтобы использовать lazorz или ракеты, и у вас будет одинаковое поведение с различным оружием, без необходимости переопределения остальные методы.tl; dr: чтобы поведение метода зависело от класса без нарушения интерфейса (robot_army принимает только Robot, но по расширению принимает любые классы, которые наследуют Robot).
источник
when inheriting
раздел, вероятно, не нужен. :)sum(String, String)
иsum(int, int)
?