Я изучаю С++, но я смущен абстрактным классом и конкретным классом. Некоторые примеры в реальном мире будут оценены.
В чем разница между конкретным классом и абстрактным классом?
Ответ 1
Абстрактный класс - это класс, для которого один или несколько методов объявлены, но не определены, что означает, что компилятор знает, что эти методы являются частью класса, но не для того, какой код выполнить для этого метода. Они называются абстрактными методами. Вот пример абстрактного класса.
class shape {
public:
virtual void draw() = 0;
};
Это объявляет абстрактный класс, который указывает, что любые потомки класса должны реализовать метод draw, если класс должен быть конкретным. Вы не можете создать экземпляр этого класса, потому что он абстрактный, в конце концов, компилятор не знает, какой код выполнить, если вы вызвали элемент draw. Поэтому вы не можете сделать следующее:
shape my_shape();
my_shape.draw();
Чтобы иметь возможность использовать метод draw, вам нужно будет вывести классы из этого абстрактного класса, которые реализуют метод 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)
Этот код позволяет собирать все фигуры в один контейнер. Это делает его намного проще, если у вас много фигур и много разных фигур в вашей сцене. Например, теперь мы можем рисовать все фигуры за один раз, а код, который это делает, даже не нужно знать о различных типах форм, которые у нас есть.
Теперь, наконец, нам нужно знать, почему функция рисования формы является абстрактной, а не просто пустой функцией, то есть почему мы не просто определили:
class shape {
public:
virtual void draw() {
/* do nothing */
}
};
Причиной этого является то, что мы действительно не хотим объектов типа типа, они все равно не будут реальными, они будут абстрактными. Поэтому нет смысла определять реализацию метода draw, даже пустого. Создание абстрактного класса формы препятствует нам ошибочно создавать экземпляр класса формы или ошибочно называть функцию пустой дроби базового класса вместо функции рисования производных классов. Фактически мы определяем интерфейс для любого класса, который хотел бы вести себя как форма, мы говорим, что любой такой класс должен иметь метод draw, который выглядит так, как мы его указали.
Чтобы ответить на последний вопрос, нет такого понятия, как "нормальный производный класс", каждый класс является абстрактным или конкретным. Класс, который имеет любые абстрактные методы, является абстрактным, любой класс, который не является конкретным. Это просто способ дифференцировать два типа классов. Базовый класс может быть абстрактным или конкретным, а производный класс может быть абстрактным или конкретным:
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 */
};
Ответ 2
Абстрактный класс не может использоваться для создания объекта. В то время как конкретный класс может быть использован для создания объекта.
Конкретный означает существующий в реальности или в реальном опыте; ощутимые чувствами; реальный ". Принимая во внимание, что абстрактный означает" не применяется или не применяется; theoritical.
Абстрактный класс не может быть создан. В то время как конкретный может быть.
Абстрактный класс - это тот, который имеет одну или несколько чистых виртуальных функций. Если конкретный класс не имеет чистых виртуальных функций.
Ответ 3
Конкретный класс - это класс, который может быть использован для создания объекта. Абстрактный класс не может использоваться для создания объекта (вы должны расширить абстрактный класс и создать конкретный класс, чтобы иметь возможность затем создать объект).
Притворись, что есть машина, которая может "штамповать" сырье и сделать машину. Стебель - это конкретный класс. Из этого мы можем создавать автомобильные объекты. Абстрактным классом были бы чертежи для шаблона. Вы не можете сделать автомобили из чертежей шаблона, вам нужно сделать класс штамповки первым из чертежей.
Ответ 4
Абсолютный класс не может быть создан в то время как конкретный может быть. Абстрактный класс служит "планом" для производных классов, которые могут быть созданы.
например. Car
class (abstract), в то время как класс Audi S4
class (исходящий из Car
) является конкретной реализацией.
Ответ 5
Многие из этих вопросов касаются следующих вопросов:
Ответ 6
Базовый класс и производный класс являются ортогональным понятием абстрактного класса по сравнению с конкретным классом.
Базовый класс - это тот, который не наследуется ни от какого другого класса. Производный класс наследует от другого класса.
Абстрактный класс - это тот, который имеет одну или несколько чистых виртуальных функций. У конкретного класса нет чистых виртуальных.
Абстрактным классом может быть либо базовый класс, либо производный класс (он получен из другого абстрактного класса). Конкретный класс также может быть либо базовым, либо производным. Вы даже можете получить абстрактный класс из конкретного класса, добавив чистую виртуальную функцию к производному классу. Но в общем случае существует один базовый абстрактный класс и один или несколько конкретных производных классов.
Ответ 7
Хорошим примером использования абстрактного класса является то, что вы строите что-то очень модульное. Скажем, вы работаете с хранилищем данных, но эти данные могут быть в базе данных MySQL, базе данных SQLite, XML файле или обычном тексте. Чтобы сохранить эту универсальность в коде, вы можете создать класс AbstractDatastore
, который определяет общедоступные методы, которые вы хотите использовать для получения информации из хранилища данных. Затем вы создаете конкретные реализации AbstractDatastore
, например XmlDatastore
, SQLiteDatastore
и т.д. Тогда ваша программа просто нуждается в получении AbstractDatastore
и что она должна иметь те функции, которые определены в AbstractDatastore
, но он не знает и не заботится о том, как данные сохраняются или извлекаются.
Ответ 8
С++ Faq Lite - отличный сайт для поиска ответов на такие вопросы.
На уровне проектирования абстрактный базовый класс (ABC) соответствует абстрактному понятию. Если вы попросите механика, если он отремонтирует транспортные средства, он, вероятно, задается вопросом, какой автомобиль вы имели в виду. Скорее всего, он не ремонтирует космические челноки, океанские лайнеры, велосипеды или атомные подводные лодки. Проблема в том, что термин "транспортное средство" является абстрактным понятием (например, вы не можете построить "транспортное средство", если не знаете, какой тип транспортного средства следует построить). В С++ класс Vehicle был бы ABC, с Bicycle, SpaceShuttle и т.д., Являясь производными классами (OceanLiner - это своего рода автомобиль). В реальном OO ABC появляются повсюду
Абстрактный класс - это класс, который имеет одну или несколько чистых виртуальных функций-членов. Вы не можете создать объект (экземпляр) абстрактного класса
class Shape {
public:
virtual void draw() const = 0; // = 0 means it is "pure virtual"
...
};
Ответ 9
В классе Concrete реализован весь его метод. Абстрактным классом является весь его метод, за исключением некоторых (по крайней мере одного) метода (ов), которые не реализованы, чтобы вы могли расширить его и реализовать не реализованный метод.
Преимущество. Расширяясь от абстрактного класса, вы получаете всю функциональность базового класса, и вы будете "вынуждены" реализовать не реализованный метод. Поэтому разработчик класса в основном заставляет вас писать код в абстрактном методе, прежде чем класс будет вам полезен.