2013-03-28 48 views
2

我收到一个错误,指出“无法找到方法 - getCenter”,但是每当用像a,b或d这样的单个对象替换“objects.get(i)”时,它会发现方法就好。我不明白为什么它无法从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的子类。

+3

您还没有声明类型参数eter或Type参数为你的'ArrayList',所以它默认为'Object'。 'Object'没有'getCenter()'方法。 –

回答

5

您尚未为您的ArrayList声明类型参数或类型参数,因此它默认为ObjectObject没有getCenter()方法。

您可以ArrayList声明更改为类似:

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

但现在只能采取Circle2对象。

3

您正在创建一个不带任何类型参数的ArrayList,这意味着您将其创建为Raw Type。当你这样做时,当你从列表中获得对象时,你需要将对象转换为适当的类型。

要在这种情况下,这是推荐的方式适当地运行您的代码,指定一个类型参数是这样 -

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

或 -

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

查看更多有关泛型here

但是,如果你仍然想使你的现有代码的工作(不推荐),然后用这个 -

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 types show up in legacy code because lots of API classes (such as the Collections classes) were not generic prior to JDK 5.0. When using raw types, you essentially get pre-generics behavior.

1

当前数组列表,你现在所拥有的......以“对象”为元素......,结果......它的元素将只支持方法一个对象(的toString,GetHashCode的等)上定义

可以定义类型等:

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

然而那么它只能接受型圈的对象。以下行会导致错误:

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

更好的方法是使用继承...因此您将有一个称为形状的基类...这将有一个名为getCenter方法将由子类覆盖(如果需要)

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

有四节课扩展形状类:所以现在

public class Cylinder extends Shape 
public class Circle extends Shape 

你可以有你的arraylist为:

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

并在其中添加多个不同的形状:

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

而下面的代码可能

for(Shape shape : shapes) 
    System.out.println(shape.getCenter()) 
0

ArrayList(或任何其他集合)需要知道类对象的,这是怎么回事存储。如果没有指定,则假定您将存储Object实例。

要指定您的收藏将存储类,你需要在创建你的收藏,包括类名:

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

现在你可以读了你的ArrayList两种方式:

的“数组”的风格:您使用索引要经过你的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教程:

相关问题