【问题标题】:Trouble with extending abstract generic class扩展抽象泛型类的问题
【发布时间】:2018-06-18 20:55:51
【问题描述】:

我需要创建一个JTextField,它只强制某些类型的输入(我的目标是排除使用JFormattedTextField 的某些功能)。为此,我想创建一个带有泛型的abstract JTextField 类:

abstract class VTextField_Core<E> extends JTextField {
    public abstract E getAmount();
    public abstract <E> void setAmount(E amount);
}

并以这样的方式实现它:

class VTextField_Integer<Integer> extends VTextField_Core {

    @Override
    public void setAmount(Integer amount) {
        // format Integer to text
    }

    @Override
    public Integer getAmount() {
        // parse text and return Integer
    }
}

class VTextField_Double<Double> extends VTextField_Core {

    @Override
    public void setAmount(Double amount) {
        // format Double to text
    }

    @Override
    public Double getAmount() {
        // parse text and return Double
    }
}

但这会导致编译器错误:

name clash: setAmount(Integer) in Test2.VTextField_Integer and <E>setAmount(E) in Test2.VTextField_Core have the same erasure, yet neither overrides the other
  where Integer,E are type-variables:
    Integer extends Object declared in class Test2.VTextField_Integer
    E extends Object declared in method <E>setAmount(E)

我不明白为什么这不起作用。如何扩展抽象的泛型超类并实现它?

基于这个问题:Extending Generic Abstract Class & Correct Use of Super

我试过了:

class VTextField_Integer<Integer> extends VTextField_Core<Integer> {
class VTextField_Integer<Integer> extends VTextField_Core<E> {

我被难住了。

【问题讨论】:

    标签: java generics


    【解决方案1】:

    class VTextField_Integer&lt;Integer&gt; 声明了一个名为Integer 的类型参数,这不是你需要的。

    将您的课程更改为:

    class VTextField_Integer extends VTextField_Core<Integer> {
    
        @Override
        public void setAmount(Integer amount) {
            // format Integer to text
        }
    
        @Override
        public Integer getAmount() {
            // parse text and return Integer
        }
    }
    
    class VTextField_Double extends VTextField_Core<Double> {
    
        @Override
        public void setAmount(Double amount) {
            // format Double to text
        }
    
        @Override
        public Double getAmount() {
            // parse text and return Double
        }
    }
    

    而且你不需要抽象类的setAmount方法中的类型参数&lt;E&gt;

    abstract class VTextField_Core<E> extends JTextField {
        public abstract E getAmount();
        public abstract void setAmount(E amount);
    }
    

    【讨论】:

      【解决方案2】:

      将您的方法声明为:

      public abstract void setAmount(E amount);
      

      即不要声明新的类型变量。

      这个方法签名:

      public abstract <E> void setAmount(E amount);
      

      表示该方法必须接受 any Object。您不能在子类中将其更改为仅接受 一些 对象。

      【讨论】:

      • 这里要明确一点:虽然它们有相同的名称,但泛型方法setAmount() 的类型参数与泛型类VTextField_Core 的类型参数完全分离和不同(很好!)。在这种情况下,也可以通过将父类方法设为普通方法,使用类的类型参数作为其参数类型来解决问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      相关资源
      最近更新 更多