Quelle est la différence entre une classe concrète et une classe abstraite?

j'apprends le class="blnk">C++, mais je suis confus au sujet de la classe abstraite et de la classe concrète. Quelques exemples du monde réel seraient appréciés.

51
demandé sur Jagd 2010-01-27 21:04:12

9 réponses

une classe abstraite est une classe pour laquelle une ou plusieurs méthodes sont déclarées mais non définies, ce qui signifie que le compilateur sait que ces méthodes font partie de la classe, mais pas quel code à exécuter pour cette méthode. Ce sont des méthodes abstraites. Voici un exemple d'une classe abstraite.

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

déclare une classe abstraite qui spécifie que tout descendant de la classe doit mettre en œuvre la méthode de tirage si la classe doit être concrète. Vous ne pouvez pas instanciez cette classe parce qu'elle est abstraite, après tout, le compilateur ne saurait pas quel code exécuter si vous appeliez le membre draw. Vous ne pouvez donc pas faire ce qui suit:

shape my_shape();
my_shape.draw();

pour pouvoir réellement utiliser la méthode de dessin, vous auriez besoin de dériver des classes de cette classe abstraite, qui mettent en œuvre la méthode de dessin, ce qui rend les classes concrètes:

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

maintenant vous pouvez instancier les objets en béton cercle et rectangle et utiliser leur méthodes de tirage:

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

Maintenant, bien sûr, la question est, pourquoi voudriez-vous faire cela? N'auriez-vous pas pu aussi bien définir les classes cercle et rectangle et supprimer toute la classe forme? Vous pourriez, mais alors vous ne seriez pas en mesure de profiter de leur héritage:

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)

ce code vous permet de rassembler toutes vos formes en un seul conteneur. Cela le rend beaucoup plus facile si vous avez beaucoup de formes et de beaucoup de différents des formes dans votre scène. Par exemple, nous pouvons maintenant tirer toutes les formes d'un seul coup, et le code qui le fait n'a même pas besoin de connaître les différents types de formes que nous avons.

maintenant enfin nous avons besoin de savoir pourquoi la fonction de dessin de la forme est abstraite, et pas seulement une fonction vide, c'est-à-dire pourquoi nous n'avons pas simplement défini:

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

la raison pour cela est que nous ne voulons pas vraiment des objets de forme de type, ils ne seraient pas des choses réelles de toute façon, ils seraient être abstrait. Il n'est donc pas logique de définir une implémentation de la méthode draw, même vide. Rendre abstraite la classe shape nous empêche d'instancier par erreur la classe shape, ou d'appeler par erreur la fonction de tirage vide de la classe de base au lieu de la fonction de tirage des classes dérivées. En effet, nous définissons une interface pour toute la classe qui voudrais se comporter comme une forme, nous disons qu'une telle classe doit avoir une méthode de dessin qui ressemble comme nous l'avons spécifié devrait.

pour répondre à votre dernière question, il n'existe pas de "classe dérivée normale". chaque classe est abstraite ou concrète. Une classe qui a des méthodes abstraites est abstraite, toute classe qui n'est pas en béton. C'est juste un moyen de différencier les deux types de classes. Une classe de base peut être abstrait ou concret et une classe dérivée peut être abstrait ou concret:

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 */
};
96
répondu wich 2010-01-27 19:17:54

la classe Abstraite ne peut pas être utilisé pour créer un objet. Par contre, classe béton peut être utilisé pour créer un objet.

Béton signifie" existant en réalité ou en expérience réelle; perceptible par les sens; réelle". Considérant que abrégé signifie Non appliqué ou pratique; théoritique ".

An abstrait de la classe ne peut pas être instanciée. Alors que, un béton on peut.

Un abstrait qui est dans une classe qui a un ou plusieurs fonction virtuelle pure. Alors qu'une classe béton n'a pas de fonctions purement virtuelles.

22
répondu Th. Manjit SEMC 2011-11-15 13:16:04

une classe de béton est une classe qui peut être utilisée pour créer un objet. Une classe abstraite ne peut pas être utilisé pour créer un objet (vous devez étendre une classe abstraite et faire un béton de classe pour pouvoir ensuite créer un objet).

prétendre qu'il ya une machine qui peut "stamp" les matières premières et de faire une voiture. Le tampon encreur est une classe concrète. À partir de cela, nous pouvons créer des objets de voiture. Une classe abstraite serait l'empreinte de la matrice. Vous ne pouvez pas faire des voitures à partir de la les plans du stamper, vous devez faire la classe du stamper d'abord à partir des plans.

20
répondu Jansen Price 2010-01-27 18:10:29

une classe abstraite ne peut pas être instanciée alors qu'une classe concrète le peut. Une classe abstraite Sert de "schéma directeur" pour les classes dérivées, celles qui peuvent être instanciées.

E. G. La classe Car (abrégé) tandis que la classe Audi S4 (dérivée de la classe Car ) est une implémentation concrète.

3
répondu jldupont 2010-01-27 18:08:23

un bon exemple d'utilisation d'une classe abstraite est quand vous construisez quelque chose de très modulaire. Disons que vous travaillez avec un magasin de données, mais ces données pourraient être dans une base de données MySQL, une base de données SQLite, un fichier XML, ou un texte simple. Pour conserver cette polyvalence dans votre code, vous pouvez créer une classe AbstractDatastore qui définit les méthodes publiques que vous voulez utiliser pour obtenir des informations à partir du datastore. Ensuite, vous créez vos implémentations spécifiques du AbstractDatastore , comme XmlDatastore , SQLiteDatastore , etc. Ensuite, votre programme a juste besoin de savoir qu'il obtient un AbstractDatastore et qu'il doit avoir ces fonctions définies dans AbstractDatastore mais il ne sait pas ou ne se soucie pas comment les données sont stockées ou extraites.

1
répondu Corey D 2010-01-27 18:15:26
"151900920 de Base" classe contre classe dérivée est une orthogonale de la notion de classe abstraite vs classe concrète.

une classe de base est une classe qui n'hérite d'aucune autre classe. Une classe dérivée hérite d'une autre classe.

une classe abstraite est une classe qui a une ou plusieurs fonctions virtuelles pures. Une classe concrète n'a pas de virtualités pures.

Une classe abstraite peut être soit une classe de base ou d'une classe dérivée (il est dérivé à partir d'une autre classe abstraite). Une classe de béton peut aussi être de base ou dérivée. Vous pouvez même dériver une classe abstraite d'une classe concrète, en ajoutant une fonction virtuelle pure à la classe dérivée. Mais en général, il existe une base de classe abstraite et une ou plusieurs classes dérivées.

1
répondu KeithB 2010-01-27 18:36:02

C++ Faq Lite est un excellent site pour chercher des réponses à ce genre de questions.

au niveau de la conception, une classe de base abstraite (ABC) correspond à un concept abstrait. Si vous demandiez à un mécanicien s'il réparait des véhicules, il se demanderait probablement quel type de véhicule vous aviez en tête. Il ne répare pas les navettes, les paquebots, les vélos ou les sous-marins nucléaires. Le problème est que le terme "véhicule" est un concept abstrait (par exemple, vous ne pouvez pas construire un "véhicule" à moins de savoir quel type de véhicule construire). En C++, le véhicule de classe serait un ABC, avec la bicyclette, la navette spatiale, etc, étant des classes dérivées (un OceanLiner est-un-genre-de-véhicule). Dans le monde réel OO, L'ABC apparaît partout

une classe abstraite est une classe qui a une ou plusieurs fonctions de membre virtuel pur. Vous ne pouvez pas faire un objet (instance) D'une classe abstraite

 class Shape {
 public:
   virtual void draw() const = 0;  // = 0 means it is "pure virtual"
   ...
 }; 
0
répondu Diego Dias 2010-01-27 18:28:08

la classe de béton a mis en œuvre toute sa méthode. Classe abstraite toute sa méthode sauf quelques (au moins une) méthode (s) un-implemented afin que vous puissiez l'étendre et implémenter la méthode un-implemented.

avantage: en étendant de la classe abstraite vous obtenez toutes les fonctionnalités de la classe de base et vous serez 'forcé' à mettre en œuvre la méthode non-implémentée. Donc le concepteur de la classe vous force à écrire du code dans la méthode abstraite avant que la classe ne soit de tout pour vous.

0
répondu prashant 2010-01-27 19:12:18