2

私は同じ機能を持つ 2 つのプロジェクトを維持しており、この機能をコモンズ プロジェクトに統合しています。インターフェイスを定義しました:

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

このインターフェイスを両方のプロジェクトに実装します。

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のサブタイプですShapeData。このクラスをコンパイルすると、このコンパイル エラーを解決するにはどうすればよいですか?List<Shape>へのキャストに関するエラーが表示されます。List<? of...たぶんもっと良い質問は、バインドされたワイルドカード (つまり ? extends) を使用してインターフェイス メソッドを定義する必要があるかということです。

4

2 に答える 2

9

基本的に、あなたのインターフェースはIMOが広すぎます。shapes(ちなみに、これはパブリックフィールドです-なぜですか?)は.である必要があると指定しましたList<Shape>。誰かが間違った種類のリストを に渡した場合、どうなると思いますsetShapesか? 例えば:

public class BadShapeData implements ShapeData { ... }

...

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

のリストじゃないShapeですよね?

インターフェイスをジェネリックにすることで修正できます。

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

それで:

public class Graph implements GraphData<Shape>

または、インターフェイスを変更してセッターを持たないようにすることもできます。本当に必要ですか?インターフェイスは本当に多くのメリットをもたらしますか? 単なるプロパティよりも意味のある操作を提供できませんか?

于 2012-03-18T19:04:41.367 に答える
0

それはそれ自体のための複雑さだと思います。あなたGraphにはList<Shape>;があります。そのタイプも取得および設定します。

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

私は通常、インターフェースにゲッター/セッターを持っていません。それはあまり意味のある、または興味深い動作ではありません。にインターフェイスが必要でさえあることに同意しませんGraph。何を達成しようとしているのかを考えてみてください。

于 2012-03-18T19:04:20.503 に答える