Usando la Programación Orientada a Objetos tenemos el poder de crear una clase dentro de una clase (una clase anidada), pero nunca he creado una clase anidada en mis 4 años de experiencia en codificación.
¿Para qué sirven las clases anidadas?
Sé que una clase se puede marcar como privada si está anidada y que podemos acceder a todos los miembros privados de esa clase desde la clase que la contiene. Podríamos poner las variables como privadas en la clase que las contiene.
Entonces, ¿por qué crear una clase anidada?
¿En qué escenarios deberían usarse las clases anidadas o son más poderosas en términos de uso que otras técnicas?
c#
object-oriented
programming-practices
.net
class-design
mayur rathi
fuente
fuente
Respuestas:
La característica principal de las clases anidadas es que pueden acceder a miembros privados de la clase externa mientras tienen todo el poder de una clase. También pueden ser privados, lo que permite una encapsulación bastante poderosa en ciertas circunstancias:
Aquí bloqueamos el setter completamente a la fábrica ya que la clase es privada, ningún consumidor puede rechazarlo y acceder al setter, y podemos controlar completamente lo que está permitido.
Aparte de eso, es útil para implementar interfaces de terceros en un entorno controlado donde todavía podemos acceder a miembros privados.
Si, por ejemplo, proporcionáramos una instancia de alguna interfaz a otro objeto, pero no queremos que nuestra clase principal lo implemente, podríamos permitir que una clase interna lo implemente.
fuente
Outer
, pasarías unFunc<int>
, que sería() => _example
Inner
nointernal
esté anidado y no funcione (es decir, cuando no se trata de ensamblajes diferentes). El impacto de legibilidad de las clases de anidamiento lo hace menos favorable que usarinternal
(cuando sea posible).Típicamente, una clase N anidada se crea dentro de una clase C cuando C necesita usar algo interno que nunca debe usarse (directamente) fuera de C, y por cualquier razón, algo debe ser un nuevo tipo de objeto en lugar de algo existente tipo.
Creo que esto sucede con mayor frecuencia al implementar un método que devuelve un objeto que implementa alguna interfaz, y queremos mantener oculto el tipo concreto de ese objeto porque no será útil en ningún otro lugar.
Implementar IEnumerable es un buen ejemplo de esto:
Simplemente no hay ninguna razón para que alguien externo
BlobOfBusinessData
sepa o se preocupe por elBusinessDatumEnumerator
tipo de concreto , por lo que podríamos mantenerlo adentroBlobOfBusinessData
.Ese no fue un ejemplo de "mejores prácticas" de cómo implementarlo
IEnumerable
correctamente, solo el mínimo para transmitir la idea, así que omití cosas como unIEnumerable.GetEnumerator()
método explícito .fuente
Node
clase en aLinkedList
. A cualquiera que use elLinkedList
no le importa cómoNode
se implementa, siempre que pueda acceder a los contenidos. La única entidad a la que le importa es laLinkedList
clase misma.Puedo pensar en un par de razones importantes:
1. Habilitar la encapsulación
Muchas veces las clases anidadas son detalles de implementación de la clase. Los usuarios de la clase principal no deberían tener que preocuparse por su existencia. Debería poder cambiarlos a voluntad sin requerir que los usuarios de la clase principal cambien su código.
2. Evitar la contaminación del nombre
No debe agregar tipos, variables, funciones, etc. en un ámbito a menos que sean apropiados en ese ámbito. Esto es ligeramente diferente de la encapsulación. Podría ser útil exponer la interfaz de un tipo anidado, pero el lugar adecuado para el tipo anidado sigue siendo la clase principal. En C ++ land, los tipos de iterador son un ejemplo de ello. No tengo experiencia en C # lo suficiente como para darle ejemplos concretos.
Hagamos un ejemplo simplista para ilustrar por qué mover una clase anidada al mismo alcance que la clase principal es la contaminación del nombre. Digamos que está implementando una clase de lista vinculada. Normalmente, usarías
Si decide
Node
subir al mismo alcance queLinkedList
, tendráLinkedListNode
es poco probable que sea útil sin laLinkedList
clase misma. Incluso si seLinkedList
proporcionan algunas funciones que devuelven unLinkedListNode
objeto que un usuarioLinkedList
podría usar, sigue siendoLinkedListNode
útil solo cuandoLinkedList
se usa. Por esa razón, hacer que la clase "nodo" sea una clase de igualLinkedList
es contaminar el alcance que contiene.fuente
Utilizo clases públicas anidadas para clases auxiliares relacionadas.
Úselos para variaciones relacionadas.
La persona que llama puede elegir qué versión es adecuada para cada problema. A veces, una clase no se puede construir completamente en una sola pasada y requiere una versión mutable. Esto siempre es cierto cuando se manejan datos cíclicos. Las mutables se pueden convertir a solo lectura más tarde.
Los uso para registros internos
fuente
La clase anidada se puede usar siempre que desee crear más de una instancia de la clase o cuando desee que ese tipo esté más disponible.
La clase anidada aumenta las encapsulaciones y dará lugar a un código más fácil de leer y mantener.
fuente