абстрактный класс и интерфейс — это два механизма языка Java, которые поддерживают определения абстрактных классов. Именно благодаря существованию этих двух механизмов языку Java предоставляются мощные объектно-ориентированные возможности. Существует большое сходство между абстрактным классом и интерфейсом с точки зрения поддержки определения абстрактного класса, и их даже можно заменить друг другом. Поэтому многие разработчики, похоже, более небрежно относятся к выбору абстрактного класса и интерфейса при определении абстрактных классов. На самом деле между ними все еще существует большая разница. Их выбор даже отражает понимание природы проблемной области и правильность и разумность понимания замысла проекта. В этой статье мы проанализируем различия между ними и попытаемся предоставить разработчикам основу для выбора между ними.
Понимание абстрактных классов
И абстрактный класс, и интерфейс используются для создания абстрактных классов на языке Java (абстрактный класс в этой статье не переводится с абстрактного класса, он представляет собой абстрактное тело, а абстрактный класс — это метод, используемый для определения абстрактных классов на языке Java), читатели пожалуйста, обратите внимание на определение), что такое абстрактный класс и какие преимущества может принести нам использование абстрактных классов?
В объектно-ориентированной концепции мы знаем, что все объекты представлены классами, но обратное неверно. Не все классы используются для описания объектов. Если класс не содержит достаточно информации для описания конкретного объекта, такой класс является абстрактным. Абстрактные классы часто используются для представления абстрактных концепций, которые мы получаем в результате анализа и проектирования проблемных областей. Они представляют собой абстракции ряда конкретных концепций, которые выглядят по-разному, но по сути одинаковы. Например: если мы разработаем программное обеспечение для редактирования графики, мы обнаружим, что в проблемной области есть некоторые конкретные понятия, такие как круги и треугольники. Они разные, но все они относятся к понятию формы. Понятие формы различно. в проблемной области, если оно существует, то это абстрактное понятие. Именно потому, что абстрактные концепции не имеют соответствующих конкретных концепций в проблемной области, абстрактные классы, используемые для представления абстрактных концепций, не могут быть созданы.
В объектно-ориентированной области абстрактные классы в основном используются для сокрытия типов. Мы можем построить абстрактное описание фиксированного набора поведений, но этот набор поведений может иметь любое количество возможных конкретных реализаций. Это абстрактное описание является абстрактным классом, и этот набор любых возможных конкретных реализаций представлен всеми возможными производными классами. Модули могут работать с абстрактным телом. Поскольку модуль опирается на фиксированную абстракцию, его нельзя одновременно изменить, поведение этого модуля также можно расширить, производя его от этой абстракции; Читатели, знакомые с OCP, должны знать, что для реализации OCP (Open-ClosedPrinciple), одного из основных принципов объектно-ориентированного проектирования, ключевым моментом являются абстрактные классы.
Взгляд на абстрактный класс и интерфейс с уровня грамматического определения.
На грамматическом уровне язык Java предоставляет разные определения абстрактного класса и интерфейса. Ниже приведен пример определения абстрактного класса с именем Demo, иллюстрирующий эту разницу.
Способ определения абстрактного класса Demo с использованием абстрактного класса следующий:
С точки зрения программирования, как абстрактный класс, так и интерфейс могут использоваться для реализации идеи «проектирования по контракту». Однако все же существуют некоторые различия в конкретном использовании.
Прежде всего, абстрактный класс представляет отношение наследования в языке Java, и класс может использовать отношение наследования только один раз. Однако класс может реализовывать несколько интерфейсов. Возможно, это компромиссное решение разработчиков языка Java при рассмотрении поддержки Java множественного наследования.
Во-вторых, в определении абстрактного класса мы можем назначить поведение метода по умолчанию. Но в определении интерфейса методы не могут иметь поведение по умолчанию. Чтобы обойти это ограничение, необходимо использовать делегаты, но это добавит некоторую сложность и иногда вызовет массу проблем.
Существует еще одна серьезная проблема, связанная с невозможностью определить поведение по умолчанию в абстрактном классе: это может вызвать проблемы с обслуживанием. Потому что, если вы позже захотите изменить интерфейс класса (обычно представленный абстрактным классом или интерфейсом) для адаптации к новым ситуациям (например, добавить новые методы или добавить новые параметры к существующим методам), это будет очень хлопотно и может Это занимает много времени (особенно когда имеется много производных классов). Но если интерфейс реализован через абстрактный класс, вам может потребоваться только изменить поведение по умолчанию, определенное в абстрактном классе.
Аналогично, если поведение по умолчанию не может быть определено в абстрактном классе, одна и та же реализация метода появится в каждом производном классе абстрактного класса, что нарушает принцип «одно правило, одно место», что приводит к дублированию кода, что также не способствует к будущему обслуживанию. Поэтому будьте очень осторожны при выборе между абстрактным классом и интерфейсом.
Взгляд на абстрактный класс и интерфейс с точки зрения концепций дизайна. Выше в основном обсуждаются различия между абстрактным классом и интерфейсом с точки зрения грамматического определения и программирования. Различия на этих уровнях относительно низкоуровневые и несущественные. В этом разделе будет проанализирована разница между абстрактным классом и интерфейсом с другого уровня: концепции дизайна, отраженные ими. Автор считает, что