/мочь интерфейсы замены абстрактных классов? [дубликат]

Этот вопрос уже имеет ответ здесь:

В Java можно создать абстрактный класс, который содержит только абстрактные методы. С другой стороны, можно создать интерфейс, который объявляет те же методы. При этом можно ли использовать абстрактные классы вместо интерфейсов?

21
задан Makoto 1 January 2016 в 09:15
поделиться

8 ответов

Не всегда:

  • класс может продлить только один класс
  • класс может реализовать более одного интерфейса

Документы Составьте более подробное сравнение:

Абстрактные классы против интерфейсов

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

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

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

34
ответ дан 29 November 2019 в 06:21
поделиться

Для этого можно использовать простой двойник.

double amount = 990.49;
double rounded = ((double) (long) (amount * 20 + 0.5)) / 20;

EDIT: для отрицательных чисел необходимо вычесть 0,5

-121--2229769-

Другая идея состоит в том, чтобы использовать Apache Commons Lang для написания следующего кода:

StringUtils.join(myList);

Интерес заключается в том, что вы также можете предоставить разделитель, например:

StringUtils.join(myList, " ; ");
-121--3030969-

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

  1. Интерфейсы определяют поведение.
  2. Абстрактные классы определяют реализацию.

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

13
ответ дан 29 November 2019 в 06:21
поделиться

Абстрактные классы и интерфейсы дополняют.

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

Тогда у вас будут абстрактные классы, частично реализующие эти интерфейсы, чтобы

  • поделиться некоторым общим кодом, который может использоваться во всех (или почти всех) реализациях для интерфейса, что очевидно
  • , обеспечивающее поведение по умолчанию, которое Может быть переопределен в «реальных» реализациях, например, метод TOSTRING () с использованием методов интерфейсов для создания текстового представления осуществления
  • Сохранение совместимости реализации после изменений интерфейса, например, когда вы добавляете новый метод в вашем интерфейсе, вы Также добавьте реализацию по умолчанию в абстрактном классе, чтобы реализованы (например, изготовленные пользователем пользователем), расширяя абстрактный класс, все еще работают без изменений
4
ответ дан 29 November 2019 в 06:21
поделиться

Чтобы ответить на ваш вопрос, да, вы могли бы использовать абстрактный класс (не предоставляя никакой реализации) вместо интерфейса, но я бы учёл эту плохую практику:

  • Вы использовали свой "один выстрел" при наследовании (не получая никакой пользы).
  • Вы не можете наследовать от нескольких абстрактных классов, но можете реализовать несколько интерфейсов.

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

5
ответ дан 29 November 2019 в 06:21
поделиться

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

[
1
ответ дан 29 November 2019 в 06:21
поделиться

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

2
ответ дан 29 November 2019 в 06:21
поделиться
  • Класс в java может наследовать от множества интерфейсов, но только от одного абстрактного класса.

  • Интерфейс не может определить код, в абстрактном классе можно определить код (т.е. поведение методов по умолчанию)

4
ответ дан 29 November 2019 в 06:21
поделиться

Здесь не хватает одного пункта в ответах - это идея , кто будет реализовывать интерфейс.

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

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

В проекте Apache Cactus есть хорошее обсуждение о том, как решить эти задачи.

11
ответ дан 29 November 2019 в 06:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: