Java: cannot implement abstract method taking generic argument

I have an abstract class; one of the abstract methods of which takes a polymorphic argument like this:

public abstract class MetricFunction<T extends MetricFunction> {

    public abstract double NDerv(int dervIndex, List<Double> evalPoint);

}

      

Now I am trying to extend this class and implement this abstract method like this:

public class NumericMetricFunction extends MetricFunction {

    @Override
    public double NDerv(int dervIndex, List<Double> evalPoint) {

        //Do something...
        double answer = 0.;

        return answer;
    }
}

      

It fails. The IDE (NetBeans in this case) informs me that this NDerv method in NumericMetricFunction does not override the superclass MetricFunction method. At the same time, NetBeans recognizes that the two methods share the same "erase" (which I assume is synonymous with "signature").

The IDE advises me to instead apply an abstract method like this:

    @Override
    public double NDerv(int dervIndex, List evalPoint) {

        //Do something...
        double answer = 0.;

        return answer;
    }

      

When I do this, everything works. However, I lose the more specific type "evalPoint", since it is now just a generic list.

Why is this happening? What can I do to override this abstract method and still ensure that "evalPoint" is of type List <Double>? I don’t want to attribute it as it is bad practice; I see no reason why my initial attempt should not work.

Update: I modified the code a bit to reproduce the problem correctly.

+3


source to share


5 answers


Your abstract class is generic, but your implementing class does not pass a parameter to it. If you iterate your implementation class like this it will pass:



public class NumericMetricFunction extends MetricFunction<NumericMetricFunction> {

    @Override
    public double NDerv(int dervIndex, List<Double> evalPoint) {

        //Do something...
        double answer = 0.;

        return answer;
    }
}

      

+3


source


Modify your code to use the generic type:

public abstract class MetricFunction<T extends Number> {

    public abstract double NDerv(int dervIndex, List<T> evalPoint);

}

      



Using it:

public class NumericMetricFunction extends MetricFunction<Double> {

    @Override
    public double NDerv(int dervIndex, List<Double> evalPoint) {

    }

}

      

+1


source


It looks like you found a bug. Actually, let's see what the JLS has to say about your question (underline mine):

Section 8.4.8.1

An instance method mC declared or inherited by class C overrides from C another method mA declared in class A, iff all of the following are true:

A is the superclass of C.

C does not inherit mA.

The mC signature is the submission (Β§8.4.2) of the mA signature .

One of the following is true:

  • mA is publicly available.

[...]

The first point is obvious.

The second point is true, because your class does not inherit a method from the superclass, because the same erasure.

The third point is also correct, but requires some notes. Subtitle means ( JLS 8.4.2 )

Method signature m1 is a sub-signal of method m2 signature if:

  • m2 has the same signature as m1, or

  • signature m1 is the same as erasure (Β§4.6) signature m2.

Again, due to the same erasure, this is true.

The fourth point is also obvious.

So your code should compile.

Ideone

the compiler won't compile it either. Demo

+1


source


I think this is an IDE issue as I tried the same thing in Eclipse.

  • Eclipse : Kepler
  • JAVA : 1.7

And everything worked out great. Autogeneration @Override had List <Double>

import java.util.List;

public abstract class MetricFunction {
    public abstract double NDerv(int dervIndex, List<Double> evalPoint);
}

import java.util.List;

      

Now extended function, automatically added override function.

import java.util.List;

public class NumericMetricFunction extends MetricFunction {

    @Override
    public double NDerv(int dervIndex, List<Double> evalPoint) {
        // TODO Auto-generated method stub
        return 0;
    }

}

      

0


source


I'm not sure why this works, but I had to declare a NumericMetricFunction like this:

public class NumericMetricFunction extends MetricFunction<NumericMetricFunction> {...}

      

-1


source







All Articles