为啥我的程序无法识别我的方法?
Posted
技术标签:
【中文标题】为啥我的程序无法识别我的方法?【英文标题】:Why is my programming not recognizing my method?为什么我的程序无法识别我的方法? 【发布时间】:2013-03-19 08:27:44 【问题描述】:我收到一条错误消息,指出“找不到方法 - 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 的子类。
【问题讨论】:
您还没有为ArrayList
声明类型参数或类型参数,所以它默认为Object
。 Object
没有 getCenter()
方法。
【参考方案1】:
您尚未为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
对象。
【讨论】:
【参考方案2】:您正在创建一个不带任何类型参数的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());
不要以这种方式使用原始类型。它们不打算在新代码中使用,支持它们只是为了向后兼容。从上面关于原始类型的链接 -
原始类型出现在遗留代码中,因为有很多 API 类(例如 Collections 类)在 JDK 5.0 之前不是通用的。使用时 原始类型,您基本上获得了预泛型行为。
【讨论】:
【参考方案3】:您现在拥有的当前数组列表...将“对象”作为其元素...因此...其元素将仅支持在对象上定义的方法(toString、getHashcode 等)
你可以像这样定义类型:
ArrayList<Circle2> objects = new ArrayList<Circle2>();
但是,它只能接受圆形类型的对象。以下几行将导致错误:
objects.add(b);
objects.add(c);
objects.add(d);
一个更好的方法是使用继承......所以你将有一个名为 shape 的基类......它将有一个名为 getCenter 的方法,该方法将被子类覆盖(如果需要)
public abstract class Shape
public String getCenter();
有四个类扩展了形状类:
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())
【讨论】:
【参考方案4】: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
*/
我建议你查看Collections
和Generics
教程:
【讨论】:
以上是关于为啥我的程序无法识别我的方法?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Netbeans 无法识别我的 Grails 应用程序中的 Maven 依赖项导入?
为啥我的 DirectX 程序无法识别我已经释放了转义键? (C++)