Я знаю синтаксис, правила, применяемые к абстрактному классу, и я хочу знать использование абстрактного класса
Абстрактный класс не может быть создан напрямую, но может быть расширен другим классом
В чем преимущество этого?
Чем он отличается от интерфейса?
Я знаю, что один класс может реализовывать несколько интерфейсов, но может расширять только один абстрактный класс. Это единственная разница между интерфейсом и абстрактным классом?
Я осведомлен об использовании интерфейса. Я узнал об этом из модели делегирования событий AWT на Java.
В каких ситуациях я должен объявлять класс как абстрактный класс? Каковы преимущества этого?
java
object-oriented
abstract-class
Вайбхав Яни
источник
источник
Ответы:
Этот ответ хорошо объясняет различия между абстрактным классом и интерфейсом, но он не отвечает, почему вы должны объявить его.
С чисто технической точки зрения никогда не требуется объявлять класс абстрактным.
Рассмотрим следующие три класса:
Вам не нужно делать класс Database абстрактным, даже если есть очевидная проблема с его реализацией: когда вы пишете эту программу, вы можете печатать,
new Database()
и она будет действительной, но она никогда не будет работать.В любом случае, вы все равно получите полиморфизм, поэтому, пока ваша программа только создает
SqlDatabase
и создаетOracleDatabase
экземпляры, вы можете написать такие методы:Абстрактные классы улучшают ситуацию, не давая разработчику создавать базовый класс, потому что разработчик пометил его как отсутствующий функционал . Он также обеспечивает безопасность во время компиляции, так что вы можете гарантировать, что любые классы, которые расширяют ваш абстрактный класс, обеспечивают минимальную функциональность для работы, и вам не нужно беспокоиться о том, чтобы использовать методы-заглушки (как вышеописанные), которые каким-либо образом имеют наследники. волшебно знать, что они должны переопределить метод, чтобы заставить его работать.
Интерфейсы - это совершенно отдельная тема. Интерфейс позволяет вам описать, какие операции могут быть выполнены над объектом. Обычно вы используете интерфейсы при написании методов, компонентов и т. Д., Которые используют сервисы других компонентов, объектов, но вас не волнует, какой тип объекта вы получаете от сервисов.
Рассмотрим следующий метод:
Вам не важно,
database
наследует ли объект какой-либо конкретный объект, вы просто заботитесь о том, чтобы у него былaddProduct
метод. Так что в этом случае интерфейс лучше подходит, чем когда все ваши классы наследуются от одного базового класса.Иногда комбинация двух работает очень хорошо. Например:
Обратите внимание, что некоторые базы данных наследуются от RemoteDatabase, чтобы использовать некоторые функциональные возможности (например, подключение перед записью строки), но FileDatabase - это отдельный класс, который реализует только
IProductDatabase
.источник
сходства
Абстрактные абстракции и классы необходимы для абстракции. Они не могут быть созданы с новым , но могут быть решены в инверсии контрольных контейнеров или с помощью заводских шаблонов.
разница
Интерфейсы
Абстрактный класс
Это действительно легко найти ответ с помощью простого запроса Google .
источник
В абстрактном классе вы можете реализовать некоторые методы и оставить (принудительно) остальные для реализации расширяющим классом. Вы не можете реализовать методы в интерфейсе. Вы не можете заставить кого-либо переопределить что-либо при расширении обычного класса. С абстрактным классом вы можете.
источник
Абстрактные классы предназначены для отношений "is a", а интерфейсы - для "can do".
Абстрактные классы позволяют добавлять базовое поведение, чтобы программистам не приходилось все кодировать, и при этом заставлять их следовать вашему дизайну.
источник
Помимо глубоких технических деталей - таких как реализация некоторых методов для абстрактных классов и т. Д., Смысл такой:
Интерфейсы определяют общую возможность - IEnumerable определяет, что класс, который реализует этот интерфейс, может быть перечислен. Это ничего не говорит о самом классе.
Абстрактные (или базовые) классы определяют поведение - WebRequest определяет общее поведение всех дочерних классов, таких как HttpWebRequest и т. Д. Он определяет основное значение класса и его реальную цель - доступ к веб-ресурсам.
источник
Wikipedia запись .
Основное различие между интерфейсом и абстрактным классом состоит в том, что абстрактный класс может предоставлять реализованные методы. С интерфейсами вы можете только объявить методы, написать их подпись. Вот пример класса, который расширяет абстрактный класс, который реализует два интерфейса: (Java)
В этом примере MyAbstractClass предоставляет открытый метод, который печатает все три значения. В ImpClass вам нужно реализовать getValue1 и getValue2 соответственно из MyInterface1 и MyInterface2 и getValue3 из абстрактного класса.
Вуаля.
Есть и другие аспекты (интерфейс: только открытые методы, абстрактный класс: защищенные абстрактные и открытые абстрактные методы), но вы можете прочитать это сами.
В заключение отметим, что абстрактный класс, который предоставляет только абстрактные методы, является «чистым» абстрактным базовым классом, или интерфейсом.
источник
Другими словами, вы должны начать с вопроса: «Обязательно ли эти классы совместно используют реализацию , или они просто имеют общий интерфейс? ?»
Если ответ смешанный, такой как - эти три класса должны совместно использовать реализацию, но эти два других только разделяют их API - тогда вы можете создать интерфейс для всех пяти из них и абстрактный класс для этих трех с общим код.
Существуют также другие способы совместного использования реализации, например, для инкапсуляции объекта с этой реализацией (например, в шаблоне стратегии ).
источник
Вы бы объявили реферат класса, если не хотите, чтобы разработчику (возможно, вам самим) было разрешено создавать его экземпляр, потому что он не будет работать или не будет иметь смысла.
Например, рассмотрим игру, в которой существуют разные типы игровых объектов. Все они наследуются от базового
GameEntity
класса.Этот класс объявлен,
abstract
так как не имеет смысла его создавать. Он объявляет некоторые действия для игровых сущностей и некоторые атрибуты, но нигде в этом классе эти атрибуты не инициализированы. Этот класс служит шаблоном для игровых сущностей, но не предназначен для самостоятельной реализации и как таковой объявленabstract
.Что касается разницы в использовании между абстрактным классом и интерфейсом:
На мой взгляд, интерфейс - это способ получить полиморфное поведение, не будучи ограниченным механизмом единого наследования некоторых языков.
Давайте вернемся к игре в качестве примера. Рассмотрим класс,
Enemy
который является производным отGameEntity
. У этого класса есть методattackMeFromDistance(RangedAttacker attacker)
. Этот метод позволяет субъектам атаковать врага издалека.Как видите, этот метод принимает
RangedAttacker
тип в качестве параметра. Однако все игровые объекты уже наследуются отGameEntity
. Они не могут продлить другой класс.Взять на занятия
Mage
иArcher
к примеру. Мы хотим, чтобы они оба были приняты в качестве параметров вattackMeFromDistance(RangedAttacker attacker)
методе, но они уже полученыGameEntity
.Чтобы решить эту проблему, мы создаем новый интерфейс:
Класс, реализующий этот интерфейс, должен реализовывать
attackFromDistance()
метод, и, таким образом, гарантируется, что он имеет дальние атакующие возможности. Это означает, чтоattackMeFromDistance
метод теперь может безопасно принимать классы, которые реализуют этот интерфейс. Таким образом, делаяMage
иArcher
реализация этого интерфейса решает нашу проблему.Для меня это сила интерфейсов.
Таким образом, чтобы подвести итог, вы обычно используете абстрактный класс, когда вы хотите иметь базовый класс для некоторых классов, но не имеет смысла создавать его экземпляр самостоятельно (или в случае, когда у него есть
abstract
методы, которые должны быть реализуется подклассами, и в этом случае компилятор заставит вас сделать классabstract
). Вы бы использовали интерфейс для получения полиморфного поведения, не будучи ограниченным механизмом единственного наследования.источник
источник