Как создать объект абстрактного класса c
Кроме обычных классов в C# есть абстрактные классы . Зачем они нужны? Классы обычно представляют некий план определенного рода объектов или сущностей. Например, мы можем определить класс Car для преставления машин или класс Person для представления людей, вложив в эти классы соответствующие свойства, поля, методы, которые будут описывать данные объекты. Однако некоторые сущности, которые мы хотим выразить с помощью языка программирования, могут не иметь конкретного воплощения. Например, в реальности не существует геометрической фигуры как таковой. Есть круг, прямоугольник, квадрат, но просто фигуры нет. Однако же и круг, и прямоугольник имеют что-то общее и являются фигурами. И для описания подобных сущностей, которые не имеют конкретного воплощения, предназначены абстрактные классы.
Абстрактный класс похож на обычный класс. Он также может иметь переменные, методы, конструкторы, свойства. Единственное, что при определении абстрактных классов используется ключевое слово abstract . Например, определим абстрактный класс, который представляет некое транспортное средство:
Транспортное средство представляет некоторую абстракцию, которая не имеет конкретного воплощения. То есть есть легковые и грузовые машины, самолеты, морские судна, кто-то на космическом корабле любит покататься, но как такового транспортного средства нет. Тем не менее все транспортные средства имеют нечто общее — они могут перемещаться. И для этого в классе определен метод Move, который эмулирует перемещение.
Но главное отличие абстрактных классов от обычных состоит в том, что мы НЕ можем использовать конструктор абстрактного класса для создания экземпляра класса. Например, следующим образом:
Тем не менее абстрактные классы полезны для описания некоторого общего функционала, который могут наследовать и использовать производные классы:
В данном случае от класса Transport наследуются три класса, которые представляют различные типы транспортных средств. Тем не менее они имеют общую черту — они могут перемещаться с помощью метода Move() .
Выше писалось, что мы не можем использовать конструктор абстрактного класса для создания экземпляра этого класса. Тем не менее такой класс также может определять конструкторы:
В данном случае в абстрактном классе Transport определен конструктор — с помощью параметра он устанавливает значение свойства Name, которое хранит название транспортного средства. И в этом случае производные классы должны в своих конструкторах вызвать этот конструктор.
Абстрактные члены классов
Кроме обычных свойств и методов абстрактный класс может иметь абстрактные члены классов, которые определяются с помощью ключевого слова abstract и не имеют никакого функционала. В частности, абстрактными могут быть:
Абстрактные члены классов не должны иметь модификатор private. При этом производный класс обязан переопределить и реализовать все абстрактные методы и свойства, которые имеются в базовом абстрактном классе. При переопределении в производном классе такой метод или свойство также объявляются с модификатором override (как и при обычном переопределении виртуальных методов и свойств). Также следует учесть, что если класс имеет хотя бы одный абстрактный метод (или абстрактные свойство, индексатор, событие), то этот класс должен быть определен как абстрактный .
Абстрактные члены также, как и виртуальные, являются частью полиморфного интерфейса. Но если в случае с виртуальными методами мы говорим, что класс-наследник наследует реализацию, то в случае с абстрактными методами наследуется интерфейс, представленный этими абстрактными методами.
Абстрактные методы
Например, выше в примере с транспортными средствами метод Move описывает передвижение транспортного средства. Однако различные типы транспорта перемещаются по разному — ездят по земле, летят по воздуху, плывут на воде и т.д. В этом случае мы можем сделать метод Move абстрактным, а его реализацию переложить на производные классы:
Абстрактные свойства
Следует отметить использование абстрактных свойств. Их определение похоже на определение автосвойств. Например:
В классе Transport определено абстрактное свойство Speed, которое должно хранить скорость транспортного средства. Оно похоже на автосвойство, но это не автосвойство. Так как данное свойство не должно иметь реализацию, то оно имеет только пустые блоки get и set. В производных классах мы можем переопределить это свойство, сделав его полноценным свойством (как в классе Ship), либо же сделав его автоматическим (как в классе Aircraft).
Отказ от реализации абстрактных членов
Производный класс обязан реализовать все абстрактные члены базового класса. Однако мы можем отказаться от реализации, но в этом случае производный класс также должен быть определен как абстрактный:
В данном случае класс Car не реализует абстрактный метод Move базового класса Transport и поэтому также определен как абстрактный. Однако любые неабстрактные классы, производные от Car, все равно должны реализовать все унаследованные абстрактные методы и свойства.
Пример абстрактного класса
Xрестоматийным примером является система геометрических фигур. В реальности не существует геометрической фигуры как таковой. Есть круг, прямоугольник, квадрат, но просто фигуры нет. Однако же и круг, и прямоугольник имеют что-то общее и являются фигурами:
Как создать объект абстрактного класса c
Abstraction in C# is the process to hide the internal details and show only the functionality. The abstract modifier indicates the incomplete implementation. The keyword abstract is used before the class or method to declare the class or method as abstract. Also, the abstract modifier can be used with indexers, events, and properties.
Example:
Abstract Method: A method that is declared abstract, has no “body” and is declared inside the abstract class only. An abstract method must be implemented in all non-abstract classes using the override keyword. After overriding, the abstract method is in the non-Abstract class. We can derive this class in another class, and again we can override the same abstract method with it.
Syntax:
Abstract Class: This is the way to achieve the abstraction in C#. An Abstract class is never intended to be instantiated directly. An abstract class can also be created without any abstract methods, We can mark a class abstract even if doesn’t have any abstract method. The Abstract classes are typically used to define a base class in the class hierarchy. Or in other words, an abstract class is an incomplete class or a special class we can’t be instantiated. The purpose of an abstract class is to provide a blueprint for derived classes and set some rules that the derived classes must implement when they inherit an abstract class. We can use an abstract class as a base class and all derived classes must implement abstract definitions.
Syntax:
Important Points:
- Generally, we use abstract class at the time of inheritance.
- A user must use the override keyword before the method is declared as abstract in the child class, the abstract class is used to inherit in the child class.
- An abstract class cannot be inherited by structures.
- It can contain constructors or destructors.
- It can implement functions with non-Abstract methods.
- It cannot support multiple inheritances.
- It can’t be static.
Example 1: Program to show the working of an abstract class
Абстрактные классы

Иногда требуется создать базовый класс, в котором определяется лишь самая общая форма для всех его производных классов, а наполнение ее деталями предоставляется каждому из этих классов. В таком классе определяется лишь характер методов, которые должны быть конкретно реализованы в производных классах, а не в самом базовом классе. Подобная ситуация возникает, например, в связи с невозможностью получить содержательную реализацию метода в базовом классе.
Создавая собственные библиотеки классов, вы можете сами убедиться в том, что у метода зачастую отсутствует содержательное определение в контексте его базового класса. Подобная ситуация разрешается двумя способами. Один из них состоит в том, чтобы просто выдать предупреждающее сообщение. Такой способ может пригодиться в определенных ситуациях, например при отладке, но в практике программирования он обычно не применяется. В подобных случаях требуется какой-то способ, гарантирующий, что в производном классе действительно будут переопределены все необходимые методы. И такой способ в C# имеется. Он состоит в использовании абстрактного метода.
Абстрактный метод создается с помощью указываемого модификатора типа abstract. У абстрактного метода отсутствует тело, и поэтому он не реализуется в базовом классе. Это означает, что он должен быть переопределен в производном классе, поскольку его вариант из базового класса просто непригоден для использования. Нетрудно догадаться, что абстрактный метод автоматически становится виртуальным и не требует указания модификатора virtual. В действительности совместное использование модификаторов virtual и abstract считается ошибкой. Для определения абстрактного метода служит приведенная ниже общая форма:
abstract тип имя(список_параметров);
Как видите, у абстрактного метода отсутствует тело. Модификатор abstract может применяться только в методах экземпляра, но не в статических методах (static). Абстрактными могут быть также индексаторы и свойства.
Класс, содержащий один или больше абстрактных методов, должен быть также объявлен как абстрактный, и для этого перед его объявлением class указывается модификатор abstract. А поскольку реализация абстрактного класса не определяется полностью, то у него не может быть объектов. Следовательно, попытка создать объект абстрактного класса с помощью оператора new приведет к ошибке во время компиляции!
Когда производный класс наследует абстрактный класс, в нем должны быть реализованы все абстрактные методы базового класса. В противном случае производный класс должен быть также определен как abstract. Таким образом, атрибут abstract наследуется до тех пор, пока не будет достигнута полная реализация класса.
В данном примере создается абстрактный класс UserInfo в котором инкапсулируется абстрактный метод ui(), который, в свою очередь, переопределяется в классе UserFamily.
Следует отметить, что в абстрактные классы вполне допускается (и часто практикуется) включать конкретные методы, которые могут быть использованы в своем исходном виде в производном классе. А переопределению в производных классах подлежат только те методы, которые объявлены как abstract.
Абстрактный класс. Основные понятия. Ключевое слово abstract . Примеры
Бывают случаи, когда нужно создать наиболее общую форму базового класса, которая будет наполняться деталями в производных (унаследованных) классах. В таком случае элементы базового класса (методы, свойства и т.п.) носят весьма неопределенный характер и реализовывать их не имеет смысла. Классы, содержащие элементы без конкретной реализации, называются абстрактными. В абстрактном классе объявляется только общий характер элемента, который будет наполняться содержанием в унаследованных классах.
Абстрактный класс – это класс, в котором объявлен хотя бы один абстрактный элемент (метод, свойство). Если в абстрактном классе объявлен абстрактный элемент, (метод, свойство) то перед именем такого класса ставится ключевое слово abstract. Если в производном классе нужно определить конкретную реализацию элемента (метода, свойства) абстрактного класса, то при объявлении элемента указывается ключевое слово override .
Абстрактный класс предусматривает использование его как базового для других унаследованных классов. В свою очередь, унаследованный класс должен реализовать все абстрактные элементы базового абстрактного класса. Если, по какой-то причине в унаследованном классе не нужно реализовывать элементы абстрактного класса, то такой класс также нужно объявить как абстрактный.
Например. Пусть нужно разработать базовый класс Figure , что описывает некоторую фигуру. Из этого класса должны быть унаследованы более конкретные реализации фигур: треугольник ( Triangle ), круг ( Circle ), прямоугольник ( Rectangle ) как изображено на рисунке 1.
Пусть в иерархию классов нужно ввести метод Area() , определяющий площадь фигуры. В базовом классе Figure и производных классах, метод Area() использует механизм полиморфизма при его вызове.
Реализация метода Area() в производных классах ( Triangle , Circle , Rectangle ) есть понятной. Для любого из этих производных классов существует свой способ определения площади. Однако, невозможно определить площадь для метода Area() базового класса Figure , поскольку, на этом этапе еще не известно для какой фигуры нужно вычислять площадь. Поэтому, реализация (тело) метода Area() не имеет смысла. Такой метод целесообразно объявлять как абстрактный с ключевым словом abstract . Автоматически, класс Figure также становится абстрактным.

Рисунок 1. Необходимость использования абстрактных классов.
Метод Area() в классе Figure есть абстрактным
2. Общая форма объявления абстрактного класса. Ключевое слово abstract
Чтобы объявить абстрактный класс нужно использовать ключевое слово abstract . В простейшем случае общая форма объявления абстрактного класса с именем ClassName следующая
Согласно синтаксису C# перед ключевым словом abstract может использоваться модификатор доступа public или internal .
3. Какие элементы класса могут быть абстрактными? Пример
С ключевым словом abstract можно объявлять:
- методы;
- свойства;
- индексаторы;
- события.
Нельзя объявить абстрактное поле (переменную) класса.
Пример. В примере демонстрируется объявление разных абстрактных элементов класса.
4. Что такое абстрактный метод? Общая форма объявления абстрактного метода
Абстрактный метод – это метод, в котором отсутствует реализация. Абстрактный метод не содержит тела метода. Для абстрактного метода задается только его сигнатура: возвращаемый тип, имя и список параметров.
Общая форма объявления абстрактного метода:
- MethodName – имя метода.
- access_modifier – один из модификаторов доступа protected , public , internal , protected internal ;
- return_type – тип, возвращаемый методом;
- parameters – список параметров метода.
5. Общая форма объявления абстрактного свойства
Общая форма объявления абстрактного свойства
- PropName – имя свойства;
- access_modifier – один из модификаторов доступа кроме модификатора private ;
- return_type – тип свойства.
Как и в случае обычного свойства, спецификаторы доступа get или set могут отсутствовать.
6. Общая форма объявления абстрактного индексатора
В C# допускается использование абстрактных индексаторов. Общая форма объявления абстрактного индексатора следующая:
- access_modifier – один из модификаторов доступа кроме модификатора private ;
- return_type – тип индексатора;
- type_index – тип индекса, по которому получается значение по индексатору;
- index – имя переменной-индекса.
Абстрактный индексатор должен содержать по крайней мере один из спецификаторов get или set .
7. Общая форма объявления абстрактного события
Чтобы объявить абстрактное событие предварительно должен быть объявлен тип делегата для этого события. Общая форма объявления абстрактного события следующая:
- access_modifier – один из модификаторов доступа: public , protected , internal или protected_internal ;
- eventName – имя абстрактного события;
- Delegate_Type – тип делегата.
Тип делегата Delegate_Type объявляется как
- Delegate_Type – имя типа делегата;
- return_type – тип, возвращаемый делегатом;
- parameters – параметры делегата.
8. Какие ограничения накладываются на абстрактные классы и их экземпляры?
На абстрактные классы накладываются следующие ограничения:
- абстрактный класс не может быть статическим ( static );
- абстрактный класс не может быть запечатанным ( sealed );
- невозможно создать экземпляр (объект) абстрактного класса.
9. Можно ли в абстрактном классе объявлять не абстрактные элементы?
Да, можно. В абстрактном классе можно объявлять любые не абстрактные элементы, которые обычно объявляются в классах (поля данных, методы, свойства, индексаторы и т.д.).
10. Можно ли использовать конструкторы в абстрактном классе?
В абстрактном классе допускается использование конструкторов. Хотя экземпляр абстрактного класса создать не удастся. Конструкторы в абстрактном классе необходимы для реализации начальной инициализации внутренних полей абстрактного класса (если такие есть). Эти конструкторы вызываются с помощью ключевого слова base в производных классах. Более подроно об особенностях использования ключевого слова base в конструкторах производных классов описывается здесь .
11. Какие ограничения накладываются на абстрактные элементы класса (методы, свойства)?
Абстрактные элементы класса – это элементы, которые объявлены с ключевым словом abstract . На абстрактные элементы (методы, свойства, индексаторы, события) накладываются следующие ограничения:
- абстрактный элемент не может быть private . Допускается объявлять абстрактный метод с любым другим модификатором доступа: public , protected , internal , protected internal ;
- абстрактный элемент не должен иметь реализации;
- абстрактный элемент (элемент, обозначенный как abstract ) не может быть обозначен ключевым словом virtual . Это естественно, поскольку для обеспечения использования полиморфизма достаточно ключевого слова abstract .
12. Может ли абстрактный класс не содержать объявления абстрактных элементов?
Да, может. Компилятор C# допускает объявление класса с ключевым словом abstract в котором нет абстрактных элементов.
Такое свойство есть полезным, когда на начальном этапе разработки программы еще до конца не известно перечень всех элементов класса, находящегося в вершине иерархии. Однако уже понятно, что при дальнейшей разработке (развитии) программы, этот класс будет содержать абстрактные элементы, а, значит, должен быть абстрактным.
Например. В начале разработки иерархии классов вводится абстрактный класс-заглушка. В данном примере объявляется класс с именем BaseAbstractClass
13. Рисунок, демонстрирующий использование абстрактного класса

Рисунок 2. Пример использования абстрактного класса
14. Может ли абстрактный класс наследовать другой абстрактный класс? Может ли абстрактный класс наследовать другой не абстрактный класс?
Да. Абстрактный класс может наследовать как абстрактный, так и не абстрактный класс. В этом случае действуют правила наследования такие же как при наследовании не абстрактных классов. Во всей цепи иерархии абстрактные и не абстрактные классы могут поочередно наследовать друг друга.
Пример. Нижеследующий пример демонстрирует свободу в использовании абстрактных классов в сочетании с неабстрактными.
15. Различия между абстрактными классами и интерфейсами
Между интерфейсами и абстрактными классами были замечены следующие различия: