2

「メソッドが見つかりません - getCenter」というエラーが表示されますが、「objects.get(i)」を a、b、または d などの単一のオブジェクトに置き換えると、メソッドが正常に検出されます。ArrayList からメソッドが見つからない理由がわかりません。

public class TestPoly
{
public static void main (String []args)
{
    ArrayList objects = new ArrayList();

    Circle2 a = new Circle2(33,10,4);
    Cylinder2 b = new Cylinder2(21,15,40,5);
    Oval2 c = new Oval2(3,7,34,10);
    OvalCylinder2 d = new OvalCylinder2(5,11,5,5,7);

    objects.add(a);
    objects.add(b);
    objects.add(c);
    objects.add(d);

    for (int i = 0; i < objects.size(); i++)
    {
        System.out.println("For " + objects.get(i).getClass().getName() + objects.get(i).getCenter());
    }
}
}

Circle2はこれです。

public class Circle2
{
// instance variables 
private int x;
private int y;
private int radius;

/**
 * Constructor for objects of class circle
 */
public Circle2(int p_x, int p_y, int r)
{
    // initialise instance variables
    x = p_x;
    y = p_y;
    radius = r;
}

public int getRadius()
{

    return radius;
}

public String getCenter()
{
    return " the center is at (" + x + "," + y + ")";
}
}

Cylinder2、Oval2、および OvalCylinder2 はすべて、Circle2 の単なるサブクラスです。

4

4 に答える 4

5

の Type パラメータまたは Type 引数を宣言していないArrayListため、デフォルトで になりObjectます。ObjectメソッドがありませんgetCenter()

ArrayList宣言を次のように変更できます。

ArrayList<Circle2> objects = new ArrayList<Circle2>();
Circle2 a = new Circle2(33,10,4);
objects.add(a);
objects.get(0).getCenter();

Circle2しかし、今ではオブジェクトしか取ることができません。

于 2013-03-28T18:37:40.657 に答える
3

ArrayListタイプ パラメータなしで を作成しています。つまり、Raw Type として作成しています。その場合、オブジェクトをリストから取得するときに、オブジェクトを適切な型にキャストする必要があります。

この場合、推奨される方法であるコードを適切に実行するには、次のような型パラメーターを指定します -

// if you are using jdk 7 or above
ArrayList<Circle2> objects = new ArrayList<>();

また -

ArrayList<Circle2> objects = new ArrayList<Circle2>(); 

ジェネリックの詳細については、こちらを参照してください。

ただし、既存のコードを機能させたい場合 (推奨されません)、これを使用してください -

ArrayList objects = new ArrayList();

Circle2 a = new Circle2(33,10,4);
Cylinder2 b = new Cylinder2(21,15,40,5);
Oval2 c = new Oval2(3,7,34,10);
OvalCylinder2 d = new OvalCylinder2(5,11,5,5,7);

objects.add(a);
objects.add(b);
objects.add(c);
objects.add(d);

for (int i = 0; i < objects.size(); i++)
{
    Circle2 circle = (Circle2 )objects.get(i);
    System.out.println("For " + circle.getClass().getName() + circle.getCenter());
}

このように生の型を使用しないでください。これらは新しいコードで使用するためのものではなく、下位互換性のためにのみサポートされています。rawタイプについては上記のリンクから -

JDK 5.0 より前では、多くの API クラス (コレクション クラスなど) がジェネリックではなかったため、未加工の型がレガシー コードに表示されます。生の型を使用すると、本質的にプレジェネリックの動作が得られます。

于 2013-03-28T18:40:28.763 に答える
1

あなたが今持っている現在の配列リストは...「オブジェクト」を要素として取ります...結果として...その要素はオブジェクトで定義されたメソッド(toString、getHashcodeなど)のみをサポートします

次のようなタイプを定義できます。

ArrayList<Circle2> objects = new ArrayList<Circle2>();

ただし、タイプが circle のオブジェクトのみを受け入れることができます。そして、次の行はエラーを引き起こします:

objects.add(b);
objects.add(c);
objects.add(d);

これを行うためのより良い方法は、継承を使用することです...したがって、shapeという名前の基本クラスが作成されます...これには、(必要に応じて)サブクラスによってオーバーライドされるgetCenterというメソッドが含まれます

public abstract class Shape {
  public String getCenter();
}

shape クラスを拡張する 4 つのクラスがあります。

public class Cylinder extends Shape
public class Circle extends Shape

等々

したがって、次のように配列リストを作成できます。

ArrayList<Shape> shapes = new ArrayList<Shape>();

その中に複数の異なる形状を追加します。

shapes.add(new Circle())
shapes.add(new Cylinder())
...

そして、次のコードが可能です

for(Shape shape : shapes)
   System.out.println(shape.getCenter())
于 2013-03-28T18:46:06.863 に答える
0

(ArrayListまたは他のコレクション) は、格納するオブジェクトのクラスを知る必要があります。Object何も指定されていない場合は、インスタンスを格納すると想定されます。

コレクションが格納するクラスを指定するには、コレクションを作成するときにクラス名を含める必要があります。

// ...
ArrayList<Circle2> objects = new ArrayList<Circle2>();
// ...

ArrayListこれで、 2 つの方法で読み取ることができます。

「配列」スタイル:インデックスを使用して、次のすべてのエントリを調べますArrayList

for(i=0; i<objects.size(); i++) {
    // Use objects(i) to get the Circle2 instance
}

「反復子」スタイル:コレクションに格納されたオブジェクトは、コレクションを反復処理することで読み取ることができます。

for(Circle2 c : objects) {
    /*
     * The object 'c' stores every single Circle2 instance in your 'objects' list
     */
}

CollectionsGenericsチュートリアルを確認することをお勧めします。

于 2013-03-28T18:48:08.033 に答える