TheFunk
TheFunk

Reputation: 1108

Java: Overriding Generic Method with Typed Method?

I have a parent class EntryPoint with an abstract method to retrieve a prop that is a list of a generic type. The list is declared as protected:

public abstract class EntryPoint implements Serializable {

    public EntryPoint(){}

    protected ArrayList<? extends Tag> tiedTags;

    public abstract ArrayList<? extends Tag> getTiedTags();

}

I have a child class representative of an SNMP Entry Point (used for querying an SNMP agent). IntelliJ is not complaining about this configuration but I am wondering, am I correctly overriding the getTiedTags() method from the parent or have I somehow overwritten the parent method?

public class SNMPEntryPoint extends EntryPoint implements Serializable {

    //Default Constructor for Serialization
    public SNMPEntryPoint(){}

    @Override
    public ArrayList<SNMPTag> getTiedTags(){ return (ArrayList<SNMPTag>) tiedTags; }
}

Upvotes: 2

Views: 124

Answers (2)

luk2302
luk2302

Reputation: 57114

The cleaner way would probably be to introduce a type parameter on the class level

public abstract class EntryPoint<T extends Tag> implements Serializable {

    public EntryPoint(){}

    protected ArrayList<T> tiedTags;

    public abstract ArrayList<T> getTiedTags();

}

and then inherit via

public class SNMPEntryPoint extends EntryPoint<SNMPTag> implements Serializable {

    //Default Constructor for Serialization
    public SNMPEntryPoint(){}

    @Override
    public ArrayList<SNMPTag> getTiedTags(){ return tiedTags; }
}

at which point the cast is no longer needed.

Upvotes: 2

Brian Goetz
Brian Goetz

Reputation: 95346

The method you are overriding is not a generic method; a generic method declares its own type variables.

The override in SNMPEntryPoint is a covariant override; a subclass is allowed to override a method in a superclass to return a more specific type (a subtype of the original type) than the return type in the overridden method, such as:

interface Factory {
    Object make();
}

class StringFactory implements Factory {
    @Override
    String make() { ... }
}

Since ArrayList<SNMPTag> is a subtype of ArrayList<? extends Tag>, your example is a valid (though unusual) covariant override.

There is no corresponding feature for overriding a method whose argument types are less specific.

Upvotes: 3

Related Questions