简体   繁体   English

(Java)如何使用有界通配符泛型实现接口方法?

[英](Java) How to implement an interface method with a bounded wildcard generic?

I maintain 2 projects with the same functionality and I am consolidating this functionality into a commons project. 我维护了2个具有相同功能的项目,我正在将这个功能整合到一个公共项目中。 I defined an interface: 我定义了一个接口:

public interface GraphData 
{
    public List<? extends ShapeData> getShapes();
    public void setShapes( List<? extends ShapeData> shapes );
}

I implement this interface in both projects: 我在两个项目中实现了这个接口:

public class Graph implements GraphData 
{
     public List<Shape> shapes = new ArrayList<Shape>();

     public List<? extends ShapeData> getShapes() 
     { 
         return shapes;
     }

     public void setShapes( List<? extends ShapeData> shapes )
     {
        this.shapes = shapes;
     }
}

Shape is a subtype of ShapeData . ShapeShapeData的子类型。 When I compile this class I get an error about casting List<Shape> to List<? of... 当我编译这个类时,我得到一个关于将List<Shape>List<? of... List<? of... How do I resolve this compilation error? List<? of...如何解决此编译错误? Maybe a better question is, should I define my interface methods using the bounded wildcard (ie ? extends)? 也许更好的问题是,我应该使用有界通配符定义我的接口方法(即?extends)?

Basically, your interface is too broad IMO. 基本上,你的界面太宽广IMO。 You've specified that shapes (which is a public field, by the way - why?) must be a List<Shape> . 你已经指定了shapes (顺便说一下,这是一个公共字段 - 为什么?)必须是List<Shape> What would you expect to happen if someone passed in the wrong kind of list to setShapes ? 如果有人将错误的列表传递给setShapes您会发生什么? For example: 例如:

public class BadShapeData implements ShapeData { ... }

...

List<BadShapeData> badShapes = new ArrayList<BadShapeData>();
new Graph().setShapes(badShapes);

That's not a list of Shape , is it? 不是 Shape的列表,是吗?

You can fix it by making your interface generic: 您可以通过使您的界面通用来修复它:

public interface GraphData<T extends ShapeData>
{
    List<T> getShapes();
    void setShapes(List<T> shapes);
}

Then: 然后:

public class Graph implements GraphData<Shape>

Alternatively, you could change your interface not to have the setter. 或者,您可以更改界面而不是设置器。 Do you really need it? 你真的需要它吗? Is the interface really adding much benefit? 界面真的增加了很多好处吗? Can you not provide more meaningful operations on it than just a property? 你能不能提供比财产更有意义的操作吗?

I think it's complication for its own sake. 我认为这本身就是复杂的。 Your Graph has a List<Shape> ; 您的Graph有一个List<Shape> ; get and set that type as well. 获取并设置该类型。

public interface GraphData 
{
    public List<Shape> getShapes();
    public void setShapes(List<Shape> shapes );
}

I usually don't have getters/setters in interfaces. 我通常在接口中没有getter / setter。 That's not very meaningful or interesting behavior. 这不是非常有意义或有趣的行为。 I don't agree that an interface is even necessary for Graph . 我不同意Graph甚至需要一个接口。 You might want to think about what you're trying to achieve. 您可能想要考虑您要实现的目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM