11
votes

Quelle est la différence entre résumé et protégé dans mon scénario - C #

Quelle est la différence entre une classe abstraite publique avec un constructeur public et une classe publique avec un constructeur protégé. Nous n'avons aucune fonction abstraite dans notre classe abstraite, mais nous voulons que les programmeurs ne soient capables de créer des objets qui prolongent cette classe.

Les deux scénarios compilent et fonctionnent, mais je ne comprends pas ce qui serait préférable d'utiliser dans quel scénario. J'ai été élevé pour comprendre que, bien que vous ne puissiez pas instancer une classe abstraite directement (uniquement via une classe enfant non abstraite), la classe Abstract doit normalement contenir des fonctions abstraites nécessaires à la mise en œuvre des enfants de cette classe.

n'ayant pas de constructeur protégé dans une classe publique signifierait que l'instanciation de cette classe n'est pas possible (c'est le seul constructeur que nous avons).


2 commentaires

Pour ce que ça vaut la peine, je pense qu'une classe abstraite transmet les intentions de votre conception plus clairement.


Tout va bien et bon de comprendre les différences, mais il est plus significatif de comprendre "quel problème avez-vous besoin pour résoudre?" Selon votre réponse, la création d'une instance peut être effectuée différentes manières (classe d'usine par exemple) qui peut être indépendante du type de classe déclaré.


4 Réponses :


6
votes

Je ferais une classe abstraite publique avec un constructeur protégé.

Utiliser Abstrait Il est clair que c'est vraiment une classe abstraite. Juste un protégé constructeur n'est pas aussi clair.

rien d'autre qu'une sous-classe ne peut appeler un abstrait constructeur; Il est un peu sans signification de le laisser public .


7 commentaires

C'est la voie à suivre. Il y a un événement a règle qui l'applique.


Désolé, mais je ne comprends vraiment pas pourquoi - ce n'est pas le fait que la classe est déclarée comme résumé le rend suffisant? Je veux dire, lisant qu'un mot, «abstrait», dit au lecteur que la classe est abstraite - comment peut-il obtenir des informations plus claires ..?


@Daniel: L'idée peut être de donner à tous les membres leur visibilité minimale requise. Un constructeur n'est pas utile publiquement dans une classe abstraite; Il ne sera jamais utilisé que dans des cours dérivés (dans leur appel de constructeur hérité, plus précisément), c'est pourquoi il devrait être protégé .


Je veux dire que l'utilisation du mot clé abstrait le rend plus clair. Ajouter "protégé" au constructeur est essentiellement du sucre. Mais cela dit aux examinateurs de la classe que vous avez compris quel résumé signifie vraiment :). Rien d'autre qu'une sous-classe ne peut appeler un constructeur abstrait; C'est un peu sans signification de le laisser publique.


@PeterRitchie: Vous ne voulez rien dire autre qu'une classe dérivée , je présume? :-)


@ O.R.Mapper Oui, Sous-classe :)


Pour un autre exemple: si le code ne donne aucun constructeur d'instance pour une classe, le compilateur sera, comme vous le savez, écrivez un constructeur pour vous, le constructeur par défaut. Ce constructeur sera public uniquement si la classe est non abstraite. Pour une classe abstraite, ce constructeur "invisible" sera protégé . Voir le paragraphe 10.11.4 du C # Spécification de langue . Il s'agit donc d'un autre exemple de la pratique de ne pas avoir de constructeurs publics dans des classes abstraites.



10
votes

Etats MSDN sur l'utilisation de le mot-clé abstrait pour les classes: Utilisez le modificateur abstrait dans une déclaration de classe pour indiquer qu'une classe est destinée à être une classe de base d'autres classes. c'est-à-dire que c'est Non requis qu'une classe abstraite contienne des membres abstraits. Le modificateur abstraite est simplement un moyen explicite de dire que la classe ne doit pas être instanciée, plutôt qu'avec des obstacles techniques tels que la fabrication des constructeurs à invisible.

Notez que l'obstacle technique que vous avez décrit a même une mise en garde: on peut toujours appeler:

  • Il peut être invoqué à partir de classes dérivées.
  • Il peut être invoqué à l'aide de la réflexion.

    Les deux signifient que les autres développeurs qui ne sont que (AB -?) L'utilisation de votre classe peut faire quelque chose que vous n'avez pas l'intention de se produire, à savoir instancier votre classe, et les deux ne sont pas éventuellement lorsque vous faites le résumé de la classe.

    Par conséquent, la réponse est que vous devez marquer vos classes comme abstrait .

    Notez qu'il est conseillé de rendre le constructeur de votre classe abstraite protégée néanmoins (pour souligner que la classe ne peut pas être instanciée). Des outils tels que FXCop produiront un avertissement si une classe abstraite a un constructeur public.

    Ceci est conforme à la règle générale de rendre chaque membre aussi visible que cela doit vraiment être. Dans une classe abstraite, les constructeurs ne seront jamais invoqués de la portée publique, de sorte que la visibilité n'est pas requise. Ils ne seront jamais invoqués que par des constructeurs de classes dérivés, de sorte que protégé est la visiblicité raisonnable pour tous les constructeurs d'une classe abstraite.

    par conséquent, faites également des constructeurs de vos classes abstraits (au plus) protégé .


0 commentaires

4
votes

Un constructeur privé ou protégé peut toujours être appelé par des méthodes statiques dans la classe de déclaration. Une classe abstraite doit avoir une classe dérivée à instantie. Par exemple, le motif singleton utilise des constructeurs privés appelés à une méthode / une propriété publiques statique.


1 commentaires

J'aime cette réponse. Avec une classe non abstraite base , même si tous les constructeurs (instance) sont protégés , une personne pourrait introduire du code dans base ou dans certains Classe dérivant de base qui dit: var b = nouvelle base (...);



0
votes

Une classe abstraite publique avec un constructeur interne protégé ou interne avise la manière dont vous voulez appeler le code pour l'utiliser. L'utilisation d'un constructeur non accessible peut être confus.


0 commentaires