@ArtFutureDev
Студент

Отличия абстрактного класса от интерфейса?

В чем отличие абстрактного класса от интерфейса в Java? И в каких ситуациях лучше применять абстрактный класс, а в каких - интерфейс?
  • Вопрос задан
  • 17174 просмотра
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
В чем отличие абстрактного класса от интерфейса в Java?


Все упирается в понятие "тип". В былые времена, то есть во времена языка Simula, из которого черпали вдохновение создатели C++, были только классы. И на классах базировалась система типов. Причем механизм наследования был реализован так, как реализован, исключительно для экономии памяти, которая в те времена была очень дорогой.

Для того чтобы достичь полиморфизма, мы должны иметь возможность объявлять абстрактные типы. Мол "любая хрень которая имеет такой тип будет работать как надо". Потому в языках типа C++ появились абстрактные классы. Поскольку иногда нам хочется делать композицию абстрактных типов, в C++ реализовали множественное наследование.

В Java, которая во многом черпала вдохновения из C++ и smalltalk, решили ввести еще одну сущность - интерфейсы. Это был своего рода упрощенный способ задать абстрактный базовый тип. По итогу чтобы не решать проблему бриллианта (или ромба) от множественного наследования было решено отказаться и дать возможность классам имплементить несколько интерфейсов.

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

В целом абстрактные классы нужны тогда, когда вам нужно наследование. Обычно это в ситуациях, когда у вас есть несколько классов, которые должны иметь общий абстрактный тип (то есть нельзя выделить наиболее слабого по ограничениям предка). Например если мы делаем цепочку классов String <- Email, то тут нет смысла в абстрактных классах так как тип String уже включает в себе подмножество типов Email.

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

Так же рекомендую к прочтению: www.javaworld.com/article/2073649/core-java/why-ex...
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
abyrkov
@abyrkov
JavaScripter
Если выражаться "проще википедии", то главная разница между абстрактным классом и интерфейсом в том, что интерфейсы можно множественно наследовать, а абстрактные классы могу содержать не абстрактные вещи.

Что касается их использования... тут все гораздо проще, если понимать, зачем нужен абстрактный класс, а зачем - интерфейс. Абстрактный класс используется, когда мы хотим получить конкретную реализацию, но она должна гибкой. Интерфейс используется, чтоб реализация этой вещи вообще была.
Ответ написан
@koronabora
Человек
Интерфейсы используются для множественного наследования. В интерфейсе нельзя прописывать реализацию методов. Этими ограничениями мы исключаем одну из проблем множественного наследования: если мы наследуемся от 2 классов с одинаковым методом (такое в с++ возможно), то вызывая этот метод в наследнике, то непонятно какую реализацию использовать. Наследуясь от нескольких интерфейсов, мы пишем реализацию конкретно под наш класс и эта проблема исключается.
Ответ написан
@sitev_ru
sitev.ru - мой блог ...
Всё уже есть в википедии:
Интерфейс — это просто чистый абстрактный класс, то есть класс, в котором не определено ничего, кроме абстрактных методов.
Ответ написан
@dev400
Абстрактный класс содержит абстрактные методы с общим функционалом, который будет логичен для методов его наследников(смотри в сторону принцип подстановки Барбары Лискоу). Интерфейс же просто описывает возможности.
Ответ написан
Комментировать
pazukdev
@pazukdev
Java Dev
Вопрос был бы интереснее, если бы спрашивали про полностью абстрактный класс vs интерфейс.
Если не вдаваться в подробности, полностью абстрактный класс может иметь состояние, а интерфейс - нет. Отсюда вытекает использование: если у наследников должно быть общее описание состояния - использовать абстрактный класс, во всех других случаях - интерфейс.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы