Как вы выбираете между использованием абстрактного класса и интерфейса?
Дубликат: интерфейс против базового класса
Я углубляюсь в мир ООП, шаблонов проектирования и ActionScript 3, и мне все еще интересно, как узнать, когда использовать класс Abstract (псевдо для AS3, который не поддерживает абстрактные классы) и интерфейс. Для меня оба служат просто шаблонами, которые обеспечивают реализацию определенных методов в данном классе. Разница только в том, что абстрактные классы требуют наследования, а интерфейс просто расширяется?
Спасибо, Брайан Ходж
3 ответа
Используйте абстрактный класс, если у вас есть какие-то функциональные возможности, которые должны быть у его подклассов. Например, если у вас есть набор функций, которые вы хотите иметь во всех подклассах базового абстрактного класса.
Используйте интерфейс, если вы просто хотите получить общий контракт на поведение / функциональность. Если у вас есть функция или объект, который вы хотите использовать в наборе различных объектов, используйте интерфейс. Затем вы можете изменить переданный объект без изменения метода или объекта, который его принимает.
Интерфейсы обычно свободны по сравнению с абстрактными классами. Вы не захотите использовать интерфейсы в ситуации, когда вы постоянно пишете один и тот же код для всех методов интерфейса. Используйте абстрактный класс и определите каждый метод один раз.
Кроме того, если вы пытаетесь создать определенную иерархию наследования объектов, вы действительно не захотите делать это только с помощью интерфейсов.
Кроме того, опять же, в некоторых языках у вас может быть только один базовый класс, и если у объекта уже есть базовый класс, вам придется выполнить некоторый рефакторинг, чтобы использовать абстрактный базовый класс. Это может означать или не означать, что вы можете вместо этого использовать интерфейс.
Как отмечает @tvanfosson, неплохо использовать множество интерфейсов, когда вы действительно понимаете абстрактные классы и интерфейсы, на самом деле это не та или иная ситуация. В конкретной ситуации могут использоваться как абстрактные классы, так и интерфейсы, или ни то, ни другое. Мне нравится иногда использовать интерфейсы, просто чтобы ограничить доступ метода или объекта к переданному параметру.
Абстрактные классы предлагают возможность реализации определенных методов и требуют, чтобы другие были реализованы в наследующем классе. С интерфейсами все должно быть реализовано в классе реализации.
Как отмечает @m4bwav, основное отличие состоит в том, что абстрактный класс может и часто обеспечивает реализацию по умолчанию по крайней мере для некоторых методов. Это позволяет вам использовать абстрактный класс, чтобы сохранить ваш код СУХИМ (не повторяйте себя), сохраняя код, общий для всех классов, которые наследуются от абстрактного класса в самом абстрактном классе.
Я думаю, что это ложная дилемма. Вам не нужно и, возможно, не следует выбирать между интерфейсами и абстрактными классами. В большинстве случаев вы захотите определить интерфейс, а затем ваш абстрактный класс предоставит реализацию по умолчанию, каркасную реализацию, если она требуется / желательна. Для меня вопрос заключается в том, нужен ли мне интерфейс или интерфейс и абстрактный класс, а не интерфейс или абстрактный класс. Использование интерфейса отделяет ваш код от любой конкретной реализации, даже от реализации абстрактного класса. Если вы решили использовать альтернативную реализацию, использование интерфейса позволило бы это, тогда как если бы у вас был только абстрактный класс, вам пришлось бы реорганизовать рефакторинг, чтобы добавить интерфейс позже.
Единственная ситуация, когда я вижу, что предоставление интерфейса в такой ситуации нежелательно, - это когда вы хотите ограничить его, чтобы можно было использовать только вашу реализацию. Использование абстрактного класса и наличие определенных методов не виртуальными заставит использовать ваш код при любых обстоятельствах, когда разработчик наследует ваш класс.