Для чего нужны абстрактные классы и интерфейсы java

Абстрактные классы и интерфейсы

От абстрактных классов и интерфейсов нельзя создавать объекты. Они служат своего рода шаблонами для обычных классов.

Абстрактный класс – это некое обобщение. Например, не существует конкретного объекта, напрямую созданного от класса Млекопитающие. Класс Млекопитающие – обобщение, абстракция. От этого класса создаются дочерние классы – отряды, и только от них уже создаются объекты. Абстрактный класс отвечает на вопрос «что чем является». Например, парнокопытные являются млекопитающими.

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

Один класс может использовать несколько интерфейсов. Этим объясняется их популярность в Java, так как здесь отсутствием множественное наследование классов.

В Java, чтобы объявить класс абстрактным, надо в заголовке прописать слово abstract. Также обычно должен быть хотя бы один абстрактный метод. Рассмотрим пример:

Нельзя создавать объекты от класса AbstrClass, так как в его заголовке есть слово abstract. (Однако переменную такого типа можно было бы создать.)

Нельзя опустить реализацию метода strPrint() в классе UsualClass, поскольку он наследник абстрактного класса, в котором указанный метод объявлен абстрактным.

Абстрактные методы не имеют тел.

Если бы класс AbstrClass не содержал абстрактный strPrint(), или метод был бы не абстрактным, то в UsualClass можно было бы не переопределять данный метод. Таким образом, объявляя абстрактные методы, мы заставляем дочерние классы придерживаться определенного стандарта.

Абстрактный класс может не иметь абстрактных методов. Отличие такого класса от обычного родительского только в том, что от него нельзя создавать объекты.

При определении интерфейсов вместо class пишется ключевое слово interface. Если есть родительские интерфейсы, они также как в случае классов перечисляются после слова extends. У интерфейсов не может быть родительских классов.

Поскольку все методы интерфейсов по умолчанию абстрактные и публичные, перед их именами не требуется писать соответствующих модификаторов.

Если класс использует интерфейс, имя интерфейса указывается после слова implements (реализует). В случае наследования нескольких интерфейсов они перечисляются через запятую. Наследовать интерфейсы могут как обычные, так и абстрактные классы.

Если класс является наследником как другого класса, так интерфейса, в его заголовке сначала пишется extends имя_класса, затем implements имя_интерфейса.

Если не указать слово public в реализации метода getStr(), будет ошибка.

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

Приведенная программа один раз мяукнет и два раза гавкнет, так как для каждого животного будет вызвана его реализация метода. Это также пример полиморфизма.

В случае наследования интерфейса было бы так:

В Java над переопределяемыми методами принято писать аннотацию @Override. Так при взгляде на класс сразу понятно, что метод не определяется, а переопределяется.

В последних версиях языка Java в интерфейсах можно писать реализацию методов. Перед такими методами добавляется ключевое слово default:

Источник

ООП. Часть 6. Абстрактные классы и интерфейсы

Узнайте истинную мощь наследования и полиморфизма! Раскрываем секреты абстрактных классов и интерфейсов.

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

В предыдущей статье мы увидели, насколько удобнее становится ООП благодаря наследованию. Но оно может стать ещё лучше, если использовать абстрактные классы и интерфейсы.

Все статьи про ООП

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Абстрактные классы

Особенность абстрактных классов в том, что их можно использовать только как родительский класс, то есть вы не можете создать объект. Для их объявления используется ключевое слово abstract.

Это может понадобиться, чтобы объединить реализацию других схожих классов. Например, в вашей игре должны быть персонаж игрока и NPC (неигровые персонажи). У них могут быть общие свойства (имя, координаты) и методы (перемещение, изменение анимации).

Чтобы не повторять код несколько раз, можно вынести реализацию этих свойств и методов в абстрактный класс Character:

Тут всё как у обычных классов, но в конце можно заметить объявление свойства и метода без реализации. Реализация этих абстрактных свойств должна находиться в дочернем классе:

Когда объявляется реализация такого члена класса, необходимо указать ключевое слово override. Абстрактными могут быть следующие члены класса:

Дочерний класс должен реализовывать все члены родительского абстрактного класса, кроме тех случаев, когда дочерний класс тоже абстрактный.

В остальном всё очень похоже на обычные классы. Например, поле Y класса Character публичное, чтобы можно было использовать его в свойстве Y дочерних классов.

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Абстрактный класс должен быть публичным.

Источник

Для чего нужны абстрактные классы и интерфейсы java

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

1. Существующие классы можно легко приспособить для реализации но­вого интерфейса.
Пояснение: для этого достаточно написать implements и реализовать необходимые методы. Но уже имеющиеся классы в общем случае не могут быть переделаны для расширения нового абстрактного класса. Если вы хотите, чтобы два класса расширяли один и тот же абстрактный класс, вам придется поднять этот класс в иерархии настолько высоко, чтобы он стал предком обоих этих классов. Это может привести к нарушению логики иерархии типов, заставляя всех потомков нового абстрактного класса расширять его независимо от того, насколько это целесообразно.

2. Интерфейсы идеально подходят для создания миксинов.
Пояснение: Миксин (mixin) — это тип, который класс может реализовать в дополнение к своему «первичному типу», объявляя о том, что этот класс предоставляет некоторое необязательное поведение. Например, Comparable является таким интерфейсом-миксином, т.к. добавляет (примешивает) к первоначальным возможностям типа дополнительную функциональность.
Использовать абстракт­ные классы для создания миксинов нельзя по той же причине, по которой их невозможно приспособить к уже имеющимся классам: класс не может иметь больше одного родителя, и в иерархии классов нет подходящего места, куда можно поместить миксин.

3. Интерфейсы позволяют создавать неиерархические каркасы типов.
Пояснение: иерархии типов прекрасно подходят для организации некоторых сущностей, но зато сущности других типов невозможно аккуратно уложить в строгую ие­рархию. Альтернативой им является раздутая иерархия классов.

4. Интерфейсы обеспечивают безопасное и мощное развитие функци­ональности с использованием шаблона Декоратор. Паттерн Декоратор позволяет динамически (в ходе выполнения программы) добавлять объекту новые возможности (состояние и/или поведение) на основе композиции.

Источник

Разница между абстрактными классами и интерфейсами

Интерфейс описывает только поведение. У него нет состояния. А у абстрактного класса состояние есть: он описывает и то, и другое.

Возьмем для примера абстрактный класс Bird и интерфейс Flyable :

Давай создадим класс птицы Mockingjay (сойка-пересмешница) и унаследуем его от Bird :

Как видишь, мы легко получаем доступ к состоянию абстрактного класса — к его переменным species (вид) и age (возраст).

Но если мы попытаемся сделать это же с интерфейсом, картина будет другой. Можем попробовать добавить в него переменные:

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

Интерфейс только описывает поведение. Соответственно, мы не сможем реализовать внутри интерфейса геттеры и сеттеры. Такова природа интерфейса: он нужен для работы с поведением, а не состоянием.

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

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

Вернемся к нашему примеру с птицами.

Наш абстрактный класс Bird нужен, чтобы на его основе создавать птиц. Только птиц и никого больше! Конечно, они будут разными.

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

С интерфейсом Flyable все обстоит по-другому. Он только описывает поведение, соответствующее его названию, — «летающий». Под определение «летающий», «способный летать» попадает много объектов, не связанных между собой.

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Мы бы не смогли описать их с помощью абстрактного класса. У них нет общего состояния, одинаковых полей. Чтобы дать характеристику самолету, нам, наверное, понадобятся поля «модель», «год выпуска» и «максимальное количество пассажиров». Для Карлсона — поля для всех сладостей, которые он сегодня съел, и список игр, в которые он будет играть с Малышом. Для комара. э-э-э. даже не знаем… Может, «уровень надоедливости»? 🙂

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

Классы могут реализовывать сколько угодно интерфейсов, но наследоваться можно только от одного класса.

Об этом мы уже говорили не раз. Множественного наследования в Java нет, а множественная реализация есть. Отчасти этот пункт вытекает из предыдущего: интерфейс связывает между собой множество разных классов, у которых часто нет ничего общего, а абстрактный класс создается для группы очень близких друг другу классов. Поэтому логично, что наследоваться можно только от одного такого класса. Абстрактный класс описывает отношения «is a».

Стандартные интерфейсы InputStream & OutputStream

Очень простой класс для записи примитивных типов Java и строк. Наверняка ты поймешь написанный код даже без объяснений:

Опять же, ты можешь самостоятельно «поиграть» с этим кодом и проверить, как он будет работать на реальных файлах твоего компьютера.

Источник

Отличие и правильность использования абстрактных классов от интерфейсов в Java

Пытаюсь понять чем эти два элемента отличаются. Почитал тут и тут, а также лекцию которую изучаю. Если я правильно понимаю, кроме определения и подключения я вижу следующее возможности:

Абстрактный класс

Интерфейс

Я понимаю, что интерфейс определяет состояние, а абстрактный класс определяет и состояние и поведение. Почему тогда не пользоваться только одним вариантом, например классом?

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

В каких случаях нужно использовать именно то, а не другое?

Есть ли примеры использования в которых именно необходимо использовать тот или иной вариант?

Интересует именно применение в Java.

Дополнение Допустим есть такая структура.

Есть класс треугольника:

Есть класс квадрата:

Я могу переделать её в интерфейс? Нужно ли её переделать в интерфейс? Или стоит разделить на две части?

PS: Дополнительный вопрос к интерфейсам. Я знаю, что интерфейс предназначен для защиты работы класса. Но разве недостаточно наложения ограничений на класс (я имею ввиду модификаторы доступа)?

PS PS PS: Извиняюсь за большое количество вопросов. Просто хотелось бы полностью разобраться с этой темой)

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

3 ответа 3

Интерфейс определяет поведение, в общем смысле интерфейс рассказывает о том, как работать с классом, который этот интерфейс реализует, к примеру все двери умеют закрываться и открываться и на не важно какая это дверь и как она сделана, главное, что это дверь и у неё есть наличие методов для открытия и закрытия. Интерфейс может использоваться классами, которые вообще никак не связаны с друг другом по смыслу (Comparable как пример). И самое важное множественное наследование.

Абстрактный класс определяет поведение и состояние. Абстрактный класс используют для наследования (т.е. мы имеем тесную связь между классами), с помощью него описывают общие черты для наследников. В нем могут находится конкретные (в интерфейсе тоже с java 8) и статические методы.

PS нашел статью, которая скорее всего поможет лучше понять разницу ссылка

Для чего нужны абстрактные классы и интерфейсы java. Смотреть фото Для чего нужны абстрактные классы и интерфейсы java. Смотреть картинку Для чего нужны абстрактные классы и интерфейсы java. Картинка про Для чего нужны абстрактные классы и интерфейсы java. Фото Для чего нужны абстрактные классы и интерфейсы java

Рассмотрим пример, когда нужны именно интерфейсы и нельзя обойтись абстрактными классами.

Поясню на примере. Допустим нам нужна возможности

Для этого можно либо создать интерфейсы типа:

Т.е. где-то существуют функции, которые используют их:

Если же мы использовали абстрактные классы, то возникают проблемы:

Интерфейсы (особенно начиная с java8) могут заменить абстрактные классы (в совокупности с другими мерами). Но иногда использование абстрактного класса может быть более практично.

Допустим, мы создаем библиотеку для сохранения объектов в БД. Можно сделать интерфейс для объекта, который можно сохранять:

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

Конечно у наследования реализации и использования абстрактных классов есть минусы, которые нужно учитывать, и взвешивать за и против в конкретном случае.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *