嵌套接口的setter

时间:2011-05-21 08:08:44

标签: java

我没有设法用嵌套接口编译一组类。

我们假设有两个接口:

public interface IntA
{   
    public Map<String, ? extends IntB> getName();
    public void setName(Map<String, ? extends IntB> name);
}

public interface IntB
{
    long getId();
    void setId(long id);
}

和两个相应的实现类

public class ImplA implements IntA,Serializable
{
    private Map<String, ImplB> name;
    public Map<String, ? extends IntB> getName(){return name;}
    public void setName(Map<String, ? extends IntB> name)
                  {this.name = (Map<String, ImplB>)name;}
}

public class ImplB implements IntB,Serializable
{
    private long id;
    public long getId() {return id;}
    public void setId(long id) {this.id = id;}
}

我如何使用ImplA的设定者?

public static void create(Random rnd, String code)
{
  ImplB b = new ImplB();
  b.setId(1);

  ImplA a = new ImplA();
  a.getName().put("key", b);
  a.getName().put("key", (IntB)b);
}

结果:

put(java.lang.String,capture#50 of ? extends IntB) in
java.util.Map<java.lang.String,capture#50 of ? extends .IntB>
cannot be applied to (java.lang.String,ImplB)

put(java.lang.String,capture#845 of ? extends IntB) in
java.util.Map<java.lang.String,capture#845 of ? extends IntB>
cannot be applied to (java.lang.String,IntB)

谢谢

托尔

1 个答案:

答案 0 :(得分:3)

你的getter正在返回一个更通用的类型。想象一下,如果它的实际返回值是对Map<String, SomeOtherImplB>的引用 - 您不希望能够在那里放置ImplB

如果您希望能够将值放入Map,则需要准确指定值类型,或者使用“超级”约束而不是“扩展”约束来指定。例如:

// This is fine
Map<String, ? super Apple> map = getMapFromSomewhere();
map.put("Foo", new Apple());

// This isn't - it might be a Map<String, Orange>!
Map<String, ? extends Fruit> map = getMapFromSomewhere();
map.put("Foo", new Apple());

这就是为什么它现在不起作用的原因。至于解决这个问题的正确方法......很难确切知道你要做什么。 也许您想将其更改为:

public interface IntA
{   
    public Map<String, IntB> getName();
    public void setName(Map<String, IntB> name);
}

......或者另一种方法是IntA通用:

public interface IntA<T extends IntB> 
{   
    public Map<String, T> getName();
    public void setName(Map<String, T> name);
}

因此,在这种情况下,您的ImplA课程将实施IntA<ImplB>