Превращение абстрактного класса без полей в интерфейс (Java, правило сонара s1610) - PullRequest
2 голосов
/ 06 марта 2020

Я ссылаюсь на это правило :

С помощью функции "метода по умолчанию" Java 8 любой абстрактный класс без прямого или унаследованного поля должен быть преобразован в интерфейс.

  • В моем восприятии по умолчанию + частные методы в интерфейсах Java8 + - это чистый компромисс Разработчики JDK взялись за решение стоящей перед ними дилеммы: им пришлось вводить новые методы (например, интерфейс Map) без разрушения старого кода, который использовал эти интерфейсы (обратная совместимость).
  • На практике разработчики JDK ввели наследование реализации в местах, где наследование интерфейса существовали, поэтому потенциально они увеличивали связность и хрупкость нашего существующего и будущего кода.
  • В моем представлении введено наследование реализации теперь уменьшает классный характер интерфейсов - множественное наследование .
  • Я понимаю, почему "абстрактные классы без полей" упоминается в статье нар правило. Этим авторы правила уменьшают хрупкость (но не исключают факт наследования реализации). Сравните с проблемами Scala черт, которые разрешают поля (новые интерфейсы Java все больше и больше похожи на черты Scala) - Scala дизайнеры lang пытались решить эти проблемы с такими вещами, как линеаризация черт, ленивые значения, et c.
  • Я избегаю таких аргументов, как «это в JDK, поэтому это шаблон», давайте поговорим здесь больше на концептуальном уровне.
  • Вопрос : Может кто-нибудь объяснить мне, почему Сонар продвигает это, ИМХО, ошибочное правило? Что мы получаем по такому правилу? Какую выгоду / вариант использования я здесь упускаю?

Спасибо.

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Я не обязательно согласен с правилом, но я вижу, откуда оно.

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

Однако это запрещено Java ( необходимо предоставить собственную реализацию этого метода), поэтому в этом нет никакой опасности.

В целом, интерфейсы более универсальны, чем классы, поэтому имеет смысл использовать их, если это возможно.

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

0 голосов
/ 06 марта 2020

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

...