Obligar a una clase a tener un cierto método estático.

(1/1)

niano:
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
public static Entero suma (Entero entero1, Entero entero2){/*...*/}
 

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
public static Real suma (Real real1, Real real2){/*...*/}
 

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
public class Vector <Elemento /*Aqui es donde me gustaria indicar que Elemento debe implementar una interfaz, o extender una clase o algo asi*/>
{
   ...
 
   public static Vector <Elemento> suma (Vector <Elemento> vector1, Vector<Elemento> vector2){
       Vector <Elemento> nuevo=new Vector<Elemento> (vector1. getTamanyo());
       for (int i=0; i<nuevo.getTamanyo(); i++){
            nuevo.setElemento(i, Elemento.suma(vector1.getElemento(i),vector2.getElemento(i));
   }
 
}
 

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

Código
public interface Grupo<TipoGrupo extends Grupo>
{
   public static TipoGrupo suma (TipoGrupo e1, TipoGrupo e2);
}
 

Y luego la clase "Entero" declararla así:

Código
public class Entero implements Grupo <Entero> {
 
   ...
 
   public static Entero suma(Entero entero1, Entero entero2){...}
 
 

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.

rub'n:
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
interface Group {
 
   static Integer sumaStatica(Integer number, Integer number2) {
       return number + number2;
   }
 
   default Integer sumaDefault(Integer number, Integer number2) {
       return number + number2;
   }
}
 
public class HolaMundo implements Group {
 
   public HolaMundo() {
       final Integer sumaPeroEnConstructor = sumaDefault(1,3);
       System.out.println("Resultado por metodo por default: " + sumaPeroEnConstructor);
   }
 
   public void otroMetodoMas() {
       sumaDefault(1,2);
       Group.sumaStatica(1, 2);
   }
 
   public static void otroMetodoMas2() {
       //Error
       sumaDefault(1, 2);
       Group.sumaStatica(1, 2);
   }
 
   public static void main(String[] args) {
       new HolaMundo();
       //Usando metodo estatico aqui
       final Integer resultado = Group.sumaStatica(1, 2);
       System.out.println("Resultado por metodo por static: " + resultado);
   }
 
}
 
 

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.

niano:
Hola.

Cita de: 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
interface Group {
 
   static Integer sumaStatica(Integer number, Integer number2) {
       return number + number2;
   }
 
   default Integer sumaDefault(Integer number, Integer number2) {
       return number + number2;
   }
}
 
public class HolaMundo implements Group {
 
   public HolaMundo() {
       final Integer sumaPeroEnConstructor = sumaDefault(1,3);
       System.out.println("Resultado por metodo por default: " + sumaPeroEnConstructor);
   }
 
   public void otroMetodoMas() {
       sumaDefault(1,2);
       Group.sumaStatica(1, 2);
   }
 
   public static void otroMetodoMas2() {
       //Error
       sumaDefault(1, 2);
       Group.sumaStatica(1, 2);
   }
 
   public static void main(String[] args) {
       new HolaMundo();
       //Usando metodo estatico aqui
       final Integer resultado = Group.sumaStatica(1, 2);
       System.out.println("Resultado por metodo por static: " + resultado);
   }
 
}
 
 

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.

rub'n:
Cita de: niano en  4 Agosto 2023, 15:48 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
interface Group<T> {
   T sum(T num1, T num2);
}
 
public class HolaMundo implements Group<Double> {
 
   Function<Integer, Integer> function = (a) -> 1 + a;
   IntUnaryOperator function1MoreSpecialized = (a) -> a + 1;
 
   public HolaMundo() {
       final int result1 = function.apply(2);
       final int result2 = function1MoreSpecialized.applyAsInt(2);
 
       System.out.println(result1);
       System.out.println(result2);
 
   }
 
   public static void main(String[] args) {
       new HolaMundo();
   }
 
   @Override
   public Double sum(Double num1, Double num2) {
       return num1 + num2;
   }
}

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

niano:
Exacto. Algo así haré. Muchas gracias.  ;)

Navegación

[0] Índice de Mensajes