2012-07-17 9 views
11

¿Cuál es la diferencia entre una clase abstracta pública con un constructor público y una clase pública con un constructor protegido? No tenemos ninguna función que sea abstracta en nuestra clase abstracta, pero queremos que los programadores solo sean capaces de crear objetos que extiendan esa clase.¿Cuál es la diferencia entre abstracto y protegido en mi escenario? C#

Ambos escenarios se compilan y funcionan, sin embargo, no entiendo cuál sería mejor usar en qué escenario. Me han criado para comprender que aunque no se puede crear una instancia de una clase abstracta directamente (solo a través de una clase secundaria no abstracta), la clase abstracta normalmente debería contener funciones abstractas que los niños de esa clase deben implementar.

No tener un constructor protegido en una clase pública significa que la instanciación de esta clase no es posible (este es el único constructor que tenemos).

+0

Por lo que vale, creo que una clase abstracta transmite las intenciones de su diseño más claramente. – FishBasketGordo

+0

Está muy bien entender las diferencias, sin embargo, es más significativo entender "¿qué problema necesitas resolver?" Dependiendo de su respuesta, la creación de una instancia se puede hacer de diferentes maneras (clase de fábrica, por ejemplo) que puede ser independiente del tipo de clase declarada. –

+0

Gracias a todos por su entrada –

Respuesta

10

MSDN states sobre el uso de la palabra clave abstract para las clases: usa el modificador resumen en una declaración de clase para indicar que una clase sólo pretende ser una clase base de otras clases. Es decir, no se requiere que una clase abstracta contenga ningún miembro abstracto. El modificador abstract es solo una forma explícita de decir que la clase no se debe instanciar, en lugar de con obstáculos técnicos, como hacer que los constructores sean públicamente invisibles.

Tenga en cuenta que el obstáculo técnico que describe incluso tiene una advertencia: Todavía se puede llamar:

  • Se puede invocar desde las clases derivadas.
  • Se puede invocar mediante el uso de la reflexión.

Ambos significan que otros desarrolladores que están justo (ab -?) La utilización de su clase puede hacer algo que no va a suceder, es decir, una instancia de la clase, y ambos no son, posiblemente, al hacer la clase abstracta.

Por lo tanto, la respuesta es que debe marcar sus clases como abstract.

Tenga en cuenta que, no obstante, es aconsejable proteger el constructor de su clase abstracta (para enfatizar que no se puede crear una instancia de la clase). Herramientas como FxCop mostrarán una advertencia si una clase abstracta tiene un constructor público.

Esto cumple con la regla general de hacer que cada miembro sea tan visible como realmente debe ser. En una clase abstracta, los constructores nunca se invocarán desde el ámbito público, por lo que no se requiere visibilidad de public. Solo serán invocados por constructores de clases derivadas, por lo que protected es la visibilidad razonable para cualquier constructor en una clase abstracta.

Por lo tanto, también haga cualquier constructor de sus clases abstractas (a lo sumo) protected.

6

Haría una clase abstracta pública con un constructor protegido.

El uso de abstract deja en claro que es realmente una clase abstracta. Solo un constructor protected no es tan claro.

Nada más que una subclase puede llamar a un constructor abstract; no tiene sentido dejarlo public.

+0

Este es el camino a seguir. Hay un evento a [regla] (http://msdn.microsoft.com/en-us/library/ms182126.aspx) que aplica esto. – Rafal

+0

Lo siento, pero realmente no entiendo por qué: ¿no es suficiente el hecho de que la clase se declara como abstracta? Es decir, al leer esa palabra, 'abstracta', le dice al lector que la clase ES abstracta, ¿cómo puede ser más clara? – Daniel

+0

@Daniel: la idea puede ser otorgar a todos los miembros la visibilidad mínima requerida. Un constructor no es públicamente útil en una clase abstracta; solo se usará en clases derivadas (en su llamada de constructor heredada, más precisamente), por lo que debe ser * protected *. –

4

Un constructor privado o protegido todavía puede ser llamado por métodos estáticos en la clase de declaración. Una clase abstracta debe tener una clase derivada para ser instanciada. Por ejemplo, el patrón singleton hace uso de constructores privados llamados a través de un método/propiedad estática pública.

+0

Me gusta esta respuesta. Con una 'Base' de clase no abstracta, incluso si todos los constructores (de instancia) están 'protegidos', alguien podría introducir código en' Base' o en alguna clase que derive de 'Base' que dijera:' var b = new Base (...); ' –

0

Una clase abstracta pública con un constructor interno o protegido transmite cómo quiere que el código de llamada lo use. Usar un constructor no accesible puede ser realmente confuso.

Cuestiones relacionadas