Java:无法实现采用泛型参数的抽象方法

时间:2015-06-26 04:48:50

标签: java inheritance netbeans abstract-class

我有一个抽象类;其中一个抽象方法采用多态参数,如下所示:

public abstract class MetricFunction<T extends MetricFunction> {

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

}

现在我尝试扩展这个类,并按如下方式实现这个抽象方法:

public class NumericMetricFunction extends MetricFunction {

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

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

        return answer;
    }
}

这失败了。 IDE(本例中为NetBeans)告诉我 NumericMetricFunction 中的 NDerv 方法不会覆盖超类 MetricFunction 的方法。与此同时,NetBeans承认这两种方法具有相同的&#34;擦除&#34; (我假设它是&#39;签名&#39;)的同义词。

IDE建议我应该按如下方式实现抽象方法:

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

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

        return answer;
    }

当我这样做时,一切似乎都有效。但是,我失去了更具体的&#34; evalPoint&#34;因为它现在只是一个通用列表。

为什么会这样?我该怎么做才能覆盖这个抽象方法并仍然确保&#34; evalPoint&#34;是 List&lt;类型双&gt; ?我不想进行类型转换,因为那是不好的做法;我没有看到为什么我的原始尝试不起作用的原因。

更新 我稍微修改了代码以正确地重现问题。

4 个答案:

答案 0 :(得分:3)

您的抽象类是通用的,但您的实现类不会将参数传递给它。如果你像这样重做你的实现类,它将通过:

var a = {};
a[21] = 'a';
a[90] = 'b';
a[13] = 'c';
a['stringkey'] = 'd';
a.stringparam = 'e'; // btw, a['stringkey'] and a.stringkey is the same

console.log(JSON.stringify(a)); 
// returns {"13":"c","21":"a","90":"b","stringkey":"d","stringparam":"e"}

console.log(Object.keys(a).length);
// returns 5

答案 1 :(得分:1)

将代码更改为使用泛型类型:

public abstract class MetricFunction<T extends Number> {

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

}

使用它:

public class NumericMetricFunction extends MetricFunction<Double> {

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

    }

}

答案 2 :(得分:1)

看起来你找到了一个错误。实际上,让我们来看看JLS在谈论你的问题(强调我的):

8.4.8.1

  

在C类中声明或继承的实例方法mC,覆盖   来自C的另一种方法mA在A类中声明, iff 以下所有方法   是的:

     

A是C的超类。

     

C不继承mA。

     

mC的签名是签名的子签名(§8.4.2)   的毫安。

     

以下其中一项是正确的:

     
      
  • mA是公开的。
  •   
     

[...]

第一点很明显。

第二点是真的,因为你的类不会从超类继承该方法,因为相同的擦除。

第三点也是如此,但需要一些注释。子签名意味着(JLS 8.4.2

  

方法m1的签名是a的签名的子签名   方法m2如果:

     
      
  • m2与m1具有相同的签名,或

  •   
  • m1的签名与的删除(§4.6)相同    m2的签名。

  •   

同样,由于相同的删除,这是真的。

第四点也很明显。

因此,您的代码应该已经编译好了。

Ideone的编译器也没有编译它。 Demo

答案 3 :(得分:0)

我认为这是一个 IDE问题,因为我在Eclipse中也尝试过这样做。

  • Eclipse :开普勒
  • JAVA :1.7

它工作正常。自动生成的 @Override 包含列表&lt;双&GT;

import java.util.List;

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

import java.util.List;

现在扩展它,覆盖功能自动添加。

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;
    }

}