Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] Clases no instanciables

Estas en el tema de Clases no instanciables en el foro de Java en Foros del Web. Estoy empezando un nuevo curso online de java a través de videos del YouTube (qué buena idea la del creador, pues seguro se está forrando... ...
  #1 (permalink)  
Antiguo 06/10/2015, 04:00
(Desactivado)
 
Fecha de Ingreso: marzo-2012
Mensajes: 366
Antigüedad: 12 años
Puntos: 31
Clases no instanciables

Estoy empezando un nuevo curso online de java a través de videos del YouTube (qué buena idea la del creador, pues seguro se está forrando... y qué bien viene para el alumno) que lo recomiendo pues está genial y está disponible en Pildoras Informáticas y hemos llegado al modificador static, explicando un valor estático y un método estático. Hemos visto un ejemplo de cuando puede venir bien tener un valor estático y un método estático.

También nos ha hecho referencia a otros métodos estáticos predefinidos en java, como pueden ser todos los de la clase Math. Y es aquí donde yo he empezado a ir un poco más allá, y donde me surgen las dudas.

En el ejemplo de la clase que hemos hecho el atributo estático y el método estático que la devuelve construimos objetos de esa clase. Es decir... instanciamos y creamos copias tanto de sus atributos como de sus métodos.

Sin embargo... he intentado instanciar la clase Math y me ha dado un error. Lo primero que he pensado es que en la declaración de la clase llevaba el modificador static. Así pues a mi clase se lo he puesto... y me ha dado un error. Eclipse solo me daba una solución: Eliminar el modificador static. Entonces... ¿como Math no se puede instanciar? He ido al error que me daba al intentar instanciar... y eclipse me decía que no había ningún constructor visible.

Por otra parte, en otras clases sin declarar constructor, siempre funciona el constructor vacio (el que no recoge parámetros) aunque no esté declarado.

Así pues... con los conocimientos que yo poseo (no se si muchos o pocos) solo me da para una única conclusión: Math tiene declarado un constructor sin parámetros que está declarado como private.

Y con esta conclusión... voy a aplicarla a mi ejemplo de la clase empleado. Cojo mi clase empleado y pongo su constructor como private... ¿y qué pasa? en mi void main, donde declaro las instanciaciones me dan error. Lógico pues ya no tienen un constructor al que acudir para instanciar (era consecuencia buscada). Pero sigo pudiendo acceder a los métodos que antes tenía creados como estáticos acudiendo a ellos como clase.método(parametros). Y además me doy cuenta de que no puedo acceder a los métodos que no son estáticos, aunque sean públicos. Así pues... mi objetivo está cumplido. Obtención de una clase que no se pueda instanciar, como la de Math con métodos estáticos que hagan cosas, o devuelvan cosas.


=====================


La pregunta final es: Para conseguir una clase no instanciable en java, con atributos variables no instanciables, atributos constantes no instanciables y métodos no instanciables... ¿es así como se consigue (declarando un solo constructor sin parámetros que sea private) o se hace de alguna otra manera?

Última edición por Kritik; 06/10/2015 a las 04:12
  #2 (permalink)  
Antiguo 06/10/2015, 04:20
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Clases no instanciables

El uso de static suele ser para implementar el patrón Singleton y obtener siempre la misma instancia de la clase. Porque todas las clases son instanciables, lo que cambia con static es que la clase solo permite/mantiene una única instancia.
__________________
Aviso: No se resuelven dudas por MP!
  #3 (permalink)  
Antiguo 06/10/2015, 05:24
(Desactivado)
 
Fecha de Ingreso: marzo-2012
Mensajes: 366
Antigüedad: 12 años
Puntos: 31
Respuesta: Clases no instanciables

A mí lo que me han enseñado es que una clase es un modelo para ser copiado. Y un simil que se me ocurre a la manera de habérmelo enseñado son las casas piloto.

Una casa piloto es la primera que se construye cuando se construye una urbanización. Es un modelo que luego va a ser copiado para hacer toda la urbanización de casas. Y que se construye para ver si los clientes quieren comprar una copia de esa casa o no.

Sin embargo... puede ser que nadie quiera comprar una copia. Y no se construyan copias. ¿Significa eso que el modelo no es habitable, y usable? No... ese modelo ya se puede utilizar, y entonces únicamente habrá 1 única copia de ese modelo. Pero no es ninguna copia, es simplemente el original. El modelo es el que se usa directamente.

¿Qué ha pasado entonces? En el momento en el que se decide que (debido a que nadie quiere copias) no se van a construir más casas... en ese momento se coloca sobre todos y cada uno de los atributos de la casa el modificador static. Y también sobre todos y cada uno de sus métodos.

Ahora que la casa piloto es estática... todo aquel que pase por delante puede utilizar su atributo booleano timbre y cambiar su estado de desactivado (false) a activado (true) y así llamar a la puerta. Quizá ese cambio active un disparador que genere más cosas... o quizá no. Quién sabe.

Resumiendo: La existencia de la propia clase ya es de por sí un objeto. Igual que la existencia de la clase Math ya es de por sí un objeto. Solo que al tener sobre la propia clase el parámetro static no se pueden crear más objetos iguales, no se puede tener ninguna copia.

Así es como yo le veo la lógica. Que si se tiene un modelo (clase) del cual no se quieren copias... se ponga el constructor (aquel método al que se llama cuando se quiere construir una copia) el modificador static.

Pero... ¿y si el método del constructor no admite el modificador static? Entonces la clase si se podría copiar, aunque esa copia no guardase ningún atributo y ningún método... pues todos serían estáticos.

Sería algo así como que te dicen "Este terreno es tu casa... pero no tienes los atributos de puertas, ni ventanas, ni paredes, ni techos, ni cimientos ni baldosas en el suelo... Ni si quiera tienes los métodos de habitar, ni calentarse, ni guarecerse de la climatología, ni encender la luz, ni limpiar..."

¿Para qué quiero yo entonces instanciar una clase que no tiene nada? Que me dejen poner a la casa piloto el modificador static. Y así nadie tendrá objetos sin atributos ni métodos porque esos atributos y métodos están en la clase original.

Así pues, según lo que me han enseñado a mí es que el modificador static no permite hacer una única instanciación si esta no existe como dices... sino que el propio atributo o método estático ya es algo utilizable simplemente por su existencia, simplemente por estar declarado. Y no hace falta hacer ninguna copia, porque se puede utilizar directamente el original simplemente por estar declarado y "existir". Como la clase Math que permite acceder a la constante Pi o a sus métodos. Simplemente porque el original ya existe.

Así es como me lo han enseñado a mí.

Pero como indico en mi anterior post de este hilo... el modificador static no se puede aplicar sobre el constructor ni sobre la declaración de la clase. Así pues... la única forma que se me ha ocurrido de conseguir una clase que no se puedan crear copias vacias es escondiendo el constructor (haciendo un único constructor sin parámetros y poniéndolo como private). Mi duda es si esto es correcto hacerlo así o se hace de alguna otra manera.

Si yo quiero conseguir una clase que funcione igual que la clase Math, con atributos estáticos y métodos estáticos. Que se puedan utilizar pero que no se pueda instanciar. ¿Se hace así?

Y luego otra pregunta aún más enrevesada: ¿Cómo consigo que los métodos de una clase que no se pueda instanciar... se ejecuten en hilos de ejecución distintos? (Toma ya menudo enrevesamiento!!)

Última edición por Kritik; 06/10/2015 a las 05:37
  #4 (permalink)  
Antiguo 06/10/2015, 06:04
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Clases no instanciables

Buenas,

Kritik, solo he leido tu primer mensaje porque el segundo es mas largo y aun no tengo tiempo.

Cita:
Sin embargo... he intentado instanciar la clase Math y me ha dado un error. Lo primero que he pensado es que en la declaración de la clase llevaba el modificador static. Así pues a mi clase se lo he puesto... y me ha dado un error. Eclipse solo me daba una solución: Eliminar el modificador static. Entonces... ¿como Math no se puede instanciar? He ido al error que me daba al intentar instanciar... y eclipse me decía que no había ningún constructor visible.

Por otra parte, en otras clases sin declarar constructor, siempre funciona el constructor vacio (el que no recoge parámetros) aunque no esté declarado.
No hay misterio. Si miras las clase java.lang.Math, veras que su constructor es privado. Por eso no se puede instanciar directamente.
Para clases como Math, que no tienen estado, interesa que se comporten de forma estatica para evitar la creacion de instancias necesarias. Esto tambien permite que la clase sea thread-safe y facilita su uso.
(Otra aproximacion, que no se debe confundir y que es la utilizada por muchas clases del JDK, como la clase String, es la inmutabilidad. La clase es creada en el constructor pero su estado no puede ser modificado. Esto tambien le permite ser utilizada con seguridad en escenarios multihilo.)

Para la clase Empleado que comentas, no se puede aplicar la misma base que para Math, ya por definicion deberia haber muchas instancias de empleado con diversos estados.
La clase Empleado debe poder instanciarse normalmente (si lo haces bien deberias implementar algun Factory que se encargue de instanciarla cuando sea necesario).


@Malenko
static != singleton
Aunque ambas soluciones son thread-safe son son exactamente lo mismo.
Una clase creada siguiendo el patron singleton puede inicializarse de forma lazy mediante proxy pattern o puede implementar una interfaz, por ejemplo.

Un ejemplo de singleton en el JDK es la clase java.lang.Runtime.

Un saludo
__________________
If to err is human, then programmers are the most human of us
  #5 (permalink)  
Antiguo 06/10/2015, 07:21
(Desactivado)
 
Fecha de Ingreso: marzo-2012
Mensajes: 366
Antigüedad: 12 años
Puntos: 31
Respuesta: Clases no instanciables

Profesor_Falken

Muchas gracias por la respuesta, el constructor private era la conclusión a la que yo había llegado, pero por si acaso se hacía de otro modo lo preguntaba.

En cuanto a que la clase empleado si debe ser instanciada... llevas razón. Para la gran mayoría de usos normales de una clase empleado si debe. Solo lo he estado probando con esa clase porque era la que tenía delante y abierta en el momento de ocurrírseme querer conseguir una clase no instanciable.

Se me ocurren pocos casos en los que lo mejor, utilizando un lenguaje de POO sea una clase no instanciable. Pero nunca se sabe, y siempre es bueno saberlo hacer por si un día llega esa circunstancia en la que se piense que esa es la mejor opción.
  #6 (permalink)  
Antiguo 06/10/2015, 07:39
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Clases no instanciables

Buenas Kritik,

No creas, hay bastantes casos en los que no es necesario tener estado o crear instancia.

Cualquier clase que simplemente realiza operaciones y devuelve resultados puede ser stateless. Normalmente para realizar dichas operaciones puede modificar el estado de otras clases (Beans o POJOs). Lo mejor para este tipo de componentes es controlar su creacion mediante algun patron creacional como Abstract Factory o mejor aun utilizando inyeccion de dependencias.

Respecto a muchos de estos temas de diseno te recomiendo un gran libro, que es lectura obligada para cualquier programador Java. Yo lo reeleo siempre de vez en cuando para refrescar las ideas .
http://www.amazon.fr/Effective-Java-.../dp/0321356683

Un saludo
__________________
If to err is human, then programmers are the most human of us

Etiquetas: clase, clases, valor
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:47.