Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with extending abstract generic class

Tags:

java

generics

I need to create a JTextField that forces only certain kinds of input (I have a goal for certain functionality that precludes using JFormattedTextField). To accomplish this, I would like to create an abstract JTextField class with generics:

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

And implement it in a way like this:

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

But this gives a compiler error:

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)

I can't figure out why this isn't working. How do you extend an abstract generic superclass and implement it?

Based on this question: Extending Generic Abstract Class & Correct Use of Super

I tried:

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

I'm stumped.

like image 734
ryvantage Avatar asked Dec 23 '22 06:12

ryvantage


1 Answers

class VTextField_Integer<Integer> declares a type parameter named Integer, which is not what you need.

Change your classes to:

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

And you don't need the type parameter <E> in the setAmount method of the abstract class.

abstract class VTextField_Core<E> extends JTextField {
    public abstract E getAmount();
    public abstract void setAmount(E amount);
}
like image 85
Eran Avatar answered Jan 08 '23 18:01

Eran