Foro de elhacker.net

Programación => Java => Mensaje iniciado por: niano en 4 Agosto 2023, 10:29 am



Título: Obligar a una clase a tener un cierto método estático.
Publicado por: niano en 4 Agosto 2023, 10:29 am
Hola.

Quisiera saber si es posible obligar a una clase a tener un método estático que encaje en un cierto patrón. Me explico. Por ejemplo, imaginemos que tenemos una clase "Entero" que pretende implementar las operaciones con números enteros y que tiene un método estático llamado "suma", que básicamente devuelve la suma de dos números enteros pasados por parámetro y cuya declaración es del tipo:

Código
  1. public static Entero suma (Entero entero1, Entero entero2){/*...*/}
  2.  

También podríamos tener una clase "Real" que pretenda implementar las operaciones que se pueden hacer con números reales y que podría tener declarado un método "suma" tipo:


Código
  1. public static Real suma (Real real1, Real real2){/*...*/}
  2.  

Pues bien, me gustaría poder trabajar con una clase que trabaje con elementos de una clase genérica que obligatoriamente tenga declarado un método de este tipo sin importar que sean enteros, reales o lo que sea... Por ejemplo, imaginemos que queremos declarar una clase "Vector", que contendrá elementos de una clase genérica (que pueden ser enteros o reales) y queremos definir la suma de vectores a partir de la suma de sus elementos. Algo así:

Código
  1. public class Vector <Elemento /*Aqui es donde me gustaria indicar que Elemento debe implementar una interfaz, o extender una clase o algo asi*/>
  2. {
  3.    ...
  4.  
  5.    public static Vector <Elemento> suma (Vector <Elemento> vector1, Vector<Elemento> vector2){
  6.        Vector <Elemento> nuevo=new Vector<Elemento> (vector1. getTamanyo());
  7.        for (int i=0; i<nuevo.getTamanyo(); i++){
  8.             nuevo.setElemento(i, Elemento.suma(vector1.getElemento(i),vector2.getElemento(i));
  9.    }
  10.  
  11. }
  12.  

Mi intento ha sido el de declarar una interfaz "Grupo" de la siguiente manera:

Código
  1. public interface Grupo<TipoGrupo extends Grupo>
  2. {
  3.    public static TipoGrupo suma (TipoGrupo e1, TipoGrupo e2);
  4. }
  5.  

Y luego la clase "Entero" declararla así:

Código
  1. public class Entero implements Grupo <Entero> {
  2.  
  3.    ...
  4.  
  5.    public static Entero suma(Entero entero1, Entero entero2){...}
  6.  
  7.  

Pero no funciona... En la interfaz Grupo, en la línea del método "suma", me sale un error que dice que "un tipo de variable no estático como "TipoGrupo" no se puede referenciar desde un entorno estático" lo cual tiene su lógica, y otro error que dice que "falta el cuerpo del método o declararlo abstracto". Si lo declaro abstracto el primer error se mantiene y aparece otro que dice que es ilegal combinar los modificadores static y abstract.

¿Realmente se puede obligar a que una clase tenga un método estático que encaje en una cierta declaración?

Gracias de antemano por la ayuda. Un saludo.


Título: Re: Obligar a una clase a tener un cierto método estático.
Publicado por: rub'n en 4 Agosto 2023, 10:44 am
Creo que hay terminos un poco, raros que quieres aplicar.

Puedes tranquilamente usar una interface "Grupo" con un método default es decir con implementación por defecto.

Código
  1. interface Group {
  2.  
  3.    static Integer sumaStatica(Integer number, Integer number2) {
  4.        return number + number2;
  5.    }
  6.  
  7.    default Integer sumaDefault(Integer number, Integer number2) {
  8.        return number + number2;
  9.    }
  10. }
  11.  
  12. public class HolaMundo implements Group {
  13.  
  14.    public HolaMundo() {
  15.        final Integer sumaPeroEnConstructor = sumaDefault(1,3);
  16.        System.out.println("Resultado por metodo por default: " + sumaPeroEnConstructor);
  17.    }
  18.  
  19.    public void otroMetodoMas() {
  20.        sumaDefault(1,2);
  21.        Group.sumaStatica(1, 2);
  22.    }
  23.  
  24.    public static void otroMetodoMas2() {
  25.        //Error
  26.        sumaDefault(1, 2);
  27.        Group.sumaStatica(1, 2);
  28.    }
  29.  
  30.    public static void main(String[] args) {
  31.        new HolaMundo();
  32.        //Usando metodo estatico aqui
  33.        final Integer resultado = Group.sumaStatica(1, 2);
  34.        System.out.println("Resultado por metodo por static: " + resultado);
  35.    }
  36.  
  37. }
  38.  
  39.  

Hay tienes una variante,

Los métodos default puedes invorcalos solo si "tu" quieres y en métodos no static, como en la línea "15" y "20"

Y estoy seguro que esto no te ayudara, jaja, porque tienes la mente en sobreComplicar las cosas ya mismo, a veces los genericos sobre complican las cosas en ciertos casos.

Para lo que quieres hacer es mejor especificar y listo, por existe la clase Interger, Double, Long, etc, especificaciones para estos casos.


Título: Re: Obligar a una clase a tener un cierto método estático.
Publicado por: niano en 4 Agosto 2023, 15:48 pm
Hola.

Creo que hay terminos un poco, raros que quieres aplicar.

Puedes tranquilamente usar una interface "Grupo" con un método default es decir con implementación por defecto.

Código
  1. interface Group {
  2.  
  3.    static Integer sumaStatica(Integer number, Integer number2) {
  4.        return number + number2;
  5.    }
  6.  
  7.    default Integer sumaDefault(Integer number, Integer number2) {
  8.        return number + number2;
  9.    }
  10. }
  11.  
  12. public class HolaMundo implements Group {
  13.  
  14.    public HolaMundo() {
  15.        final Integer sumaPeroEnConstructor = sumaDefault(1,3);
  16.        System.out.println("Resultado por metodo por default: " + sumaPeroEnConstructor);
  17.    }
  18.  
  19.    public void otroMetodoMas() {
  20.        sumaDefault(1,2);
  21.        Group.sumaStatica(1, 2);
  22.    }
  23.  
  24.    public static void otroMetodoMas2() {
  25.        //Error
  26.        sumaDefault(1, 2);
  27.        Group.sumaStatica(1, 2);
  28.    }
  29.  
  30.    public static void main(String[] args) {
  31.        new HolaMundo();
  32.        //Usando metodo estatico aqui
  33.        final Integer resultado = Group.sumaStatica(1, 2);
  34.        System.out.println("Resultado por metodo por static: " + resultado);
  35.    }
  36.  
  37. }
  38.  
  39.  

Hay tienes una variante,

Los métodos default puedes invorcalos solo si "tu" quieres y en métodos no static, como en la línea "15" y "20"

Y estoy seguro que esto no te ayudara, jaja, porque tienes la mente en sobreComplicar las cosas ya mismo, a veces los genericos sobre complican las cosas en ciertos casos.

Para lo que quieres hacer es mejor especificar y listo, por existe la clase Interger, Double, Long, etc, especificaciones para estos casos.


 ;D ;D ;D

Gracias igualmente por la ayuda, el problema es que necesito que devuelva un tipo genérico. En ocasiones necesitaré que sea un tipo que no tiene nada que ver con las clases Integer, Double, etc.

Creo que simplemente renunciaré a las versiones estáticas y lo haré todo a partir de métodos no estáticos, que con eso me funciona bien.

Gracias. Un saludo.


Título: Re: Obligar a una clase a tener un cierto método estático.
Publicado por: rub'n en 4 Agosto 2023, 19:22 pm
Hola.

 ;D ;D ;D

Gracias igualmente por la ayuda, el problema es que necesito que devuelva un tipo genérico. En ocasiones necesitaré que sea un tipo que no tiene nada que ver con las clases Integer, Double, etc.

Creo que simplemente renunciaré a las versiones estáticas y lo haré todo a partir de métodos no estáticos, que con eso me funciona bien.

Gracias. Un saludo.

Claro lo simple seria el

Código
  1. interface Group<T> {
  2.    T sum(T num1, T num2);
  3. }
  4.  
  5. public class HolaMundo implements Group<Double> {
  6.  
  7.    Function<Integer, Integer> function = (a) -> 1 + a;
  8.    IntUnaryOperator function1MoreSpecialized = (a) -> a + 1;
  9.  
  10.    public HolaMundo() {
  11.        final int result1 = function.apply(2);
  12.        final int result2 = function1MoreSpecialized.applyAsInt(2);
  13.  
  14.        System.out.println(result1);
  15.        System.out.println(result2);
  16.  
  17.    }
  18.  
  19.    public static void main(String[] args) {
  20.        new HolaMundo();
  21.    }
  22.  
  23.    @Override
  24.    public Double sum(Double num1, Double num2) {
  25.        return num1 + num2;
  26.    }
  27. }

Y si le das fuerte la linea 7 y 8 mete interfaces funcionales ya creadas para problemas comunes.


Título: Re: Obligar a una clase a tener un cierto método estático.
Publicado por: niano en 4 Agosto 2023, 23:22 pm
Exacto. Algo así haré. Muchas gracias.  ;)