Как вы решаете между использованием абстрактного класса и интерфейса?

Дублировать: Интерфейс и базовый класс


Я все глубже погружаюсь в мир ООП, шаблонов проектирования и ActionScript 3, и мне все еще интересно узнать, когда использовать абстрактный класс (псевдо для AS3, который не поддерживает абстрактные классы) и интерфейс. Для меня оба просто служат шаблонами, которые гарантируют, что определенные методы реализованы в данном классе. Разница заключается только в том, что абстрактные классы требуют наследования, а интерфейс просто расширяется?

Спасибо, Брайан Ходж hodgedev.com

Ответ 1

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

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

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

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

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

Как отмечает @tvanfosson, неплохо использовать множество интерфейсов, когда вы действительно понимаете абстрактные классы и интерфейсы, это не совсем иная ситуация. В конкретной ситуации могут использоваться как абстрактные классы, так и интерфейсы, либо нет. Мне нравится иногда использовать интерфейсы, чтобы ограничить доступ метода или объекта к переданному в объекте параметра.

Ответ 2

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

Ответ 3

Как отмечает @m4bwav, основное отличие состоит в том, что абстрактный класс может и часто выполняет стандартную реализацию хотя бы для некоторых методов. Это позволяет использовать абстрактный класс, чтобы сохранить код DRY (не повторяйте себя), сохраняя общий код для всех классов, которые наследуются от абстрактного класса в самом абстрактном классе.

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

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