Adam Hughes
Adam Hughes

Reputation: 16309

How to implement generic fields from abstract class?

I have an abstract class that has one field whose type can vary between its subclassses. For example:

public abstract class ABCModel {
    protected String foo;
    protected String bar;
    protected ? baz;
}

In my implementations, baz may be an Int or a Float. For example:

public class ModelFoo {
     protected Int baz;
}

public class Modelbar {
     protected Float baz;
}  

First, let me ask if this is a valid/accepted design pattern in Java? I've chosen this pattern because I want to abstract-away most of the tedious boilerplate in the shared methods.

Depending on how I implement it, I get variations of this error:

incompatible types: CAP#1 cannot be converted to BidAsk
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?

This leads me to believe I'm doing something wrong.

The example I posted is a bit trivial compared to my actual code, in which this generic is buried in a nested hashtable. I'm trying to decide if what I'm doing is a smart design in Java or not before getting too invested.

I've tried searching for this, but probably am not articulating the terminology correctly.

Thanks.

Upvotes: 4

Views: 4030

Answers (3)

AdamSkywalker
AdamSkywalker

Reputation: 11619

What you are asking is the basic usage of generics:

public abstract class ABCModel<T> {
    private T baz;

    public T getBaz() { return baz; }

    public void setBaz(T baz) { this.baz = baz; }
}

public class IntModel extends ABCModel<Integer> { // baz is of type Integer   
}

public class FloatModel extends ABCModel<Float> { // baz is of type Float   
}

IntModel m1 = new IntModel();
Integer i = m1.getBaz();

FloatModel m2 = new FloatModel();
Float f = m2.getBaz();

Upvotes: 5

Coralie B
Coralie B

Reputation: 603

This is an accepted pattern, but you should be more specific about your generics :

public abstract class ABCModel<T extends Number> {
    protected String foo;
    protected String bar;
    protected T baz;

    public T getBaz() {
      return baz;
    }
}

After that you can extend your model :

public class ModelFoo extends ABCModel<Integer> {
     // No need to specify again baz.
}

Upvotes: 2

Steve Kuo
Steve Kuo

Reputation: 63104

Fields cannot be overridden in Java. You can however use methods with generics.

public abstract class ABCModel<T> {
    public abstract T getBaz();
}

Then

public class ModelFoo extends ABCModel<Integer> {
    public Integer getBaz() {
        ...
    }
}

Upvotes: 1

Related Questions