En utilisant la programmation orientée objet, nous avons le pouvoir de créer une classe à l'intérieur d'une classe (une classe imbriquée), mais je n'ai jamais créé de classe imbriquée au cours de mes 4 années d'expérience en codage.
À quoi servent les classes imbriquées?
Je sais qu'une classe peut être marquée comme privée si elle est imbriquée et que nous pouvons accéder à tous les membres privés de cette classe à partir de la classe conteneur. Nous pourrions simplement mettre les variables comme privées dans la classe contenant elle-même.
Alors pourquoi créer une classe imbriquée?
Dans quels scénarios les classes imbriquées devraient-elles être utilisées ou sont-elles plus puissantes en termes d'utilisation que d'autres techniques?
c#
object-oriented
programming-practices
.net
class-design
mayur rathi
la source
la source
Réponses:
La principale caractéristique des classes imbriquées est qu'elles peuvent accéder aux membres privés de la classe externe tout en ayant la pleine puissance d'une classe elle-même. Ils peuvent également être privés, ce qui permet une encapsulation assez puissante dans certaines circonstances:
Ici, nous verrouillons complètement le setter à l'usine puisque la classe est privée, aucun consommateur ne peut le downcaster et accéder au setter, et nous pouvons contrôler complètement ce qui est autorisé.
En dehors de cela, il est utile pour implémenter des interfaces tierces dans un environnement contrôlé où nous pouvons toujours accéder à des membres privés.
Si, par exemple, nous devions fournir une instance d'une interface à un autre objet mais que nous ne voulons pas que notre classe principale l'implémente, nous pourrions laisser une classe interne l'implémenter.
la source
Outer
, vous passeriez uneFunc<int>
, qui serait juste() => _example
Inner
non imbriquéeinternal
ne fonctionne pas (c'est-à-dire lorsque vous n'avez pas affaire à des assemblys différents). La lisibilité atteinte par les classes d'imbrication la rend moins favorable que l'utilisationinternal
(si possible).En règle générale, une classe N imbriquée est créée à l'intérieur d'une classe C chaque fois que C doit utiliser quelque chose en interne qui ne devrait jamais être (directement) utilisé en dehors de C, et pour une raison quelconque, quelque chose doit être un nouveau type d'objet plutôt qu'un objet existant type.
Je crois que cela se produit le plus souvent en implémentant une méthode qui renvoie un objet implémentant une interface, et nous voulons garder le type concret de cet objet caché car il ne sera utile nulle part ailleurs.
L'implémentation d'IEnumerable en est un bon exemple:
Il n'y a tout simplement aucune raison pour que quelqu'un en dehors de
BlobOfBusinessData
connaître ou de se soucier duBusinessDatumEnumerator
type de béton , nous pourrions aussi bien le garder à l'intérieurBlobOfBusinessData
.Ce n'était pas censé être un exemple de "meilleures pratiques" sur la façon de mettre en œuvre
IEnumerable
correctement, juste le strict minimum pour faire passer l'idée, alors j'ai laissé de côté des choses comme uneIEnumerable.GetEnumerator()
méthode explicite .la source
Node
classe dans aLinkedList
. Quiconque utilise leLinkedList
ne se soucie pas de la façon dont leNode
est implémenté, tant qu'il peut accéder au contenu. La seule entité qui se soucie du tout est laLinkedList
classe elle-même.Je peux penser à quelques raisons importantes:
1. Activer l'encapsulation
Plusieurs fois, les classes imbriquées sont des détails d'implémentation de la classe. Les utilisateurs de la classe principale ne devraient pas avoir à se soucier de leur existence. Vous devriez pouvoir les modifier à volonté sans obliger les utilisateurs de la classe principale à changer leur code.
2. Évitez la pollution par les noms
Vous ne devez pas ajouter des types, des variables, des fonctions, etc. dans une étendue, sauf s'ils sont appropriés dans cette étendue. Ceci est légèrement différent de l'encapsulation. Il pourrait être utile d'exposer l'interface d'un type imbriqué, mais l'emplacement approprié pour le type imbriqué est toujours la classe principale. En terre C ++, les types d'itérateurs en sont un exemple. Je n'ai pas assez d'expérience en C # pour vous en donner des exemples concrets.
Faisons un exemple simpliste pour illustrer pourquoi le déplacement d'une classe imbriquée dans la même portée que la classe principale est une pollution de nom. Supposons que vous implémentez une classe de liste chaînée. Normalement, vous utiliseriez
Si vous décidez de passer
Node
à la même portée queLinkedList
, vous aurezLinkedListNode
est peu susceptible d'être utile sans laLinkedList
classe elle-même. Même siLinkedList
certaines fonctions renvoyaient unLinkedListNode
objet qu'un utilisateurLinkedList
pourrait utiliser, elles ne sontLinkedListNode
utiles que lorsqu'ellesLinkedList
sont utilisées. Pour cette raison, faire de la classe "node" une classe homologue deLinkedList
pollue la portée contenante.la source
J'utilise des classes publiques imbriquées pour les classes d'assistance associées.
Utilisez-les pour les variantes associées.
L'appelant peut choisir quelle version convient à quel problème. Parfois, une classe ne peut pas être entièrement construite en un seul passage et nécessite une version mutable. Cela est toujours vrai lors de la manipulation de données cycliques. Les mutables peuvent être convertis en lecture seule ultérieurement.
Je les utilise pour des enregistrements internes
la source
La classe imbriquée peut être utilisée chaque fois que vous souhaitez créer plusieurs instances de la classe ou chaque fois que vous souhaitez rendre ce type plus disponible.
La classe imbriquée augmente les encapsulations ainsi que cela conduira à un code plus lisible et maintenable.
la source