2010-04-06 25 views
47

Si una clase tiene un constructor privado, no se puede crear una instancia. Entonces, si no quiero que mi clase sea instanciada y aún la use, entonces puedo hacerla estática.¿Por qué necesitamos un constructor privado?

¿Cuál es el uso de un constructor privado?

También se utiliza en la clase singleton, pero a excepción de eso, ¿hay algún otro uso?

(Nota: El motivo por el que excluyo el caso de singleton anterior es porque no entiendo por qué necesitamos un singleton cuando hay una clase estática disponible. No puede responder a esto por mi confusión en la pregunta.)

Respuesta

47

fábrica

constructores privados pueden ser útiles cuando se utiliza un patrón de fábrica (en otras palabras, una función estática que se utiliza para obtener una instancia de la clase en lugar de instancias explícita).

public class MyClass 
{ 
    private static Dictionary<object, MyClass> cache = 
     new Dictionary<object, MyClass>(); 

    private MyClass() { } 

    public static MyClass GetInstance(object data) 
    { 
     MyClass output; 

     if(!cache.TryGetValue(data, out output)) 
      cache.Add(data, output = new MyClass()); 

     return output;   
    } 
} 

Pseudo-Sellado con anidada niños

Cualquier clases anidadas que heredan de la clase externa puede acceder al constructor privado.

Por ejemplo, puede utilizar esto para crear una clase abstracta que que puede heredar de, pero nadie más (un constructor de internal también funcionaría aquí para restringir la herencia de un solo conjunto, pero los private fuerzas constructor de todo implementaciones sean clases anidadas.)

public abstract class BaseClass 
{ 
    private BaseClass() { } 

    public class SubClass1 : BaseClass 
    { 
     public SubClass1() : base() { } 
    } 

    public class SubClass2 : BaseClass 
    { 
     public SubClass2() : base() { } 
    } 
} 

Base Constructor

también pueden ser utilizados para crear "base" constructores que se llaman desde diferente, más acce constructores posibles.

public class MyClass 
{ 
    private MyClass(object data1, string data2) { } 

    public MyClass(object data1) : this(data1, null) { } 

    public MyClass(string data2) : this(null, data2) { } 

    public MyClass() : this(null, null) { } 
} 
+0

Me gusta la asignación dentro de la declaración de agregar caché, he utilizado esa sintaxis para las propiedades cargadas de forma perezosa con el operador nulo coalescente que no se me ocurrió antes de que pueda ser utilizado igualmente en los métodos regulares antes de ahora. –

+0

Adam-muchas gracias, tiene sentido ahora !!!! –

+0

¿El primer ejemplo parece ser un ejemplo de SingletonFactory? –

14

A veces no se debe poder instanciar una clase. Esto lo hace explícito e impone esto a nivel de compilador.

Los Singleton son solo un caso de uso. Las clases de constantes, las clases de métodos estáticos y otros tipos de patrones dictan que una clase no debe ser instanciable.

+0

simplemente para la corrección: Es posible marcar una clase estática, lo que asegura que sólo estática los miembros están permitidos y no se puede crear una instancia de la clase. – flq

+0

Stefan - ¡gracias por la respuesta, ayudó! –

2

Bueno, si su único objetivo es que no desee que se cree una instancia, entonces hacerlo estático es suficiente.

Si, otoh, simplemente no desea que se instale desde fuera de la clase, (tal vez solo desee que los usuarios obtengan uno usando una fábrica estática en la clase) - entonces necesita un ctor privado para permitir esas fábricas estáticas de acceso público para instanciarlo.

Históricamente, recuerde que hacer una clase estática no siempre ha existido ... Convertir el ctor en privado era una forma de hacerlo no instanciable (¿es esto una palabra?) Antes de que la palabra clave static pudiera aplicarse a una clase ...

0

Si la clase SOLO tiene constructores privados, no se puede crear una instancia desde el exterior.

También puede tener constructores privados y constructores públicos con diferentes firmas.

1

Puede usarlo para forzar una instancia singleton o crear una clase factory.

Un método estático puede llamar al constructor privado para crear una nueva instancia de esa clase.

Por ejemplo una instancia singleton:

public class Foo 
{ 

    private Foo(){} 

    private Foo FooInstance {get;set;} 

    public static Foo GetFooInstance() 
    { 
    if(FooInstance == null){ 
     FooInstance = new Foo(); 
    } 

    return FooInstance; 
    } 

} 

Esto permite sólo una instancia de la clase que se creará.

0

Si desea crear una fábrica para una clase, puede usar una construcción privada y agregar algunos métodos estáticos de "fábrica" ​​a la clase para crear la clase.

Un ejemplo para esto es la clase Graphics, con los métodos From *.

22

Como Stefan, Adam y otros han señalado, los constructores privados son útiles en los casos en que no es deseable que una clase sea creada por código fuera de la clase. Singletons, fábricas, objetos de método estático son ejemplos de donde poder restringir construcciones de un tipo es útil para imponer un patrón particular.

Para responder a la segunda parte de su pregunta acerca de por qué se necesitan únicos si existen clases estáticas: únicos y clases estáticas no son equivalente.

Por ejemplo, una clase singleton puede implementar una interfaz, una clase estática no. Un objeto singleton puede pasarse a los métodos como un parámetro; esto no es tan fácil de hacer con las clases estáticas sin recurrir a objetos de envoltura o reflexión. También hay casos en los que es posible que desee crear una jerarquía de herencia en la que una (o más) de las clases de hoja sean únicas, esto tampoco es posible con las clases estáticas. Como otro ejemplo, puede tener varios Singletons diferentes y es posible que desee crear una instancia de uno de ellos en tiempo de ejecución en función de los parámetros ambientales o de configuración; esto tampoco es posible con las clases estáticas.

Es importante comprender las características del idioma y elegir el más adecuado para el trabajo; están ahí por algún motivo.

+0

Gran respuesta :-) –

+1

excelente explicación diferenciando singleton y estático. Gracias !!!! –

+0

Explicación excelente en singleton vs clase estática! ¡Aprendo de eso! FWIW, puede usar "inicialización estática" para inicializar una clase singleton no estática. Consulte la [documentación oficial en este caso] (https://msdn.microsoft.com/en-us/library/ff650316.aspx). Ese es otro concepto para confundirte al principio y aprender algo bueno al final. :-) – RayLuo

1

En cuanto a singletons, singleton es un patrón de diseño utilizado cuando el entorno y los requisitos satisfacen motivaciones similares para el uso del patrón; las clases estáticas son una característica del lenguaje.

Como LBushkin's answer habla, mientras que algunos de los objetivos del uso de singleton se pueden cumplir utilizando clases estáticas, una implementación particular de singleton puede exceder el conjunto de características de clases estáticas solamente.

1

Propósito para crear el constructor privado dentro de una clase

  1. Para restringir una clase que se hereda.

  2. Restringir una clase al crear instancias o crear varias instancias/objetos.

  3. Para lograr el patrón de diseño singleton.

    public class TestPrivateConstructor 
    { 
        private TestPrivateConstructor() 
        { } 
    
        public static int sum(int a , int b) 
        { 
         return a + b; 
        } 
    } 
    
    class Program 
    { 
        static void Main(string[] args) 
        { 
         // calling the private constructor using class name directly 
         int result = TestPrivateConstructor.sum(10, 15); 
         // TestPrivateConstructor objClass = new TestPrivateConstructor(); // Will throw the error. We cann't create object of this class 
        } 
    } 
    
0
  • Uno de los usos de la construcción privada es cuando tenemos único miembro estático.
  • Una vez que proporcionamos un constructor que sea privado o público o alguno, el compilador no nos permitirá agregar un constructor público sin parámetros a la clase.
  • Si queremos crear objeto de la clase, incluso si tenemos constructores privados a continuación, tenemos que tener constructor público junto con el constructor privado
Cuestiones relacionadas