Is there a way to make sure classes implementing an Interface implement static methods?

后端 未结 9 1944
礼貌的吻别
礼貌的吻别 2021-01-07 17:11

First of all, I read erickson\'s useful reply to \"Why can’t I define a static method in a Java interface?\". This question is not about the \"why\" but about the \"how then

相关标签:
9条回答
  • 2021-01-07 17:57

    You cannot require classes to implement particular static methods through an interface. It just makes no sense in Java terms. Interfaces force the presence of particular non-static methods in the classes that implement the interface; that's what they do.

    The easiest way is definitely to have some sort of factory class that produces instances of the others. Yes, this does mean that you have to remember to keep that factory up to date when you add new instances, but since the first thing you do when you make a new implementation is test it (you do test it, yes?) you'll pick up on that problem very quickly!

    0 讨论(0)
  • 2021-01-07 18:00

    Why not try Java 5 enum? ie:

    public enum ParametricFunctions implements ParametricFunction {
        Parabola() {
            /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */
            public double getValue(double x, double[] parameters) {
                return ( parameters[2] + x*(parameters[1] + x*parameters[0]));
            }
    
            public String getName() { return "Parabola"; }
    
            public boolean checkParameters(double[] parameters) {
                return (parameters.length==3);
            }
        },
    
        // other functions as enum members
    }
    

    With this you can look up the static function types easily, and with compile-time safety, but still allow the interface type to be referenced elsewhere. You could also place a method on the enum type to allow lookup of the function by name.


    EDIT for concerns on file size with the enum way.

    In that case you could define each function as it's own class, ie:

    public class Parabola implements ParametricFunction {
    
        /** @return f(x) = parameters[0] * x² + parameters[1] * x + parameters[2] */
        public double getValue(double x, double[] parameters) {
            return ( parameters[2] + x*(parameters[1] + x*parameters[0]));
        }
    
        public String getName() { return "Parabola"; }
    
        public boolean checkParameters(double[] parameters) {
            return (parameters.length==3);
        }
    

    }

    Then you can have many separate, implementation files, and compose them into one, smaller, enum-like class through which the functions can be accessed statically. Ie:

    public class ParametricFunctions {  
        public static final ParametricFunction parabola = new Parabola(),
                                               bessel = new BesselFunction(),
                                               // etc
    }
    

    This allows a single place to look up the functions, with the implementation kept separate. You could also add them to a static collection for name lookup. You could then maintain readability in your functions as mentioned in another comment:

    import static ...ParametricFunctions.parabola;
    // etc
    
    public void someMethodCallingFit() {
        fit(parabola, xValues, yValues);
    }
    
    0 讨论(0)
  • 2021-01-07 18:05

    One solution - is make all methods non-static with requirement that class must have default constructor. Then you can instantiate it easily and call methods you need.

    0 讨论(0)
提交回复
热议问题