ABAP Blog | Абстрактный класс или интерфейс, что и когда использовать
от Astrafox·5 комментариев
Абстрактные классы как и интерфейсы используются для одних целей. Как их применять при разработке в ABAP познакомимся в этой статье.
Что такое абстрактный класс?
Абстрактный класс это специальный вид класса который не может иметь инстанций. Мы можем лишь создать инстанции дочернего от него класса, если он так же не является абстрактным. Абстрактный класс должен содержать по крайней мере один абстрактный метод. Абстрактные методы имеют только объявление, они не должны иметь реализацию. Кроме того мы можем создать переменные типа абстрактного класса и присвоить им инстанцию дочернего класса во время выполнения. Пример простого абстрактного класса:
1 2 3 4 5 6 7 8 9 10 11 12 | CLASS zcl_base_functions DEFINITION ABSTRACT. PUBLIC SECTION. METHODS: set_my_name ABSTRACT IMPORTING iv_text TYPE STRING . METHODS: write_name. PRIVATE SECTION. DATA: my_name TYPE STRING. ENDCLASS. «zcl_base_functions DEFINITION * CLASS zcl_base_functions IMPLEMENTATION. METHOD write_name. ENDMETHOD. «write_name ENDCLASS. «zcl_base_functions IMPLEMENTATION |
Что такое интерфейс?
Во-первых интерфейс это не класс. Это сущность не имеющая реализации. Интерфейс может содержать только объявление методов и компонентов. Компоненты интерфейса всегда находятся в общедоступном разделе (public). Чтобы изменить их видимость в дальнейшем мы можем создать класс на основе интерфейса. Пример простого интерфейса и класса его реализующего:
1 2 3 4 5 6 7 8 9 | INTERFACE zif_order. METHODS: set_order_data IMPORTING iv_order_Data TYPE STRING. METHODS: create_order. ENDINTERFACE. * CLASS zcl_sales_order DEFINITION. PUBLIC SECTION. INTERFACES: zif_order. ENDCLASS. |
Основные отличия абстрактных классов от интерфейсов:
- Множественное наследование. Мы можем использовать множественное наследование с помощью интерфейсов. ABAP не позволяет создавать класс на основе более чем одного супер класса, под супер классом имеется в виду абстрактный класс.
- Функциональные возможности. Если мы добавим в интерфейс новый метод, все классы реализующие данный интерфейс так же должны определить этот метод, в противном случае возникнет ошибка. Для абстрактных классов если мы добавим новый не абстрактный метод, не будет необходимости его определения в наследуемых от него классах.
- Поведение. Мы можем заранее задать определение для не абстрактных методов в абстрактном классе. Интерфейс такого не позволяет.
- Видимость. Все компоненты интерфейса по умолчанию находятся в общедоступном разделе (public). В абстрактном классе мы можем сами задавать область видимости компонентов.
На основе данных особенностей можно определить следующие рекомендации:
- В случае если необходимо использовать множественное наследование, надо использовать интерфейсы.
- В случае когда вы хотите создать заранее определенное поведение для сущности необходимо рассмотреть возможность использования абстрактного класса с не абстрактными методами. Это предаст определенную гибкость при создании наследуемого класса, т.к. некоторое го поведение уже будет определено.
- Если вы хотите обеспечить общую реализацию функциональности для всех наследующих компонентов используйте абстрактный класс. Абстрактные классы позволяют частично реализовать свой класс, интерфейсы нет.
- Интерфейсы должны использоваться для широкого круга объектов. Абстрактные классы должны быть использованы для наследуемых классов тесно связанных друг с другом.
- Интерфейсы должны использоваться как определения небольших функциональностей, объединяясь вместе которые задают поведение конкретному бизнес объекту.
Оригинал статьи.
В чем разница между абстрактными и интерфейсными классами?
Прочее › Java › Что такое абстрактный класс в Java?
Фундаментальная разница между интерфейсом и абстрактным классом заключается в том, что интерфейс определяет только поведение. Он не сообщает ничего про объект, который будет его реализовывать. Например, такое поведение как «движение» может быть применимо к разным типам объектов: машина, кот, котировки курса и т. д.
- В чем разница между интерфейсом и абстрактным классом?
- Что такое абстрактный класс и интерфейс?
- Чем отличается класс от абстрактного класса С?
- Какая разница между интерфейсом и классом?
- Когда лучше использовать абстрактный класс или интерфейс?
- Что такое интерфейс класса?
- Что означает абстрактный класс?
- Что может быть в абстрактном классе?
- Зачем делать класс абстрактным?
- Можно ли наследоваться от абстрактного класса?
- Когда лучше использовать интерфейс?
- Какая разница между абстрактным классом и интерфейсом Котлин?
- Что вы понимаете под интерфейсом?
- Можно ли класс использовать как интерфейс?
- В чем разница между абстрактным классом и интерфейсом php?
- Что называется интерфейсом?
В чем разница между интерфейсом и абстрактным классом?
Интерфейс описывает только поведение (методы), и у него нет полей. Точнее, есть возможность их объявить, но они будут public static final. В то же время абстрактный класс может содержать классические поля, которые будут принадлежать разным объектам.
Что такое абстрактный класс и интерфейс?
Абстрактный класс — это класс, у которого не реализован один или больше методов (некоторые языки требуют такие методы помечать специальными ключевыми словами). Интерфейс — это абстрактный класс, у которого ни один метод не реализован, все они публичные и нет переменных класса.
Чем отличается класс от абстрактного класса С?
Абстрактный класс похож на обычный класс. Он также может иметь переменные, методы, конструкторы, свойства. Единственное, что при определении абстрактных классов используется ключевое слово abstract.
Какая разница между интерфейсом и классом?
Класс — это объект, из которого мы можем создавать объекты с одинаковой конфигурацией — свойства и методы. Интерфейс — это группа связанных свойств и методов, которые описывают объект, но не обеспечивают их реализацию или инициализацию.
Когда лучше использовать абстрактный класс или интерфейс?
Если нам нужно поведение — необходимо использовать интерфейс. Если речь про концептуальный объект — мы должны использовать абстрактный класс.
Что такое интерфейс класса?
Interface) — структура программы/синтаксиса, определяющая отношение с объектами, объединенными только некоторым поведением. При проектировании классов, разработка интерфейса тождественна разработке спецификации (множества методов, которые каждый класс, использующий интерфейс, должен реализовывать).
Что означает абстрактный класс?
Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП — полиморфизм. Абстрактный класс может содержать (и не содержать) абстрактные методы и свойства.
Что может быть в абстрактном классе?
Абстрактный класс может содержать как обычные методы так и абстрактные (abstract) методы, одновременно. А так же конструкторы, если это необходимо. НО! Создать объект на основе абстрактного класса невозможно.
Зачем делать класс абстрактным?
Абстрактные классы используются в качестве обобщенных концепций, на основе которых можно создавать более конкретные производные классы. Невозможно создать объект абстрактного типа класса. Однако можно использовать указатели и ссылки на абстрактные типы классов.
Можно ли наследоваться от абстрактного класса?
Абстрактные классы в объектно-ориентированном программировании — это базовые классы, которые можно наследовать, но нельзя реализовывать. То есть на их основе нельзя создать объект.
Когда лучше использовать интерфейс?
Когда следует использовать интерфейсы:
- Если нам надо определить функционал для группы разрозненных объектов, которые могут быть никак не связаны между собой.
- Если мы проектируем небольшой функциональный тип
Какая разница между абстрактным классом и интерфейсом Котлин?
Интерфейсы в Kotlin могут содержать объявления абстрактных методов, а также методы с реализацией. Главное отличие интерфейсов от абстрактных классов заключается в невозможности хранения переменных экземпляров. Они могут иметь свойства, но те должны быть либо абстрактными, либо предоставлять реализацию методов доступа.
Что вы понимаете под интерфейсом?
Интерфе́йс (от англ. interface) — граница между двумя функциональными объектами, требования к которой определяются стандартом; совокупность средств, методов и правил взаимодействия (управления, контроля и т. д.) между элементами системы.
Можно ли класс использовать как интерфейс?
Любой класс, который хочет реализовать интерфейс, должен указать это с помощью ключевого слова implements, после которого следует идентификатор реализуемого интерфейса. Указание реализации классом интерфейса располагается между идентификатором класса и его телом.
В чем разница между абстрактным классом и интерфейсом php?
Абстрактные классы могут иметь свойства и методы. Но в отличии от обычных классов, методы в абстрактных классах не имеют тела. Ключевое значение в таких методах — необходимость их реализации в дочерних классах. Интерфейс — это тот же абстрактный класс, но у него нет свойств.
Что называется интерфейсом?
Интерфе́йс (от англ. interface) — граница между двумя функциональными объектами, требования к которой определяются стандартом; совокупность средств, методов и правил взаимодействия (управления, контроля и т. д.) между элементами системы.
Когда использовать интерфейс против абстрактного класса после Java 8
Очевидно, вы имеете в виду функцию «методов по умолчанию», реализующих поведение в интерфейсе.
Вы должны понимать, что эта функция была добавлена для решения этой дилеммы: как задним числом добавить функции, использующие потоки и лямбда-выражения в существующих интерфейсах, не нарушая существующие классы, реализующие эти интерфейсы?
Многие новые методы были добавлены в эти интерфейсы, например, в Java Collections Framework. Добавление методов к существующему интерфейсу автоматически нарушит работу всех классов, реализующих интерфейс, в которых отсутствуют новые необходимые методы. Возможность предоставить запасной вариант, дать реализацию там, где она сейчас требуется, но еще не существует, решила бы дилемму. Так родились «методы по умолчанию».
Цитата из учебника Oracle по ссылке выше:
Методы по умолчанию позволяют добавлять новые функции в интерфейсы ваших библиотек и обеспечивать двоичную совместимость с кодом, написанным для более старых версий этих интерфейсов.
Чтобы процитировать этот ответ Брайана Гетца, архитектора языка Java в Oracle:
Непосредственной причиной добавления методов по умолчанию в интерфейсы была поддержка эволюции интерфейса
Таким образом, эта функция добавления поведения по умолчанию к интерфейсу сама по себе не должна была стать новой основной функцией. Цель по умолчанию
не должен был заменять абстрактный
.
В самом деле, некоторые опытные эксперты по Java рекомендовали отказаться от привычки писать методы по умолчанию для интерфейса.
Вы, безусловно, можете писать свои собственные методы по умолчанию для своих интерфейсов. И, безусловно, вы должны сделать это, если вы находитесь в похожей ситуации публикации интерфейса, который могли реализовать другие, и теперь вы хотите добавить методы. Но ненужное добавление методов по умолчанию может сбить с толку других программистов, которые ожидают частичной реализации в абстрактном классе, а не в интерфейсе.
Четыре ситуации, требующие использования метода
по умолчанию
на интерфейсеВ том же сообщении, указанном выше, Брайан Гетц предлагает три других случая помимо эволюции интерфейса, когда методы по умолчанию на интерфейсе могут быть подходящими. Вот краткое упоминание; подробности см. в его посте.
- Необязательные методы. Метод
по умолчанию
вызывает исключениеUnsupportedOperationException
, поскольку мы ожидаем, что реализации этого интерфейса чаще не захотят реализовывать этот метод. - Удобные методы
- Комбинаторы
Что касается выбора между интерфейсом и абстрактным классом:
- Обычно начинают с интерфейса
- Дважды подумайте, прежде чем добавлять метод
по умолчанию
. Подумайте, соответствует ли ваша ситуация одному из четырех случаев, рекомендованных Брайаном Гетцем, как обсуждалось выше.
- Дважды подумайте, прежде чем добавлять метод
- Если вы обнаружите, что у вас есть дублированный код в нескольких классах, рассмотрите централизацию этого общего кода в абстрактном классе для использования в подклассах.
- В качестве альтернативы используйте композицию, а не наследование (обсуждается ниже).
Например, у вас может быть класс для внутренних ShippingLabelUS
, а также ShippingLabelCanada
и ShippingLabelOverseas
. Все три необходимо конвертировать между имперскими фунтами и метрическими килограммами. Вы обнаружите, что копируете этот код между классами. На этом этапе вы можете рассмотреть возможность расширения всех трех классов от абстрактного класса 9.0021 ShippingLabel , где находится единственная копия методов преобразования веса.
При разработке своего API помните, что Java, как и большинство языков ООП, имеет одиночное наследование. Таким образом, ваши подклассы ограничены расширением только одного класса. Чтобы быть немного более конкретным в отношении одиночного и множественного наследования, я процитирую Брайана Гетца из этого PDF-файла со слайд-презентацией:
[относительно
методов по умолчанию
на интерфейсе]Подождите, это множественное наследование в Java?
• В Java всегда было множественное наследование типов
• Это добавляет множественное наследование поведения
• Но не штата, где большая часть проблем исходит от
Композиция вместо наследования
Альтернативой использованию абстрактного класса для общего поведения является создание отдельного класса для определенного поведения, а затем добавление объекта этого отдельного класса, который будет сохранен как поле-член в более крупном классе. Мудрые программисты часто делятся этой жемчужиной мудрости: Предпочитает композицию наследованию .
Что касается приведенного выше примера транспортной этикетки, вы можете создать класс WeightConverter
, объект которого будет членом каждого из трех классов этикеток. В таком расположении нет необходимости в абстрактном классе.
Абстрактный класс против интерфейса в Kotlin | by Marcin Moskala
Дизайн katemangostar / Freepik«В чем разница между абстрактным классом и интерфейсом?» — это один из самых популярных вопросов при подборе программистов. Популярные ответы:
- Интерфейс не может хранить состояние
- Классы могут иметь реальные функции
- Мы можем реализовать несколько интерфейсов и только один класс
Я покажу, что эти ответы на самом деле неверны. Интерфейсы могут иметь свойства и могут хранить состояние, но не использовать поля. Они могут иметь функции с реальными телами, пока они не являются конечными. Истинные существенные различия между абстрактными классами и интерфейсами:
- Интерфейсы не могут иметь полей
- Мы можем расширить только один класс и реализовать несколько интерфейсов
- Классы имеют конструкторы
Итак, давайте поговорим о мифах:
В интерфейсах Kotlin могут быть функции с телами по умолчанию:
В этих телах мы можем использовать ссылка на класс, использующий this
:
Эти функции не могут быть окончательными, и их всегда можно переопределить. Это разница между интерфейсом и абстрактным классом, где мы можем сделать функцию final. Когда мы переопределяем эти функции, мы по-прежнему можем использовать тело по умолчанию, используя super
:
Свойство в Котлине представляет собой абстракцию геттера ( val
) или геттера и сеттера ( var
). По умолчанию у них есть поля, используемые под капотом. Вот почему этот класс:
Компилируется в код, похожий на этот:
Хотя свойства не обязательно должны иметь внутреннее поле. Например, в следующем коде fullName
— это просто геттер, вычисляемый каждый раз по запросу:
Свойства — это просто аксессоры (геттеры и сеттеры), поэтому они могут присутствовать на интерфейсах, пока у них нет фактических значений. :
Эти свойства также могут иметь тела по умолчанию:
Это немного хакерство и, как правило, плохая практика, но я просто хочу показать, что можно удерживать состояние в интерфейсе. Нам просто нужно использовать тела по умолчанию для его хранения. Где мы можем его хранить? Есть несколько вариантов, и ни один из них не является хорошим. Все они будут плохо управляться и не очищаться должным образом сборщиком мусора. Выбрав меньшее из зол, я решил сохранить его в свойстве объекта-компаньона:
Обратите внимание, что этот способ хранения в памяти отличается от того, когда мы используем поля:
- Сборщик мусора не управляет должным образом
- Свойства связаны с одинаковыми классами, а не с одинаковыми классами (это можно было бы улучшить, если бы мы используйте ссылку)
Это решение противоречит здравому смыслу и не должно использоваться в реальном проекте, если вы действительно хорошо не знаете, что вы делаете и каковы последствия! Хотя хорошо знать, что это возможно, и это показывает нам, что интерфейсы могут сохранять состояние. Это не значит, что вы должны исправлять, когда кто-то говорит, что не может. Трудно и неинтуитивно заставить их правильно сохранять состояние, поэтому в разговорной речи мы говорим, что они не могут. Оставим так 😉
Абстрактные классы могут иметь все, что могут интерфейсы, и, кроме того, они могут иметь поля и конструкторы. Поэтому мы можем корректно хранить состояние в абстрактных классах:
Функции и свойства с телами по умолчанию не только могут быть окончательными, но и окончательными по умолчанию. Мы также можем иметь конструктор и передавать значения этому абстрактному классу:
Когда у нас есть первичный конструктор, у нас может быть блок инициализации
:
С другой стороны, когда мы их используем, мы можем реализовать несколько интерфейсов и расширить только один класс. Мы всегда должны вызывать конструктор суперкласса.
Это важное преимущество интерфейсов над классами. В этой статье я показал, как его можно использовать в шаблоне, называемом трейтами или примесями: