2008-11-21 20 views
42

Comúnmente me encuentro extrayendo comportamientos comunes fuera de clases en clases de ayuda/utilidad que no contienen nada más que un conjunto de métodos estáticos. A menudo me he preguntado si debería declarar estas clases como abstractas, ya que realmente no puedo pensar en una razón válida para alguna vez instanciarlas.¿Las clases de ayudante/utilidad deben ser abstractas?

¿Cuáles serían los pros y los contras al declarar una clase como abstracta?

public [abstract] class Utilities{ 

    public static String getSomeData(){ 
     return "someData"; 
    } 

    public static void doSomethingToObject(Object arg0){ 
    } 
} 

Respuesta

65

Se podía declarar un constructor privado que no hace nada.

El problema con declarar la clase "abstracta" es que la palabra clave abstracta generalmente significa que la clase está destinada a ser subclasificada y extendida. Eso definitivamente no es lo que quieres aquí.

+7

Y probablemente lo declare final para que su intención sea absolutamente clara. – tvanfosson

+9

Lamentablemente, no puede declararlo como abstracto final. :-) –

+3

No estaba sugiriendo que debería ...: | –

3

Al declararlos como abstractos, está en efecto indicando a otros codificadores de los que pretendía derivar estas clases. En realidad, tienes razón, no hay mucha diferencia, pero la semántica aquí es realmente más sobre la interpretación de otras personas que miran tu código.

0

No, pero si su idioma lo admite, hay un argumento fuerte que se debe hacer que en la mayoría de los casos deben (pueden) declararse como 'estáticos' ... Static le dice al compilador que no se pueden crear instancias, y todos los métodos en ellos deben ser estáticos.

abstracta es para las clases que tienen basados ​​en instancia detalles de implementación, los cuales serán utilizados por las instancias de clases derivadas ...

+1

las clases de Java no se pueden declarar como estáticas, ¿o sí? Tal vez solo estoy malinterpretando tu punto? – shsteimer

+0

Lo siento, soy .Net chico ... y no me di cuenta de la etiqueta java ... Entonces, si las clases de Java no se pueden declarar estáticas, debe hacer privado ctor sin parámetros y hacer todos los miembros estáticos ... –

+2

En algunos circunstancias, una clase de Java se puede declarar como estática, pero significa algo diferente. – erickson

17

No se moleste en hacerlos abstractos, pero incluya un constructor privado sin parámetros para evitar que se creen instancias.

punto de comparación para los interesados: en C# que declararían la clase a ser estática, por lo que es abstracto y sellada (Java final) en forma compilada, y sin ninguna instancia constructor en absoluto. Eso también hace que sea un error en tiempo de compilación declarar un parámetro, variable, matriz, etc. de ese tipo. Práctico.

0

Los métodos de Ayuda/Utilidad están muy bien. No se preocupe por agregarlos a una biblioteca dentro de su aplicación o Marco. La mayoría de los marcos que he visto los usan en muchas variedades.

Habiendo dicho eso, si quieres ser realmente astuto sobre ellos deberías mirar en extension methods en C# 3.0. El uso del método de extensión hará que sus Utilidades sean un poco más de una parte "integral" de su marco de trabajo, lo que parece ser lo que está tratando de hacer si las considera abstractas. ¡Sin mencionar el método de extensión es muy divertido de escribir!

0

Alguien mencionó que en C# 3.0 se puede lograr esto a través de métodos de extensión. No soy un chico C#, hice algunos en los días 1.5/2.0, pero no lo he usado desde entonces. Basado en una comprensión muy superficial, creo que se puede lograr algo similar en Java con importaciones estáticas. Me doy cuenta de que no es para nada lo mismo, pero si el objetivo es hacer que estos métodos de utilidad parezcan un poco más "nativos" (por falta de un término mejor) a la clase de llamadas, creo que hará el truco. Asumiendo la clase de utilidades declaro en mi pregunta original.

import static Utilities.getSomeData; 

public class Consumer { 

    public void doSomething(){ 

     String data = getSomeData(); 
    } 

} 
+0

¿Es esto válido Java? –

2

Como han dicho otros, cree un constructor privado sin parámetro. Nadie puede crear una instancia de él, aparte de la clase en sí.

Como otros han mostrado cómo se hace con otros lenguajes, aquí viene la forma de hacerlo en la versión siguiente de C++, cómo hacer que una clase no instanciable:

struct Utility { 
    static void doSomething() { /* ... */ } 
    Utility() = delete; 
}; 
9

no declaro de utilidad clases abstractas, las declaro definitivas y hago que el constructor sea privado. De esa forma no pueden ser subclasificados y no pueden ser instanciados.



public final class Utility 
{ 
    private Utility(){} 

    public static void doSomethingUseful() 
    { 
     ... 
    } 
} 
+0

Usando este formato que sugiere arriba, ¿debería usar una línea de "importación estática" para importar los métodos de clase para usar en mi proyecto? – djangofan

2

yo añadiría paso más allá del constructor privado:

public class Foo { 
    // non-instantiable class 
    private Foo() { throw new AssertionError(); } 
} 

Lanzar el AssertionError impide que los métodos de la misma clase de una instancia de la clase (así, pueden probar). Esto no suele ser un problema, pero en un entorno de equipo nunca se sabe lo que alguien hará.

En cuanto a la palabra clave "abstracto", que he notado clases de servicios públicos subclasificadas en numerosos casos:

public class CoreUtils { ... } 
public class WebUtils extends CoreUtils { ... } 

public class Foo { ... WebUtils.someMethodInCoreUtils() ... } 

creo que esto se hace para que la gente no tiene que recordar qué clase de utilidad para incluir. ¿Hay algún inconveniente en esto? ¿Es esto un antipatrón?

Saludos, LES

0

¿podría ofrecer algún consejo constructivo?

Si está haciendo mucho de esto, hay dos problemas que se encontrará.

En primer lugar, un método estático que toma un parámetro a menudo debe ser una parte del objeto que es ese parámetro. Me doy cuenta de que esto no ayuda con objetos como String, pero si toma objetos que haya definido, casi con seguridad podría mejorar el objeto al incluir su ayudante como método de ese objeto.

Si toma todos los valores nativos, probablemente pueda definir un objeto del que sea un método. Vea si puede encontrar cualquier agrupación de esos valores nativos y agruparlos como un objeto. Si lo intentas, encontrarás muchos otros usos para ese pequeño mini objeto, y antes de que te des cuenta será increíblemente útil.

Otra cosa, si tiene una clase de utilidad con un montón de métodos estáticos semi relacionados y variables estáticas, casi siempre quiere que sea un singleton. Descubrí esto por prueba y error, pero cuando averiguas que necesitas más de 1 (eventualmente lo harás), es MUCHO más fácil hacer un singleton en un multipleton (?) Luego tratar de cambiar una clase estática en un multipleton (de acuerdo, entonces estoy inventando palabras ahora).

Buena suerte. Para mí, todo esto fue principalmente de prueba y error; sin embargo, lo descubrí hace 5 años, y nunca he encontrado una instancia en la que lamentara no tener clase/métodos estáticos.

Cuestiones relacionadas