Каково различие между реальным классом и абстрактным классом?

Я изучаю C++, но я смущен абстрактным классом и реальным классом. Некоторые примеры реального мира ценились бы.

51
задан Jagd 27 January 2010 в 08:38
поделиться

8 ответов

Абстрактный класс - это класс, для которого одно или несколько методов объявлены, но не определены, что означает, что компилятор знает, что эти методы являются частью класса, но не какой код для выполнения этого метода. Они называются абстрактными методами. Вот пример абстрактного класса.

class shape {
public:
  virtual void draw() = 0;
};

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

shape my_shape();
my_shape.draw();

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

class circle : public shape {
public:
  circle(int x, int y, int radius) {
    /* set up the circle */
  }
  virtual draw() {
    /* do stuff to draw the circle */
  }
};

class rectangle : public shape {
public:
  rectangle(int min_x, int min_y, int max_x, int max_y) {
    /* set up rectangle */
  }
  virtual draw() {
    /* do stuff to draw the rectangle */
  }
};

теперь вы можете создать Бетонные объекты круг и прямоугольник и используют их методы рисования:

circle my_circle(40, 30, 10);
rectangle my_rectangle(20, 10, 50, 15);
my_circle.draw();
my_rectangle.draw();

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

std::vector<shape*> my_scene;
my_scene.push_back(new circle(40, 30, 10));
my_scene.push_back(new rectangle(20, 10, 50, 15));
std::for_each(my_scene.begin(), my_scene.end(), std::mem_fun_ref(&shape::draw)

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

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

class shape {
public:
  virtual void draw() {
    /* do nothing */
  }
};

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

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

class abstract_base {
public:
  virtual void abstract_method1() = 0;
  virtual void abstract_method2() = 0;
};

class concrete_base {
public:
  void concrete_method1() {
    /* do something */
  }
};

class abstract_derived1 : public abstract_base {
public:
  virtual void abstract_method3() = 0;
};

class abstract_derived2 : public concrete_base {
public:
  virtual void abstract_method3() = 0;
};

class abstract_derived3 : public abstract_base {
public:
  virtual abstract_method1() {
    /* do something */
  }
  /* note that we do not provide an implementation for
     abstract_method2 so the class is still abstract */
};

class concrete_derived1 : public concrete_base {
public:
  void concrete_method2() {
    /* do something */
  }
};

class concrete_derived2 : public abstract_base {
public:
  virtual void abstract_method1() {
    /* do something */
  }
  virtual void abstract_method2() {
    /* do something */
  }
  /* This class is now concrete because no abstract methods remain */
};
97
ответ дан 7 November 2019 в 09:48
поделиться

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

E.G. Автомобиль класс (Аннотация) В то время как Audi S4 класс (вытекающий из автомобиля ) класса ) является конкретным осуществлением.

3
ответ дан 7 November 2019 в 09:48
поделиться

Хороший пример использования абстрактного класса - это когда вы строите что-то очень модульное. Допустим, вы работаете с хранилищем данных, но эти данные могут быть в базе данных MySQL, базе данных SQLite, файл XML или простой текст. Чтобы сохранить эту универсальность в вашем коде, вы можете создать класс ABSEDDATASTORE , который определяет публичные методы, которые вы хотите использовать для получения информации из DataStore. Затем вы создаете свои конкретные реализации ABSEDATASTATATASTORE , таких как XMLDASTASTASTORE , SQLITEDATATASTORE и т. Д. Затем ваша программа просто нужно знать, что он получает И что он должен иметь те функции, определенные в Абпрентадатататуре , но он не знает или не зависит от того, как данные хранятся или извлекаются.

1
ответ дан 7 November 2019 в 09:48
поделиться

Базовый класс по сравнению с производным класса - это ортогональная концепция для абстрактного класса против бетонного класса.

Базовый класс - это тот, который не наследует от любого другого класса. Полученный класс наследует от другого класса.

Абстрактный класс - это тот, который имеет одну или несколько чистых виртуальных функций. Бетонный класс не имеет чистых виртуальных.

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

1
ответ дан 7 November 2019 в 09:48
поделиться

C ++ FAQ Lite - отличный сайт, чтобы искать ответы на такие вопросы.

На уровне дизайна абстрактный базовый класс (ABC) соответствует абстрактной концепции. Если вы спросили механика, если он отремонтировал транспортные средства, он, вероятно, удивился, какой автомобиль вы имели в виду. Скорее всего, он не ремонтирует космические шаттлы, океанские лайнеры, велосипеды или атомные подводные лодки. Проблема в том, что термин «транспортное средство» является абстрактным концепцией (например, вы не можете построить «транспортное средство», если вы не знаете, какой автомобиль для сборки). В C ++ классный автомобиль будет ABC, с велосипедом, SpaceShuttle и т. Д., Быть полученными классами (океанином - это автомобиль). В реальном мире OO ABCS повсюду повсюду

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

 class Shape {
 public:
   virtual void draw() const = 0;  // = 0 means it is "pure virtual"
   ...
 }; 
0
ответ дан 7 November 2019 в 09:48
поделиться

Бетонный класс - это класс, который можно использовать для создания объекта. Абстрактный класс не может быть использован для создания объекта (вы должны продлить абстрактный класс и сделать конкретный класс, чтобы затем создать объект).

Притворись, что есть машина, которая может «штамп» сырье и сделать машину. Штампер - это бетонный класс. От этого мы можем создать автомобильные объекты. Абстрактный класс станет чертежами для струйных. Вы не можете сделать автомобили от чертежи шпеллера, вам нужно сделать класс Stamper сначала из чертежи.

20
ответ дан 7 November 2019 в 09:48
поделиться

Бетонный класс имеет весь свой метод реализован. Абстрактный класс весь свой метод, кроме некоторых (по меньшей мере, одного) метода (ы) не реализован, чтобы вы могли продлить его и внедрить нереализационный метод.

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

0
ответ дан 7 November 2019 в 09:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: