Pour clarifier, ce que je demande, c'est
public class A{
private/*or public*/ B b;
}
contre.
public class A{
private/*or public*/ class B{
....
}
}
Je peux certainement penser à certaines raisons d'utiliser l'une ou l'autre, mais ce que j'aimerais vraiment voir, ce sont des exemples convaincants qui montrent que les avantages et les inconvénients ne sont pas seulement académiques.
object-oriented-design
class-design
EpsilonVector
la source
la source
Réponses:
Ils sont généralement utilisés lorsqu'une classe est un détail d'implémentation interne d'une autre classe plutôt qu'une partie de son interface externe. Je les ai surtout vus comme des classes de données uniquement qui rendent les structures de données internes plus propres dans les langages qui n'ont pas de syntaxe distincte pour les structures de style C. Ils sont également utiles parfois pour des objets dérivés d'une méthode hautement personnalisés comme les gestionnaires d'événements ou les threads de travail.
la source
Supposons que vous construisez un arbre, une liste, un graphique, etc. Pourquoi devriez-vous exposer les détails internes d'un nœud ou d'une cellule au monde extérieur?
Toute personne utilisant un graphique ou une liste ne doit compter que sur son interface, et non sur son implémentation, car vous souhaiterez peut-être la changer un jour à l'avenir (par exemple, d'une implémentation basée sur un tableau à une implémentation basée sur un pointeur) et les clients utilisant votre la structure des données ( chacune d'elles ) devrait modifier son code afin de l'adapter à la nouvelle implémentation.
Au lieu de cela, l'encapsulation de l'implémentation d'un nœud ou d'une cellule dans une classe interne privée vous donne la liberté de modifier l'implémentation à tout moment, sans que les clients soient obligés d'ajuster leur code en conséquence, tant que l'interface de votre structure de données reste intacte.
Masquer les détails de l'implémentation de votre structure de données entraîne également des avantages de sécurité, car si vous souhaitez distribuer votre classe, vous ne rendrez disponible que le fichier d'interface avec le fichier d'implémentation compilé et personne ne saura si vous utilisez réellement des tableaux ou des pointeurs pour votre implémentation, protégeant ainsi votre application d'une sorte d'exploitation ou, au moins, de connaissances en raison de l'impossibilité d'utiliser ou d'inspecter votre code. En plus des problèmes pratiques, ne sous-estimez pas le fait que c'est une solution extrêmement élégante dans de tels cas.
la source
À mon avis, c'est un flic juste d'utiliser des classes définies en interne pour les classes qui sont utilisées brièvement dans une classe pour permettre une tâche spécifique.
Par exemple, si vous devez lier une liste de données composée de deux classes indépendantes:
Si votre classe interne est utilisée par une autre classe, vous devez la séparer. Si votre classe interne contient une logique, vous devez la séparer.
Fondamentalement, je pense qu'ils sont parfaits pour boucher les trous dans vos objets de données, mais ils sont difficiles à maintenir s'ils doivent contenir de la logique, car vous devrez savoir où les chercher si vous devez les changer.
la source
tuple.ItemX
le code n'est pas clair.Les classes internes dans certains langages (Java par exemple) ont un lien avec un objet de leur classe contenante et peuvent utiliser leurs membres sans les qualifier. Lorsqu'elles sont disponibles, il est plus clair que de les réimplémenter à l'aide d'autres ressources linguistiques.
Les classes imbriquées dans d'autres langages (C ++ par exemple) n'ont pas ce lien. Vous utilisez simplement le contrôle de la portée et de l'accessibilité fourni par la classe.
la source
J'évite les classes internes en Java car le remplacement à chaud ne fonctionne pas en présence de classes internes. Je déteste cela parce que je déteste vraiment compromettre le code pour de telles considérations, mais ces redémarrages de Tomcat s'additionnent.
la source
L'une des utilisations de la classe interne statique privée est le modèle de mémo. Vous mettez toutes les données qui doivent être mémorisées dans une classe privée et les renvoyez d'une fonction en tant qu'objet. Personne à l'extérieur ne peut (sans réflexion, désérialisation, inspection de la mémoire ...) l'examiner / le modifier, mais il peut le rendre à votre classe et il peut restaurer son état.
la source
Une raison d'utiliser une classe interne privée peut être due au fait qu'une API que vous utilisez nécessite l'héritage d'une classe particulière, mais vous ne voulez pas exporter la connaissance de cette classe vers les utilisateurs de votre classe externe. Par exemple:
Dans ce cas, do_my_async_op nécessite de lui passer un objet de type callback. Ce rappel a une signature de fonction de membre public que l'API utilise.
Lorsque do_op () est appelé à partir de la classe externe, il utilise une instance de la classe interne privée qui hérite de la classe de rappel requise au lieu d'un pointeur sur lui-même. La classe externe a une référence à la classe externe dans le simple but de shunter le rappel dans la fonction membre do_callback privée de la classe externe .
L'avantage de ceci est que vous êtes sûr que personne d'autre ne peut appeler la fonction membre publique "fire ()".
la source
Selon Jon Skeet dans C # in Depth, l'utilisation d'une classe imbriquée était le seul moyen d'implémenter un singleton thread-safe entièrement paresseux (voir cinquième version) (jusqu'à .NET 4).
la source
Les classes privées et internes sont utilisées pour augmenter les niveaux d'encapsulation et masquer les détails d'implémentation.
En C ++, en plus d'une classe privée, le même concept peut être obtenu en implémentant l'espace de noms anonyme d'une classe cpp. Cela sert bien à cacher / privatiser un détail d'implémentation.
C'est la même idée qu'une classe interne ou privée mais à un niveau d'encapsulation encore plus élevé car elle est complètement invisible en dehors de l'unité de compilation du fichier. Rien de tout cela n'apparaît dans le fichier d'en-tête ou n'est visible de l'extérieur dans la déclaration de la classe.
la source