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

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

  • автор:

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

Кроме обычных классов в C# есть абстрактные классы . Зачем они нужны? Классы обычно представляют некий план определенного рода объектов или сущностей. Например, мы можем определить класс Car для преставления машин или класс Person для представления людей, вложив в эти классы соответствующие свойства, поля, методы, которые будут описывать данные объекты. Однако некоторые сущности, которые мы хотим выразить с помощью языка программирования, могут не иметь конкретного воплощения. Например, в реальности не существует геометрической фигуры как таковой. Есть круг, прямоугольник, квадрат, но просто фигуры нет. Однако же и круг, и прямоугольник имеют что-то общее и являются фигурами. И для описания подобных сущностей, которые не имеют конкретного воплощения, предназначены абстрактные классы.

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

abstract class Transport < public void Move() < Console.WriteLine("Транспортно средство движется"); >>

Транспортное средство представляет некоторую абстракцию, которая не имеет конкретного воплощения. То есть есть легковые и грузовые машины, самолеты, морские судна, кто-то на космическом корабле любит покататься, но как такового транспортного средства нет. Тем не менее все транспортные средства имеют нечто общее — они могут перемещаться. И для этого в классе определен метод Move, который эмулирует перемещение.

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

Transport tesla = new Transport();

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

Transport car = new Car(); Transport ship = new Ship(); Transport aircraft = new Aircraft(); car.Move(); ship.Move(); aircraft.Move(); abstract class Transport < public void Move() < Console.WriteLine("Транспортное средство движется"); >> // класс корабля class Ship : Transport < >// класс самолета class Aircraft : Transport < >// класс машины class Car : Transport

В данном случае от класса Transport наследуются три класса, которые представляют различные типы транспортных средств. Тем не менее они имеют общую черту — они могут перемещаться с помощью метода Move() .

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

Transport car = new Car("машина"); Transport ship = new Ship("корабль"); Transport aircraft = new Aircraft("самолет"); car.Move(); // машина движется ship.Move(); // корабль движется aircraft.Move(); // самолет движется abstract class Transport < public string Name < get; >// конструктор абстрактного класса Transport public Transport(string name) < Name = name; >public void Move() =>Console.WriteLine($" движется"); > // класс корабля class Ship : Transport < // вызываем конструктор базового класса public Ship(string name) : base(name) < >> // класс самолета class Aircraft : Transport < public Aircraft(string name) : base(name) < >> // класс машины class Car : Transport < public Car(string name) : base(name) < >>

В данном случае в абстрактном классе Transport определен конструктор — с помощью параметра он устанавливает значение свойства Name, которое хранит название транспортного средства. И в этом случае производные классы должны в своих конструкторах вызвать этот конструктор.

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

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

  • Методы
  • Свойства
  • Индексаторы
  • События

Абстрактные члены классов не должны иметь модификатор private. При этом производный класс обязан переопределить и реализовать все абстрактные методы и свойства, которые имеются в базовом абстрактном классе. При переопределении в производном классе такой метод или свойство также объявляются с модификатором override (как и при обычном переопределении виртуальных методов и свойств). Также следует учесть, что если класс имеет хотя бы один абстрактный метод (или абстрактные свойство, индексатор, событие), то этот класс должен быть определен как абстрактный .

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

Абстрактные методы

Например, выше в примере с транспортными средствами метод Move описывает передвижение транспортного средства. Однако различные типы транспорта перемещаются по разному — ездят по земле, летят по воздуху, плывут на воде и т.д. В этом случае мы можем сделать метод Move абстрактным, а его реализацию переложить на производные классы:

abstract class Transport < public abstract void Move(); >// класс корабля class Ship : Transport < // мы должны реализовать все абстрактные методы и свойства базового класса public override void Move() < Console.WriteLine("Корабль плывет"); >> // класс самолета class Aircraft : Transport < public override void Move() < Console.WriteLine("Самолет летит"); >> // класс машины class Car : Transport < public override void Move() < Console.WriteLine("Машина едет"); >>
Transport car = new Car(); Transport ship = new Ship(); Transport aircraft = new Aircraft(); car.Move(); // машина едет ship.Move(); // корабль плывет aircraft.Move(); // самолет летит
Абстрактные свойства

Следует отметить использование абстрактных свойств. Их определение похоже на определение автосвойств. Например:

abstract class Transport < // абстрактное свойство для хранения скорости public abstract int Speed < get; set; >> // класс корабля class Ship: Transport < int speed; public override int Speed < get =>speed; set => speed = value; > > class Aircraft : Transport < public override int Speed < get; set; >>

В классе Transport определено абстрактное свойство Speed, которое должно хранить скорость транспортного средства. Оно похоже на автосвойство, но это не автосвойство. Так как данное свойство не должно иметь реализацию, то оно имеет только пустые блоки get и set. В производных классах мы можем переопределить это свойство, сделав его полноценным свойством (как в классе Ship), либо же сделав его автоматическим (как в классе Aircraft).

Отказ от реализации абстрактных членов

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

Transport tesla = new Auto(); tesla.Move(); // легковая машина едет abstract class Transport < public abstract void Move(); >// класс машины abstract class Car : Transport<> class Auto: Car < public override void Move() < Console.WriteLine("легковая машина едет"); >>

В данном случае класс Car не реализует абстрактный метод Move базового класса Transport и поэтому также определен как абстрактный. Однако любые неабстрактные классы, производные от Car, все равно должны реализовать все унаследованные абстрактные методы и свойства.

Пример абстрактного класса

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

// абстрактный класс фигуры abstract class Shape < // абстрактный метод для получения периметра public abstract double GetPerimeter(); // абстрактный метод для получения площади public abstract double GetArea(); >// производный класс прямоугольника class Rectangle : Shape < public float Width < get; set; >public float Height < get; set; >// переопределение получения периметра public override double GetPerimeter() => Width * 2 + Height * 2; // переопрелеление получения площади public override double GetArea() => Width * Height; > // производный класс окружности class Circle : Shape < public double Radius < get; set; >// переопределение получения периметра public override double GetPerimeter() => Radius * 2 * 3.14; // переопрелеление получения площади public override double GetArea() => Radius * Radius * 3.14; >
var rectanle = new Rectangle < Width = 20, Height = 20 >; var circle = new Circle < Radius = 200 >; PrintShape(rectanle); // Perimeter: 80 Area: 400 PrintShape(circle); // Perimeter: 1256 Area: 125600 void PrintShape(Shape shape) < Console.WriteLine($"Perimeter: Area: "); >

не удается создать экземпляр абстрактного класса или интерфейса «Item» c#

Всё правильно. По законам ООП нельзя создавать экземпляры абстрактного класса. Это как создать человека из мысли о человеке.

Отслеживать
ответ дан 28 мая 2021 в 20:05
Алексей Шиманский Алексей Шиманский
73.5k 12 12 золотых знаков 93 93 серебряных знака 182 182 бронзовых знака
тем не менее, в лабораторной просят сделать именно так «Реализуйте класс Item как абстрактный»
28 мая 2021 в 20:06

@ававава да ради бога. Только вот создавать надо из реального класса. Т.е. нужно создать ещё класс, который наследуется от абстрактного и уже создавать экземпляр этого самого класса, а не абстрактного

28 мая 2021 в 20:08

Под «реализуйте класс Item как абстрактный» имеется ввиду добавить абстрактный класс Item с некоторыми его членами. Не нужно создавать экземпляр абстрактного класса (этого делать нельзя).

2 ноя 2023 в 6:27
@Danila вы это кому написали?))
2 ноя 2023 в 16:51
@АлексейШиманский, я написал @ав….
4 ноя 2023 в 7:59

не удается создать экземпляр абстрактного класса

/*abstract*/ class Item 

Вслушайтесь в эти слова: «Тиха украинская ночь, прозрачно небо . «

Отслеживать
ответ дан 28 мая 2021 в 20:05
user176262 user176262
тем не менее, в лабораторной просят сделать именно так «Реализуйте класс Item как абстрактный»
28 мая 2021 в 20:06
@ававава Мне сквозь компьютер плохо видно Вашу лабораторную.
– user176262
28 мая 2021 в 20:57

Что бы создать объект класса, класс должен быть не абстрактным. Просто создайте новый класс, которые является наследником Item .

Отслеживать
ответ дан 28 мая 2021 в 20:32
iikuzmychov iikuzmychov
3,092 2 2 золотых знака 11 11 серебряных знаков 28 28 бронзовых знаков
а что я туда должен написать?
28 мая 2021 в 20:34
@ававава class ItemA : Item
28 мая 2021 в 20:35
@ававава а вы можете добавить в ответ всё задание текстом?
28 мая 2021 в 20:36

Реализуйте класс Item как абстрактный  Добавьте ключевое слово abstract при объявлении класса abstract class Item Производные классы не обязаны переопределять виртуальные методы, но если требуется обязать переопределять виртуальный метод, то его следует сде- лать абстрактным. Методы, помеченные как abstract, являются чистым прото- колом: они просто определяют имя, возвращаемый тип (если есть), и набор па- раметров (при необходимости).Реализуйте метод Return как абстрактный  Добавьте ключевое слово abstract при объявлении метода Return базового класса и удалите тело класса:

28 мая 2021 в 20:39

abstract public void Return();  Протестируйте вызов абстрактного метода  В методе Main класса Program вызовите абстрактный метод: 53 Item it; it = b2; it.TakeItem(); it.Return(); it.Show(); it = mag1; it.TakeItem(); it.Return(); it.Show();

C ++ — Интерфейсы (абстрактные классы)

Интерфейс описывает поведение или возможности класса C ++, не связываясь с конкретной реализацией этого класса.

Интерфейсы C ++ реализуются с использованием абстрактных классов,и эти абстрактные классы не следует путать с абстракцией данных, которая представляет собой концепцию сохранения деталей реализации отдельно от связанных данных.

Класс делается абстрактным, объявляя хотя бы одну из своих функций чистой виртуальной функцией. Чистая виртуальная функция задается путем размещения в объявлении «= 0» следующим образом:

class Box < public: // pure virtual function virtual double getVolume() = 0; private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box >;

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

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

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

Пример абстрактного класса

Рассмотрим следующий пример, когда родительский класс предоставляет интерфейс базовому классу для реализации функции getArea ()

#include using namespace std; // Base class class Shape < public: // pure virtual function providing interface framework. virtual int getArea() = 0; void setWidth(int w) < width = w; >void setHeight(int h) < height = h; >protected: int width; int height; >; // Derived classes class Rectangle: public Shape < public: int getArea() < return (width * height); >>; class Triangle: public Shape < public: int getArea() < return (width * height)/2; >>; int main(void) < Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // Print the area of the object. cout 

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Total Rectangle area: 35 Total Triangle area: 17

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

Стратегия проектирования

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

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

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

C ++ - Интерфейсы (абстрактные классы)

Интерфейс описывает поведение или возможности класса C ++, не связываясь с конкретной реализацией этого класса.

Интерфейсы C ++ реализуются с использованием абстрактных классов,и эти абстрактные классы не следует путать с абстракцией данных, которая представляет собой концепцию сохранения деталей реализации отдельно от связанных данных.

Класс делается абстрактным, объявляя хотя бы одну из своих функций чистой виртуальной функцией. Чистая виртуальная функция задается путем размещения в объявлении «= 0» следующим образом:

class Box < public: // pure virtual function virtual double getVolume() = 0; private: double length; // Length of a box double breadth; // Breadth of a box double height; // Height of a box >;

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

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

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

Пример абстрактного класса

Рассмотрим следующий пример, когда родительский класс предоставляет интерфейс базовому классу для реализации функции getArea () -

#include using namespace std; // Base class class Shape < public: // pure virtual function providing interface framework. virtual int getArea() = 0; void setWidth(int w) < width = w; >void setHeight(int h) < height = h; >protected: int width; int height; >; // Derived classes class Rectangle: public Shape < public: int getArea() < return (width * height); >>; class Triangle: public Shape < public: int getArea() < return (width * height)/2; >>; int main(void) < Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // Print the area of the object. cout 

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Total Rectangle area: 35 Total Triangle area: 17

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

Стратегия проектирования

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

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

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

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

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