Фрагмент для ознакомления
2
Фундаментальное отличие между интерфейсом и абстрактным классом заключается в том, что интерфейс определяет исключительно поведение, не раскрывая информации о том, какой именно объект его реализует. Например, такое поведение, как «движение», может быть применимо к самым различным объектам: автомобилю, коту, финансовым котировкам и т.д. Эти объекты не имеют ничего общего, кроме факта, что способны двигаться.
Если представить это поведение в коде на Java, то мы увидим, что интерфейс обеспечивает лишь контракт, который не позволяет однозначно определить, к какому именно типу объекта он относится. Это может быть как машина, так и кот, или же другие варианты.
Абстрактный класс служит для описания определенного абстрактного объекта, такого как автомобиль, человек или кот, и не ограничивается лишь поведенческими характеристиками [4]. Если говорить об абстрактном классе "автомобиль", то у нас возникают ассоциации с предметом, который обладает определенными характеристиками, такими как двигатель и колеса, а также может выполнять действия, такие как движение, поворот, ускорение и торможение. Мы сразу же можем представить, что автомобиль включает поля для хранения его внутренних компонентов, таких как мотор, колеса и тормоза. Слово "автомобиль" само по себе вызывает четкие образы и ассоциации.
В то же время, такие сущности, как кот или котировка валют, не относятся к классу "автомобиль", несмотря на то что они могут также передвигаться. На основе этого понимания можем создать класс Automobile:
Интерфейс и абстрактный класс представляют собой разные концепции, которые нельзя заменять друг другом. Даже если абстрактный класс с абстрактными методами выглядит как интерфейс, и в то время как интерфейс с методами по умолчанию напоминает абстрактный класс с реализациями методов, это все равно остаются две принципиально различных категории. Если требуется поведение, правильным решением будет использование интерфейса. В случаях, когда необходимо описать концептуальный объект, следует применять абстрактный класс.
Теперь обсудим технические отличия этих двух понятий. В данной части мы сосредоточимся на синтаксических различиях при реализации в языке Java. Обычно именно это и делают при обсуждении разницы между интерфейсами и абстрактными классами, однако для нас это всего лишь вторая часть ответа, не обладающая главенствующим значением [4].
Что касается синтаксиса, создание абстрактного класса предполагает использование ключевого слова abstract, тогда как для определения интерфейса применяется слово interface.
Пример абстрактного класса:
Пример интерфейса:
Синтаксис использования. При наследовании от абстрактного класса используется ключевое слово extends (с англ. «расширяет»), а при реализации интерфейса — implements (с англ. «реализует»).
В приведенном ниже коде класс MyClass расширяет MyAbstractClass:
А тут класс MyClass реализует интерфейс MyInterface:
Класс может одновременно и наследоваться от абстрактного класса (только одного) и реализовать один или множество интерфейсов [4].
Например, класс MyClass реализует интерфейс MyInterface, MyInterface_2 и MyInterface_3:
Наличие конструктора. Как вы знаете, невозможно создать экземпляр абстрактного класса. Но, объявить и определить в нем конструктор мы можем. В противном случае за нас это сделает компилятор, создав конструктор по умолчанию. Без него код просто не скомпилируется, поскольку при создании конкретного класса первым оператором будет неявный вызов super() конструктора суперкласса, в данном случае абстрактного [4].
Добавим в абстрактный класс MyAbstractClass конструктор:
Также добавим конструктор в MyClass:
В классе Main создадим объект и запустим программу:
Результат выполнения программы:
Для интерфейсов понятия «конструктор» не существует.
Типы переменных. Все переменные в интерфейсах неявно являются public static final (т.е. константами). «final» подразумевает, что переменной обязательно должно быть присвоено значение во время инициализации.