Do/can абстрактные классы заменяют интерфейсы?

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

Ответ 1

Не всегда:

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

Sun docs сделать более подробное сравнение:

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Проект Apact Cactus имеет хорошее обсуждение на как решить эти обязательства.

Ответ 4

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

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

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

Ответ 5

  • Класс в java может наследовать от нескольких интерфейсов, но только из одного абстрактного класса.

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

Ответ 6

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

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

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

  • поделиться некоторым распространенным кодом, который может использоваться во всех (или почти всех) реализациях для интерфейса, что очевидно
  • предоставлять поведение по умолчанию, которое может быть переопределено в "реальных" реализациях, например, метод toString(), используя методы интерфейсов для создания текстового представления реализации
  • сохранить совместимость реализаций после изменений интерфейса, например, когда вы добавляете новый метод в свой интерфейс, вы также добавляете реализацию по умолчанию в абстрактном классе, чтобы выполнялись реализации (например, сделанные пользователем), расширяющие абстрактный класс без изменений

Ответ 7

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

Ответ 8

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

Ответ 9

Что вы должны использовать, абстрактные классы или интерфейсы?

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

  • Вы хотите поделиться кодом между несколькими тесно связанными классами.
  • Вы ожидаете, что классы, которые расширяют ваш абстрактный класс, имеют много общих методов или полей или требуют модификаторов доступа, отличных от public (например, protected и private).
  • Вы хотите объявить нестатические или не финальные поля. Это позволяет вам определять методы, которые могут обращаться и изменять состояние объекта, к которому они принадлежат.

Рассмотрите возможность использования интерфейсов, если любое из этих утверждений применимо к вашей ситуации:

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

Обратитесь к ссылке на документацию Oracle для получения более подробной информации.

Ответ 10

Абстрактные классы - это частичная реализация абстракции, в то время как интерфейсы - это полная реализация Abstraction.Means в абстрактных классах, мы можем поместить декларацию методов, а также тело метода. Мы не можем создать объект абстрактных классов (ассоциация) и повторно использовать класс по наследству (а не по ассоциации). По умолчанию в интерфейсах все объявленные переменные являются static final и все методы являются общедоступными.

Пример: В JDK существует только несколько абстрактных классов, и HttpServlet является одним из них, который используется в Servlet.So мы не можем создать объект HttpServlet и его можно использовать только по наследству.

Ответ 11

Основное использование интерфейса - это когда вы создаете ссылку на интерфейс и вызываете метод определенного класса, который разрешен во время выполнения. Поэтому всегда лучше создать ссылку интерфейса для вызова метода.

Ответ 12

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