6

В настоящее время я читаю «Эффективная Java» Джошуа Блоха и пункт 17 «Дизайн и документ для наследования или запрет». Автор предлагает запретить наследование по умолчанию.Может ли удаление окончательного из определения класса нарушить обратную совместимость?

Можно ли объявить классы окончательными по умолчанию, а в более позднем выпуске удалить ключевое слово final, если есть необходимость расширить класс? Будет ли он нарушать обратную совместимость с кодом, который был скомпилирован с предыдущей версией?

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

+0

Это зависит от того, сколько у вас живого, дыхательного API. Если вы постоянно вносите изменения и выпускаете, не так уж плохо ждать неделю, чтобы получить возможность наследовать. Если, с другой стороны, Java по умолчанию применил свои базовые классы JDK, это заставит программистов до слез ждать 5 лет для «исправления». –

+0

@ Kirk Woll, если потребуется 5 лет, чтобы перейти от финала к нефиналу, сколько времени потребуется, чтобы перейти от нефинального к финалу? – emory

ответ

10

Он не разбивает ни двоичную, ни исходную совместимость. Это одна из причин, по которой неплохо сделать классы окончательными; это всегда хорошо, чтобы изменить свое мнение об этом.

The Java Language Specification, §13.4.2, имеет следующие сказать о бинарной совместимости:

Изменение класса, который был объявлен final больше не объявляться final не нарушает совместимость с уже существующими двоичными файлами.

Я полагаю, вы все еще мог составить истолковываться пример, когда он на самом деле может привести к поломке программы; например, байт-код, генерирующий класс, наследующий класс предположительно final, а затем загружающий этот сгенерированный класс и полагающийся на получение VerifyError.

2

Мои мысли по этому поводу:

Снимаем final по классу не вызовет немедленные проблемы. Но учтите следующее:

Был последний класс под названием AdamsFactory, который вы переходите в нефинал. Через два месяца новый программист по имени Дилберт присоединяется к вашей команде.
Он подклассифицирует ваш используемый для конечного класса класс в ScottFactory, но нарушает принцип замещения Лискова.

Затем у него есть класс ComicStripPrinter, который использует ScottFactory вместо AdamsFactory. Что-то обязательно сломается.

Что возвращает нас к тому, что говорит Джошуа Блох:

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

Надеюсь, что я сказал, что это не большой груз.


EDIT:

Пойдите в preface of Java Langauge Specification и искать Джошуа Блох :)

+1

Человек, который разработал AdamsFactory, не знал, сделать ли это окончательным/нефинальным, поэтому PHB обязал его быть нефинализированным (по умолчанию). Позже Дилберт делает убедительным аргументом в пользу того, что AdamsFactory является окончательным, но к этому времени существует около одного триллиона классов, расширяющих AdamsFactory, которые нарушают принцип Лискова. Если Дилберт внесет изменения, все эти классы сломаны. Эверон ненавидит Дильберта. – emory

2

Если вы разрабатываете что-то вроде Java Standard API, что миллионы программистов будет использовать в течение многих лет, да , думаю, как Джошуа Блох. FORWARD EVOLUTION имеет решающее значение.

99% программ Java - нет. Они разработаны для внутреннего использования, влияние изменения API крошечное, как правило, весь исходный код доступен для рефакторинга.SIMPLICITY является ключевым для таких программ. Если у вас есть сложные и причудливые проекты, или вы тратите все свое время на размышления о финале или нет, вы теряете время.

Я обвиняю Джошуа в том, что он не устанавливал надлежащие отказы от своих предложений.

+2

Ну, YAGNI все в порядке и dandy, но изменение шаблона Java IDE Java, чтобы объявить все классы как «final», - это одно дело, и разумный дизайн класса всегда облегчает долговременное и среднесрочное обслуживание (часто, но не всегда , это помогает даже в краткосрочной перспективе), а переход к объявлению класса и удаление «final» - очень простая задача, если вы считаете, что вам это нужно. – gustafc

+0

, пока вы на нем, сделайте все поля и методы окончательными. – irreputable

 Смежные вопросы

  • Нет связанных вопросов^_^