Как создать объект абстрактного класса c
Перейти к содержимому

Как создать объект абстрактного класса c

Абстрактные и запечатанные классы и члены классов (Руководство по программированию на C#)

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

Ключевое слово sealed позволяет предотвратить наследование класса или определенных членов класса, помеченных ранее как virtual.

Абстрактные классы и члены классов

Классы могут быть объявлены абстрактными путем помещения ключевого слова abstract перед определением класса. Пример:

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

Абстрактные классы могут определять абстрактные методы. Для этого перед типом возвращаемого значения метода необходимо поместить ключевое слово abstract . Пример:

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

Если метод virtual объявляется как abstract , он все равно считается виртуальным по отношению к любому классу, наследующему от абстрактного класса. Класс, наследующий абстрактный метод, не может получать доступ к исходной реализации метода (так, в предыдущем примере DoWork для класса F не может вызывать DoWork для класса D). Таким образом, абстрактный класс может принудительно задавать необходимость предоставлять новые реализации виртуальных методов в производных классах.

Запечатанные классы и члены классов

Классы могут быть объявлены как запечатанные путем помещения ключевого слова перед определением класса. Пример:

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

Метод, индексатор, свойство или событие для производного класса, переопределяющего виртуальный член базового класса, может объявлять этот член как запечатанный. Это делает бесполезным виртуальный аспект члена для каждого последующего производного класса. Для этого в объявлении члена класса необходимо перед ключевым словом sealed поместить ключевое слово sealed . Пример:

Что такое абстрактный класс в С++

user avatar

Абстрактный класс в C++ — это класс, в котором объявлена хотя бы одна чисто виртуальная функция.

Описание

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

Но возникает возможность создать абстрактный класс, что противоречит архитектуре: как «выделанная общая часть» может быть полноценным классом? Ответ: никак, надо запретить создавать подобный класс. Для этого указывают один из методов как чистый виртуальный ( pure virtual method ), пример для С++:

тем самым заставляя классы наследники определить реализацию для данного метода. Понятное дело, что такое «ограничение» вызывает зависимость и бьет по гибкости, поэтому в 90% случаев таким методом делают деструктор, так как кто-кто, а деструктор в классах, где есть наследование и виртуальные методы нужен всегда. Но не стоит забывать, что при вызове деструктора класс вызывает все деструкторы своих родителей, и поэтому мы объязаны написать реализацию деструктора, в случае определения его как чисто виртуального в абстрактном классе:

Класс или его наследник перестаёт быть для компилятора абстрактным и экземпляр такого класса может быть создан, как только определена реализация для каждого pure virtual method.

Отличие от интерфейса

Так как понятия «интерфейс» и «абстрактный класс» путают, приведу их отличия:

  1. Каждый интерфейс является абстрактным классом, не каждый абстрактный класс — интерфейс (прим. #1).
  2. Интерфейс содержит только public секцию, абстрактный класс не имеет ограничений.
  3. Интерфейс содержит только pure virtual methods, абстрактный класс может содержать и поля, и обычные методы в добавок.
  4. Интерфейс реализуют, абстрактный класс наследуют (для С++ прим. #1)

Примечение #1: так как в С++ нету понятия интерфейс на уровне языка, то программисты симулируют его поведение через абстрактный класс, наследуя его.

Пример

Интересный, как по мне, способ использовать абстрактный класс в связке с этим паттерном Template Method Design Pattern.

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

XYZ School

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

Создавая собственные библиотеки классов, вы можете сами убедиться в том, что у метода зачастую отсутствует содержательное определение в контексте его базового класса. Подобная ситуация разрешается двумя способами. Один из них состоит в том, чтобы просто выдать предупреждающее сообщение. Такой способ может пригодиться в определенных ситуациях, например при отладке, но в практике программирования он обычно не применяется. В подобных случаях требуется какой-то способ, гарантирующий, что в производном классе действительно будут переопределены все необходимые методы. И такой способ в C# имеется. Он состоит в использовании абстрактного метода.

Абстрактный метод создается с помощью указываемого модификатора типа abstract. У абстрактного метода отсутствует тело, и поэтому он не реализуется в базовом классе. Это означает, что он должен быть переопределен в производном классе, поскольку его вариант из базового класса просто непригоден для использования. Нетрудно догадаться, что абстрактный метод автоматически становится виртуальным и не требует указания модификатора virtual. В действительности совместное использование модификаторов virtual и abstract считается ошибкой. Для определения абстрактного метода служит приведенная ниже общая форма:

abstract тип имя(список_параметров);

Как видите, у абстрактного метода отсутствует тело. Модификатор abstract может применяться только в методах экземпляра, но не в статических методах (static). Абстрактными могут быть также индексаторы и свойства.

Класс, содержащий один или больше абстрактных методов, должен быть также объявлен как абстрактный, и для этого перед его объявлением class указывается модификатор abstract. А поскольку реализация абстрактного класса не определяется полностью, то у него не может быть объектов. Следовательно, попытка создать объект абстрактного класса с помощью оператора new приведет к ошибке во время компиляции!

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

В данном примере создается абстрактный класс UserInfo в котором инкапсулируется абстрактный метод ui(), который, в свою очередь, переопределяется в классе UserFamily.

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

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

Ваш адрес email не будет опубликован.