supports - Почему Java не предлагает перегрузку оператора?




operator<< overloading c++ (10)

Исходя из C ++ в Java, очевидный неотвеченный вопрос заключается в том, почему Java не включала перегрузку оператора?

Не является Complex a, b, c; a = b + c; Complex a, b, c; a = b + c; намного проще, чем Complex a, b, c; a = b.add(c); Complex a, b, c; a = b.add(c); ?

Есть ли известная причина для этого, допустимые аргументы в пользу недопущения перегрузки оператора? Является ли причина произвольной или потеряна во времени?


Говоря о том, что перегрузка оператора приводит к логическим ошибкам типа, который оператор не соответствует логике операций, это как ничего не говорит. Ошибка такого же типа произойдет, если имя функции не подходит для логики работы - так что же такое решение: отказаться от возможности использования функции !? Это смешной ответ: «Не подходит для логики работы», каждое имя параметра, каждый класс, функция или что-то другое может быть логически неуместным. Я думаю, что этот вариант должен быть доступен на уважаемом языке программирования, а те, которые считают, что это небезопасно, - нет, ни один из них не говорит, что вы должны его использовать. Возьмем C #. Они опустили указатели, но эй, - есть «небезопасный код» - программа, как вам нравится, на свой страх и риск.


Джеймс Гослинг сравнивал проектирование Java со следующим:

«Этот принцип заключается в перемещении, когда вы переходите из одной квартиры в другую квартиру. Интересный эксперимент заключается в том, чтобы собрать вашу квартиру и поместить все в коробки, а затем переехать в следующую квартиру, а не распаковывать что-либо, пока вам это не понадобится. вы делаете свой первый прием, и вы вытаскиваете что-то из коробки. Затем через месяц или около того вы использовали это, чтобы в значительной степени выяснить, что в вашей жизни вам действительно нужно, а затем вы берете остальную часть вещи - забыть, насколько вам это нравится или как это здорово, - и вы просто выбросите его. Удивительно, как это упрощает вашу жизнь, и вы можете использовать этот принцип во всех вопросах дизайна: не делайте ничего, потому что они «круто или просто потому, что они интересны».

Вы можете прочитать http://www.gotw.ca/publications/c_family_interview.htm

В основном перегрузка операторов отлично подходит для класса, который моделирует некую точку, валюту или комплексное число. Но после этого вы быстро запускаете примеры.

Другим фактором было злоупотребление функцией на C ++ разработчиками, перегружающими операторы типа «&&», «||», операторы трансляции и, конечно, «новые». Сложность, возникающая в результате сочетания этого с передачей по значению и исключениям, хорошо освещена в Исключительной книге на С ++ .


Некоторые говорят, что перегрузка операторов на Java приведет к обфускации.Неужели эти люди когда-либо останавливались, чтобы посмотреть на какой-то Java-код, делающий некоторые основные математические модели, например, увеличение финансовой стоимости на процент, используя BigDecimal? ... многословие такого упражнения становится его собственной демонстрацией обфускации. По иронии судьбы, добавление перегрузки оператора на Java позволило бы нам создать собственный валютный класс, который сделал бы такой математический код изящным и простым (менее обманутым).


Ну, вы действительно можете стрелять в ногу с перегрузкой оператора. Похоже, что с указателями люди делают с ними глупые ошибки, и поэтому было решено снять ножницы.

По крайней мере, я думаю, в этом причина. Я все равно на твоей стороне. :)


Проверьте Boost.Units: текст ссылки

Он обеспечивает нулевой объемный анализ размеров посредством перегрузки оператора. Насколько яснее это можно получить?

quantity<force>     F = 2.0*newton;
quantity<length>    dx = 2.0*meter;
quantity<energy>    E = F * dx;
std::cout << "Energy = " << E << endl;

фактически выводит «Energy = 4 J», что является правильным.


Разработчики Java решили, что перегрузка оператора была больше проблем, чем того стоила. Просто как тот.

В языке, где каждая объектная переменная на самом деле является ссылкой, перегрузка оператора приобретает дополнительную опасность для нелогичности - по крайней мере, для программиста на C ++. Сравните ситуацию с перегрузкой оператора C # 's и Object.Equals и Object.ReferenceEquals (или как бы там ни называлось).


Я думаю, что это может быть сознательный выбор дизайна, чтобы заставить разработчиков создавать функции, чьи имена четко сообщают о своих намерениях. В C ++ разработчики перегружали бы операторов функциональностью, которая часто не имела бы отношения к общепринятому характеру данного оператора, что почти не могло бы определить, что делает код, не глядя на определение оператора.


Groovy имеет перегрузку оператора и работает в JVM. Если вы не против удара производительности (который становится меньше каждый день). Он основан на именах методов. например, «+» вызывает метод «плюс (аргумент)».


Иногда было бы неплохо иметь перегрузку оператора, классы друзей и множественное наследование.

Однако я все еще думаю, что это было хорошее решение. Если бы у Java была бы перегрузка оператора, мы никогда не были бы уверены в значениях оператора, не просматривая исходный код. В настоящее время это не обязательно. И я думаю, что ваш пример использования методов вместо перегрузки оператора также вполне читабельен. Если вы хотите сделать что-то более понятным, вы всегда можете добавить комментарий выше волосатых заявлений.

// a = b + c
Complex a, b, c; a = b.add(c);

Это не повод для отказа, но практический:

Люди не всегда используют это ответственно. Посмотрите на этот пример из библиотеки Python scapy:

>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>

Вот объяснение:

Оператор / использовался как оператор композиции между двумя слоями. При этом нижний уровень может иметь одно или несколько полей по умолчанию, перегруженных в соответствии с верхним уровнем. (Вы все равно можете указать желаемое значение). Строка может использоваться как необработанный слой.







operator-overloading