views:

77

answers:

4

This doesn't seem to work (compiler complains that Something's getFoo() method doesn't implement HasFoo) and I can't figure out why or how to fix it....

enum FooKey { BLOB1, DONUT, ... }

interface HasFoo
{
   public Object getFoo(FooKey k);
}

class Something implements HasFoo
{
    private Map<FooKey, Object> map;

    @SuppressWarnings("unchecked")
    @Override
    <T> T getFoo(FooKey k)
    {
        return (T)map.get(k);
    }

    /* other stuff deleted */
}

I want both an interface and I also want to be able to do stuff like

Something something = ...
Blob blob1 = something.getFoo(FooKey.BLOB1);
Donut donut = something.getFoo(FooKey.DONUT);
+1  A: 

Doesn't this work?

interface HasFoo
{
   public <T> T getFoo(FooKey k);
}
Kelly French
doh! So it does! I didn't know you could do that in an interface, I thought you could only do `interface HasFoo<T>`.
Jason S
A: 

Compiler's error really mean that methods' signatures differ:

<T> T getFoo(FooKey k)

Object getFoo(FooKey k)

Althought Object is the ultimate ancestor compiler wants signatures to be exactly same

Andrey
A: 

Your interface is specifying an Object, whereas the return type of the impl is 'anything'. You need to change the interface to return T.

BTW, you could also declare your map to be <FooKey, T>

eqbridges
can't declare the map to be <FooKey, T>. T is not constant for the class. it's a map of different things.
Jason S
yes, you can. you're returning T from the method...which is coming from the map, no?
eqbridges
+1  A: 

You can't override a non-generic method with a generic one. An alternative could be:

interface HasFoo
{
    <T> T getFoo(FooKey k);
}

class Something implements HasFoo
{
    private Map<FooKey, Object> map;

    @Override
    public <T> T getFoo(FooKey k)
    {
        return (T)map.get(k);
    }

    /* other stuff deleted */
}
bruno conde