2009-08-25 212 views
15

Recientemente me he enfrentado a una pregunta: ¿Cómo evitar crear una instancia de una clase de Java?Evite instanciar una clase en Java

Sin embargo, respondí diciendo:

  1. Si no desea crear una instancia de una clase, utilice el modificador "abstracto". Ejemplo: javax.servlet.HttpServlet, se declara como abstracto (aunque ninguno de sus métodos es abstracto) para evitar la creación de instancias.

  2. Declare a no argument private constructor.

a) Mi pregunta es a) ¿Hay alguna otra manera? b) ¿por qué nadie quiere crear una instancia de una clase? - Después de buscar en SO, llegué a saber de this que las clases de Util se pueden hacer para no instanciar. ¿En otros lugares donde no queremos instanciar una clase en OOP?

Respuesta

24

Cuatro razones vienen a la mente:

  1. Para permitir subclases, pero no el de los padres a crear una instancia;
  2. Para no permitir instanciación directa y, en su lugar, proporcione un método de fábrica para devolver y, si es necesario, crear instancias;
  3. Porque todas las instancias están predefinidas (por ejemplo, trajes en una baraja de cartas), aunque desde Java 5, se recomiendan enums seguros; y
  4. La clase realmente no es una clase. Es solo un titular de constantes y/o métodos estáticos.

Como ejemplo de (2), es posible que desee crear objetos canónicos. Por ejemplo, combinaciones de colores RGB. Usted no desea crear más de una instancia de cualquier combinación RGB por lo que hace esto:

public class MyColor { 
    private final int red, green, blue; 

    private MyColor(int red, int green, int blue) { 
    this.red = red; 
    this.green = green; 
    this.blue = blue; 
    } 

    public static MyColor getInstance(int red, int green, int blue) { 
    // if combo already exists, return it, otherwise create new instance 
    } 
} 

Nota: Se requiere constructor sin sin argumentos porque otro constructor se define de forma explícita.

2

Creo que la razón más común para no querer crear una instancia de una clase es cuando se trata de una clase estática, y por lo tanto con sus métodos estáticos. No quieres que alguien intente crear una instancia de esa clase. Del mismo modo, cuando se trata de clases de Factory o en algunos casos, muchas clases de singleton ocultarán su constructor para que no se creen instancias de la manera normal.

3

En ocasiones, solo desea evitar que otros creen sus objetos para tener un control total sobre todas las instancias existentes. Un ejemplo es el singleton pattern.

1

Otra forma de hacer que una clase no sea instanciable sería declararla como una clase interna privada, y luego no proporcionar ninguna forma de instanciarla en la clase circundante. Pero esto es (IMO) bastante inútil.

Desea que una clase no sea instanciable si no tiene sentido crear una instancia. Generalmente haces esto si la clase es realmente solo una colección de métodos auxiliares (estáticos), o si la clase está "incompleta". Lo incompleto puede ser sintácticamente obvio (es decir, métodos abstractos), pero hay otros tipos de incompletud.Por ejemplo, puede proporcionar implementaciones predeterminadas predeterminadas para todos los métodos, y requerir que uno o más de ellos sean anulados para que la clase haga algo útil.

Otra razón para hacer que una clase no sea instanciable (o al menos, no directamente instanciable) es si su aplicación necesita controlar la creación de instancias. Por ejemplo, la clase java.util.regex.Pattern no se puede instanciar directamente para que el JRE pueda (pueda) mantener un caché de expresiones regulares pre compiladas.

8

No es realmente una respuesta a su pregunta, pero sólo una nota:

Al realizar un constructor sin argumentos privada para prevenir creación de instancias de sus clases de utilidad, usted debe tener el constructor de una excepción (por ejemplo UnsupportedOperationException). Esto se debe a que puede acceder a miembros privados (incluidos los constructores) a través de la reflexión. Tenga en cuenta que si lo hace, debe acompañarlo con un comentario, porque es un poco contra-intuitivo que defina un constructor en para evitar que se cree una instancia de.

Hacer que la clase de utilidad sea abstracta no es una buena idea porque hace que parezca que la clase va a extenderse y, además, puede ampliar la clase y así crear una instancia.

Cuestiones relacionadas