c++ - tienen - ¿Cuál es la diferencia entre una clase concreta y una clase abstracta?
que es una clase abstracta en poo (9)
Estoy aprendiendo C ++, pero estoy confundido acerca de la clase abstracta y la clase concreta. Algunos ejemplos del mundo real serían apreciados.
La clase base frente a la clase derivada es un concepto ortogonal para la clase abstracta frente a la clase concreta.
Una clase base es aquella que no hereda de ninguna otra clase. Una clase derivada hereda de otra clase.
Una clase abstracta es aquella que tiene una o más funciones virtuales puras. Una clase concreta no tiene virtuales puros.
Una clase abstracta puede ser una clase base o una clase derivada (se deriva de otra clase abstracta). Una clase concreta también puede ser base o derivada. Incluso puede derivar una clase abstracta de una clase concreta, agregando una función virtual pura a la clase derivada. Pero en el uso general, hay una clase abstracta base y una o más clases derivadas concretas.
La clase concreta tiene todo su método implementado. Clase abstracta, todo su método, excepto algunos (al menos uno) método (s) no implementado para que pueda extenderlo e implementar el método no implementado.
Ventaja: Al extenderse desde la clase abstracta, obtienes toda la funcionalidad de la clase base y serás ''forzado'' a implementar el método no implementado. Entonces, el diseñador de la clase básicamente te obliga a escribir código en el método abstracto antes de que la clase te sea útil.
Mucho de esto cubierto en estas otras preguntas:
Un buen ejemplo de usar una clase abstracta es cuando estás construyendo algo muy modular. Supongamos que está trabajando con un almacén de datos, pero esos datos podrían estar en una base de datos MySQL, una base de datos SQLite, un archivo XML o un texto plano. Para mantener esta versatilidad en su código, puede crear una clase AbstractDatastore
que defina los métodos públicos que desea usar para obtener información del almacén de datos. Luego, crea sus implementaciones específicas de AbstractDatastore
, como XmlDatastore
, SQLiteDatastore
, etc. Luego, su programa solo necesita saber que está obteniendo un AbstractDatastore
y que debe tener esas funciones definidas en AbstractDatastore
pero no sabe ni le importa cómo los datos es almacenado o recuperado
Una clase abstracta es una clase para la que uno o más métodos se declaran pero no se definen, lo que significa que el compilador sabe que estos métodos son parte de la clase, pero no el código que se ejecutará para ese método. Estos se llaman métodos abstractos. Aquí hay un ejemplo de una clase abstracta.
class shape {
public:
virtual void draw() = 0;
};
Esto declara una clase abstracta que especifica que cualquier descendiente de la clase debe implementar el método de dibujar si la clase debe ser concreta. No puede crear una instancia de esta clase porque es abstracta, después de todo, el compilador no sabría qué código ejecutar si llamó al sorteo de miembros. Entonces no puedes hacer lo siguiente:
shape my_shape();
my_shape.draw();
Para poder usar realmente el método de dibujar, necesitarías derivar clases de esta clase abstracta, que implementen el método de dibujar, haciendo que las clases sean concretas:
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 */
}
};
Ahora puedes crear una instancia del círculo y rectángulo de objetos concretos y usar sus métodos de dibujo:
circle my_circle(40, 30, 10);
rectangle my_rectangle(20, 10, 50, 15);
my_circle.draw();
my_rectangle.draw();
Ahora, por supuesto, la pregunta es, ¿por qué querrías hacer esto? ¿No podría haber definido las clases de círculo y rectángulo y haber eliminado toda la clase de formas? Podría, pero entonces no podría aprovechar su herencia:
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)
Este código te permite recolectar todas tus formas en un contenedor. Esto lo hace mucho más fácil si tiene muchas formas y muchas formas diferentes en su escena. Por ejemplo, ahora podemos dibujar todas las formas de una vez, y el código que lo hace ni siquiera necesita saber sobre los diferentes tipos de formas que tenemos.
Ahora, finalmente, necesitamos saber por qué la función de dibujar de la forma es abstracta, y no solo una función vacía, es decir, ¿por qué no simplemente definimos:
class shape {
public:
virtual void draw() {
/* do nothing */
}
};
La razón de esto es que realmente no queremos objetos de forma tipo, no serían cosas reales de todos modos, serían abstractos. Por lo tanto, no tiene sentido definir una implementación para el método Draw, incluso uno vacío. Hacer que la clase de forma sea abstracta nos impide crear una instancia errónea de la clase de forma, o llamar erróneamente a la función de extracción vacía de la clase base en lugar de llamar a la función de las clases derivadas. En efecto, definimos una interfaz para cualquier clase que desea comportarse como una forma, decimos que cualquier clase debe tener un método de dibujo que parece que hemos especificado que debería.
Para responder a su última pregunta, no existe una ''clase derivada normal'', cada clase es abstracta o concreta. Una clase que tiene cualquier método abstracto es abstracta, cualquier clase que no lo es es concreta. Es solo una forma de diferenciar los dos tipos de clases. Una clase base puede ser abstracta u concreta y una clase derivada puede ser abstracta o concreta:
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 */
};
Una clase abstracta no puede ser instanciada mientras que una concreta puede. Una clase abstracta sirve como "blueprint" para las clases derivadas, que se pueden crear instancias.
Por ejemplo Car
clase de Car
(resumen), mientras que la clase de Audi S4
(derivada del Car
) es una implementación concreta.
Una clase concreta es una clase que se puede usar para crear un objeto. No se puede usar una clase abstracta para crear un objeto (debe extender una clase abstracta y hacer una clase concreta para luego poder crear un objeto).
Pretenda que hay una máquina que puede "estampar" las materias primas y hacer un automóvil. El stamper es una clase concreta. De esto podemos crear objetos de automóvil. Una clase abstracta sería los planos para el estampador. No puede hacer autos a partir de los planos del estampador, primero debe hacer la clase de estampado de los planos.
C ++ Faq Lite es un sitio excelente para buscar respuestas a este tipo de preguntas.
En el nivel de diseño, una clase base abstracta (ABC) corresponde a un concepto abstracto. Si le preguntaras a un mecánico si reparaba vehículos, probablemente se preguntaría qué tipo de vehículo tenías en mente. Lo más probable es que no repare los transbordadores espaciales, los transatlánticos, las bicicletas o los submarinos nucleares. El problema es que el término "vehículo" es un concepto abstracto (por ejemplo, no puede construir un "vehículo" a menos que sepa qué tipo de vehículo construir). En C ++, Class Vehicle sería un ABC, con Bicycle, SpaceShuttle, etc., siendo clases derivadas (un OceanLiner es un tipo de Vehículo). En OO del mundo real, el ABC aparece en todo el lugar
Una clase abstracta es una clase que tiene una o más funciones de miembros virtuales puros. No puede hacer un objeto (instancia) de una clase abstracta
class Shape {
public:
virtual void draw() const = 0; // = 0 means it is "pure virtual"
...
};
La clase abstracta no se puede usar para crear un objeto. Mientras que, la clase concreta se puede usar para crear un objeto.
Concreto significa '''' existir en la realidad o en la experiencia real; perceptible por los sentidos; real''''. Considerando que, abstracto significa '' no aplicado o práctico; teórico ''.
Una clase abstracta no puede ser instanciada. Mientras que, uno concreto puede.
Una clase abstracta es aquella que tiene una o más funciones virtuales puras. Mientras que una clase concreta no tiene funciones virtuales puras.