2010-01-27 21 views

Respuesta

88

Una clase abstracta es una clase para la que se declaran uno o más métodos pero no se define, 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 sorteo si la clase es que ser concreto. 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. Por lo que no puede hacer lo siguiente:

shape my_shape(); 
my_shape.draw(); 

Para poder utilizar realmente el método de sorteo que se necesita para derivar clases de esta clase abstracta, que ponen en práctica el método de sorteo, por lo que las clases 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 se puede crear una instancia del círculo y el rectángulo objetos concretos y utilizar 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é w hormiga para 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 sería capaz de tomar ventaja de 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 de recoja todas sus formas en un contenedor let. 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 tracción cuya forma es abstracta, y no sólo una función de vacío, es decir, ¿por qué no acabamos de definir:

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

La razón de esto es que Don Realmente quiero 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 abstracto o concreto y una clase derivada puede ser abstracto o concreto:

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 */ 
}; 
+7

gran explicación con simplicidad ..! –

+0

Si falta la definición de una función, entonces eso es solo un error de enlace. Una clase abstracta implica = 0, como han dicho otras respuestas. Peor aún, una función virtual pura * puede * definirse en C++. De hecho, los destructores virtuales definidos pero puros son comunes. –

+0

Simple pero cubre el rincón y la esquina –

3

Una clase abstracta no se puede instanciar mientras que una concreta. Una clase abstracta sirve como "blueprint" para las clases derivadas, que se pueden crear instancias.

E.g. Car clase (resumen) mientras que Audi S4 clase (derivada de Car) clase es una implementación concreta.

+0

estoy claro con la clase abstracta, pero ¿cuál es la diferencia entre la clase derivada normal y la clase concreta? –

18

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).

Supongamos que hay una máquina que puede "sellar" 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.

+0

¿por qué lo llamamos clase concreta? –

+7

Debido a la definición: Concreto es "Existente en la realidad o en la experiencia real; Perceptible por los sentidos; Real", mientras que Resumen significa "No aplicado o práctico; Teórico" –

0

Un buen ejemplo del uso de una clase abstracta es cuando se está 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 conservar 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 del 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

+0

Esto no explica la diferencia entre clases abstractas y concretas, justo cuando usarías uno. – wich

+1

Otras personas dieron explicaciones razonables, di un ejemplo real. –

0

C++ Faq Lite es un excelente sitio en busca de respuestas en 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 todas partes.

Una clase abstracta es una clase que tiene una o más funciones de miembros virtuales puros. No se puede hacer un objeto (instancia) de una clase abstracta clase

class Shape { 
public: 
    virtual void draw() const = 0; // = 0 means it is "pure virtual" 
    ... 
}; 
+0

Esto no explica la diferencia entre clases abstractas y concretas, solo lo que es una clase abstracta. – wich

+0

Leí la explicación de una clase abstracta como implícitamente indicando qué es una clase concreta. Además, C++ FAQ Lite es un sitio muy útil. Por lo tanto, me pellizqué. –

+0

@wich Para mí, está claro que si una clase abstracta es "una clase que tiene una o más funciones de miembros virtuales puros", entonces una clase concreta es una clase que no lo es. ¿O hay una clase semi-abstracta? –

1

-Clase base vs. derivada es un concepto ortogonal a clase abstracta vs. 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.

0

clase concreta tiene toda 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: si se extiende desde la clase abstracta se obtiene toda la funcionalidad de la clase base &, se le 'forzará' 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.

20

La clase abstracta no se puede usar para crear un objeto. Mientras que, clase de concreto se puede usar para crear un objeto.

Concreto significa '' existente en la realidad o en la experiencia real; perceptible por los sentidos; real''. Mientras que, abstract significa 'no aplicado o práctico; theoritical '.

No se puede crear una instancia de abstract. Mientras que, un concreto uno puede.

Un resumen clase es aquella que tiene una o más funciones virtuales puras. Mientras que una clase concreta de no tiene funciones virtuales puras.

Cuestiones relacionadas